summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/exe/ajax.php435
-rw-r--r--lib/exe/css.php343
-rw-r--r--lib/exe/detail.php48
-rw-r--r--lib/exe/fetch.php205
-rw-r--r--lib/exe/index.html12
-rw-r--r--lib/exe/indexer.php271
-rw-r--r--lib/exe/js.php358
-rw-r--r--lib/exe/mediamanager.php122
-rw-r--r--lib/exe/opensearch.php38
-rw-r--r--lib/exe/xmlrpc.php888
-rw-r--r--lib/images/admin/README2
-rw-r--r--lib/images/admin/acl.pngbin0 -> 1074 bytes
-rw-r--r--lib/images/admin/config.pngbin0 -> 1496 bytes
-rw-r--r--lib/images/admin/plugin.pngbin0 -> 1127 bytes
-rw-r--r--lib/images/admin/popularity.pngbin0 -> 1189 bytes
-rw-r--r--lib/images/admin/revert.pngbin0 -> 1295 bytes
-rw-r--r--lib/images/admin/usermanager.pngbin0 -> 1467 bytes
-rw-r--r--lib/images/arrow_down.gifbin0 -> 273 bytes
-rw-r--r--lib/images/arrow_up.gifbin0 -> 274 bytes
-rw-r--r--lib/images/at.gifbin0 -> 57 bytes
-rw-r--r--lib/images/blank.gifbin0 -> 42 bytes
-rw-r--r--lib/images/close.pngbin0 -> 137 bytes
-rw-r--r--lib/images/del.pngbin0 -> 355 bytes
-rw-r--r--lib/images/diff.pngbin0 -> 206 bytes
-rw-r--r--lib/images/edit.gifbin0 -> 142 bytes
-rw-r--r--lib/images/error.pngbin0 -> 648 bytes
-rw-r--r--lib/images/fileicons/7z.pngbin0 -> 651 bytes
-rw-r--r--lib/images/fileicons/audio.pngbin0 -> 727 bytes
-rw-r--r--lib/images/fileicons/bz2.pngbin0 -> 641 bytes
-rw-r--r--lib/images/fileicons/c.pngbin0 -> 759 bytes
-rw-r--r--lib/images/fileicons/conf.pngbin0 -> 664 bytes
-rw-r--r--lib/images/fileicons/cpp.pngbin0 -> 822 bytes
-rw-r--r--lib/images/fileicons/cs.pngbin0 -> 771 bytes
-rw-r--r--lib/images/fileicons/css.pngbin0 -> 843 bytes
-rw-r--r--lib/images/fileicons/csv.pngbin0 -> 400 bytes
-rw-r--r--lib/images/fileicons/deb.pngbin0 -> 646 bytes
-rw-r--r--lib/images/fileicons/doc.pngbin0 -> 583 bytes
-rw-r--r--lib/images/fileicons/docx.pngbin0 -> 583 bytes
-rw-r--r--lib/images/fileicons/file.pngbin0 -> 581 bytes
-rw-r--r--lib/images/fileicons/gif.pngbin0 -> 907 bytes
-rw-r--r--lib/images/fileicons/gz.pngbin0 -> 643 bytes
-rw-r--r--lib/images/fileicons/htm.pngbin0 -> 695 bytes
-rw-r--r--lib/images/fileicons/html.pngbin0 -> 695 bytes
-rw-r--r--lib/images/fileicons/index.php50
-rw-r--r--lib/images/fileicons/java.pngbin0 -> 739 bytes
-rw-r--r--lib/images/fileicons/jpeg.pngbin0 -> 907 bytes
-rw-r--r--lib/images/fileicons/jpg.pngbin0 -> 907 bytes
-rw-r--r--lib/images/fileicons/js.pngbin0 -> 809 bytes
-rw-r--r--lib/images/fileicons/lua.pngbin0 -> 440 bytes
-rw-r--r--lib/images/fileicons/mp3.pngbin0 -> 831 bytes
-rw-r--r--lib/images/fileicons/odc.pngbin0 -> 682 bytes
-rw-r--r--lib/images/fileicons/odf.pngbin0 -> 746 bytes
-rw-r--r--lib/images/fileicons/odg.pngbin0 -> 735 bytes
-rw-r--r--lib/images/fileicons/odi.pngbin0 -> 735 bytes
-rw-r--r--lib/images/fileicons/odp.pngbin0 -> 687 bytes
-rw-r--r--lib/images/fileicons/ods.pngbin0 -> 682 bytes
-rw-r--r--lib/images/fileicons/odt.pngbin0 -> 522 bytes
-rw-r--r--lib/images/fileicons/ogg.pngbin0 -> 807 bytes
-rw-r--r--lib/images/fileicons/pdf.pngbin0 -> 592 bytes
-rw-r--r--lib/images/fileicons/php.pngbin0 -> 749 bytes
-rw-r--r--lib/images/fileicons/pl.pngbin0 -> 685 bytes
-rw-r--r--lib/images/fileicons/png.pngbin0 -> 907 bytes
-rw-r--r--lib/images/fileicons/ppt.pngbin0 -> 697 bytes
-rw-r--r--lib/images/fileicons/pptx.pngbin0 -> 697 bytes
-rw-r--r--lib/images/fileicons/ps.pngbin0 -> 470 bytes
-rw-r--r--lib/images/fileicons/py.pngbin0 -> 683 bytes
-rw-r--r--lib/images/fileicons/rar.pngbin0 -> 557 bytes
-rw-r--r--lib/images/fileicons/rb.pngbin0 -> 802 bytes
-rw-r--r--lib/images/fileicons/rpm.pngbin0 -> 555 bytes
-rw-r--r--lib/images/fileicons/rtf.pngbin0 -> 402 bytes
-rw-r--r--lib/images/fileicons/sql.pngbin0 -> 813 bytes
-rw-r--r--lib/images/fileicons/swf.pngbin0 -> 732 bytes
-rw-r--r--lib/images/fileicons/sxc.pngbin0 -> 682 bytes
-rw-r--r--lib/images/fileicons/sxd.pngbin0 -> 735 bytes
-rw-r--r--lib/images/fileicons/sxi.pngbin0 -> 687 bytes
-rw-r--r--lib/images/fileicons/sxw.pngbin0 -> 522 bytes
-rw-r--r--lib/images/fileicons/tar.pngbin0 -> 663 bytes
-rw-r--r--lib/images/fileicons/tgz.pngbin0 -> 643 bytes
-rw-r--r--lib/images/fileicons/txt.pngbin0 -> 466 bytes
-rw-r--r--lib/images/fileicons/wav.pngbin0 -> 820 bytes
-rw-r--r--lib/images/fileicons/xls.pngbin0 -> 670 bytes
-rw-r--r--lib/images/fileicons/xlsx.pngbin0 -> 670 bytes
-rw-r--r--lib/images/fileicons/xml.pngbin0 -> 409 bytes
-rw-r--r--lib/images/fileicons/zip.pngbin0 -> 800 bytes
-rw-r--r--lib/images/history.pngbin0 -> 149 bytes
-rw-r--r--lib/images/icon-file.pngbin0 -> 3363 bytes
-rw-r--r--lib/images/icon-list.pngbin0 -> 3342 bytes
-rw-r--r--lib/images/icon-sort.pngbin0 -> 316 bytes
-rw-r--r--lib/images/icon-thumb.pngbin0 -> 969 bytes
-rw-r--r--lib/images/index.html12
-rw-r--r--lib/images/info.pngbin0 -> 725 bytes
-rw-r--r--lib/images/interwiki.pngbin0 -> 443 bytes
-rw-r--r--lib/images/interwiki/amazon.de.gifbin0 -> 110 bytes
-rw-r--r--lib/images/interwiki/amazon.gifbin0 -> 110 bytes
-rw-r--r--lib/images/interwiki/amazon.uk.gifbin0 -> 110 bytes
-rw-r--r--lib/images/interwiki/callto.gifbin0 -> 178 bytes
-rw-r--r--lib/images/interwiki/coral.gifbin0 -> 85 bytes
-rw-r--r--lib/images/interwiki/doku.gifbin0 -> 188 bytes
-rw-r--r--lib/images/interwiki/dokubug.gifbin0 -> 166 bytes
-rw-r--r--lib/images/interwiki/google.gifbin0 -> 170 bytes
-rw-r--r--lib/images/interwiki/meatball.gifbin0 -> 339 bytes
-rw-r--r--lib/images/interwiki/paypal.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/phpfn.gifbin0 -> 164 bytes
-rw-r--r--lib/images/interwiki/sb.gifbin0 -> 195 bytes
-rw-r--r--lib/images/interwiki/skype.pngbin0 -> 675 bytes
-rw-r--r--lib/images/interwiki/wiki.gifbin0 -> 131 bytes
-rw-r--r--lib/images/interwiki/wp.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/wpde.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/wpes.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/wpfr.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/wpjp.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/wpmeta.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/wppl.gifbin0 -> 171 bytes
-rw-r--r--lib/images/larger.gifbin0 -> 87 bytes
-rw-r--r--lib/images/license/badge/cc-by-nc-nd.pngbin0 -> 1475 bytes
-rw-r--r--lib/images/license/badge/cc-by-nc-sa.pngbin0 -> 1587 bytes
-rw-r--r--lib/images/license/badge/cc-by-nc.pngbin0 -> 1421 bytes
-rw-r--r--lib/images/license/badge/cc-by-nd.pngbin0 -> 1283 bytes
-rw-r--r--lib/images/license/badge/cc-by-sa.pngbin0 -> 1421 bytes
-rw-r--r--lib/images/license/badge/cc-by.pngbin0 -> 1204 bytes
-rw-r--r--lib/images/license/badge/cc-zero.pngbin0 -> 1202 bytes
-rw-r--r--lib/images/license/badge/cc.pngbin0 -> 898 bytes
-rw-r--r--lib/images/license/badge/gnufdl.pngbin0 -> 1667 bytes
-rw-r--r--lib/images/license/badge/publicdomain.pngbin0 -> 1345 bytes
-rw-r--r--lib/images/license/button/cc-by-nc-nd.pngbin0 -> 396 bytes
-rw-r--r--lib/images/license/button/cc-by-nc-sa.pngbin0 -> 403 bytes
-rw-r--r--lib/images/license/button/cc-by-nc.pngbin0 -> 388 bytes
-rw-r--r--lib/images/license/button/cc-by-nd.pngbin0 -> 386 bytes
-rw-r--r--lib/images/license/button/cc-by-sa.pngbin0 -> 386 bytes
-rw-r--r--lib/images/license/button/cc-by.pngbin0 -> 369 bytes
-rw-r--r--lib/images/license/button/cc-zero.pngbin0 -> 386 bytes
-rw-r--r--lib/images/license/button/cc.pngbin0 -> 399 bytes
-rw-r--r--lib/images/license/button/gnufdl.pngbin0 -> 509 bytes
-rw-r--r--lib/images/license/button/publicdomain.pngbin0 -> 368 bytes
-rw-r--r--lib/images/list-minus.gifbin0 -> 64 bytes
-rw-r--r--lib/images/list-plus.gifbin0 -> 67 bytes
-rw-r--r--lib/images/loading.gifbin0 -> 337 bytes
-rw-r--r--lib/images/magnifier.pngbin0 -> 569 bytes
-rw-r--r--lib/images/media_align_center.pngbin0 -> 250 bytes
-rw-r--r--lib/images/media_align_left.pngbin0 -> 251 bytes
-rw-r--r--lib/images/media_align_noalign.pngbin0 -> 220 bytes
-rw-r--r--lib/images/media_align_right.pngbin0 -> 252 bytes
-rw-r--r--lib/images/media_link_direct.pngbin0 -> 720 bytes
-rw-r--r--lib/images/media_link_displaylnk.pngbin0 -> 306 bytes
-rw-r--r--lib/images/media_link_lnk.pngbin0 -> 580 bytes
-rw-r--r--lib/images/media_link_nolnk.pngbin0 -> 464 bytes
-rw-r--r--lib/images/media_size_large.pngbin0 -> 102 bytes
-rw-r--r--lib/images/media_size_medium.pngbin0 -> 231 bytes
-rw-r--r--lib/images/media_size_original.pngbin0 -> 212 bytes
-rw-r--r--lib/images/media_size_small.pngbin0 -> 210 bytes
-rw-r--r--lib/images/mediamanager.pngbin0 -> 507 bytes
-rw-r--r--lib/images/minus.gifbin0 -> 85 bytes
-rw-r--r--lib/images/notify.pngbin0 -> 736 bytes
-rw-r--r--lib/images/ns.pngbin0 -> 800 bytes
-rw-r--r--lib/images/page.pngbin0 -> 582 bytes
-rw-r--r--lib/images/pencil.pngbin0 -> 391 bytes
-rw-r--r--lib/images/plus.gifbin0 -> 88 bytes
-rw-r--r--lib/images/smaller.gifbin0 -> 86 bytes
-rw-r--r--lib/images/smileys/delete.gifbin0 -> 448 bytes
-rw-r--r--lib/images/smileys/facepalm.gifbin0 -> 185 bytes
-rw-r--r--lib/images/smileys/fixme.gifbin0 -> 450 bytes
-rw-r--r--lib/images/smileys/icon_arrow.gifbin0 -> 170 bytes
-rw-r--r--lib/images/smileys/icon_biggrin.gifbin0 -> 172 bytes
-rw-r--r--lib/images/smileys/icon_confused.gifbin0 -> 171 bytes
-rw-r--r--lib/images/smileys/icon_cool.gifbin0 -> 172 bytes
-rw-r--r--lib/images/smileys/icon_cry.gifbin0 -> 424 bytes
-rw-r--r--lib/images/smileys/icon_doubt.gifbin0 -> 178 bytes
-rw-r--r--lib/images/smileys/icon_doubt2.gifbin0 -> 180 bytes
-rw-r--r--lib/images/smileys/icon_eek.gifbin0 -> 170 bytes
-rw-r--r--lib/images/smileys/icon_evil.gifbin0 -> 188 bytes
-rw-r--r--lib/images/smileys/icon_exclaim.gifbin0 -> 171 bytes
-rw-r--r--lib/images/smileys/icon_frown.gifbin0 -> 171 bytes
-rw-r--r--lib/images/smileys/icon_fun.gifbin0 -> 179 bytes
-rw-r--r--lib/images/smileys/icon_idea.gifbin0 -> 176 bytes
-rw-r--r--lib/images/smileys/icon_kaddi.gifbin0 -> 179 bytes
-rw-r--r--lib/images/smileys/icon_lol.gifbin0 -> 344 bytes
-rw-r--r--lib/images/smileys/icon_mrgreen.gifbin0 -> 168 bytes
-rw-r--r--lib/images/smileys/icon_neutral.gifbin0 -> 171 bytes
-rw-r--r--lib/images/smileys/icon_question.gifbin0 -> 182 bytes
-rw-r--r--lib/images/smileys/icon_razz.gifbin0 -> 176 bytes
-rw-r--r--lib/images/smileys/icon_redface.gifbin0 -> 669 bytes
-rw-r--r--lib/images/smileys/icon_rolleyes.gifbin0 -> 471 bytes
-rw-r--r--lib/images/smileys/icon_sad.gifbin0 -> 171 bytes
-rw-r--r--lib/images/smileys/icon_silenced.gifbin0 -> 177 bytes
-rw-r--r--lib/images/smileys/icon_smile.gifbin0 -> 174 bytes
-rw-r--r--lib/images/smileys/icon_smile2.gifbin0 -> 174 bytes
-rw-r--r--lib/images/smileys/icon_surprised.gifbin0 -> 174 bytes
-rw-r--r--lib/images/smileys/icon_twisted.gifbin0 -> 180 bytes
-rw-r--r--lib/images/smileys/icon_wink.gifbin0 -> 170 bytes
-rw-r--r--lib/images/success.pngbin0 -> 728 bytes
-rw-r--r--lib/images/throbber.gifbin0 -> 746 bytes
-rw-r--r--lib/images/toolbar/bold.pngbin0 -> 251 bytes
-rw-r--r--lib/images/toolbar/chars.pngbin0 -> 496 bytes
-rw-r--r--lib/images/toolbar/h.pngbin0 -> 258 bytes
-rw-r--r--lib/images/toolbar/h1.pngbin0 -> 290 bytes
-rw-r--r--lib/images/toolbar/h2.pngbin0 -> 328 bytes
-rw-r--r--lib/images/toolbar/h3.pngbin0 -> 322 bytes
-rw-r--r--lib/images/toolbar/h4.pngbin0 -> 310 bytes
-rw-r--r--lib/images/toolbar/h5.pngbin0 -> 325 bytes
-rw-r--r--lib/images/toolbar/hequal.pngbin0 -> 311 bytes
-rw-r--r--lib/images/toolbar/hminus.pngbin0 -> 409 bytes
-rw-r--r--lib/images/toolbar/hplus.pngbin0 -> 396 bytes
-rw-r--r--lib/images/toolbar/hr.pngbin0 -> 254 bytes
-rw-r--r--lib/images/toolbar/image.pngbin0 -> 554 bytes
-rw-r--r--lib/images/toolbar/italic.pngbin0 -> 241 bytes
-rw-r--r--lib/images/toolbar/link.pngbin0 -> 405 bytes
-rw-r--r--lib/images/toolbar/linkextern.pngbin0 -> 904 bytes
-rw-r--r--lib/images/toolbar/mono.pngbin0 -> 296 bytes
-rw-r--r--lib/images/toolbar/ol.pngbin0 -> 304 bytes
-rw-r--r--lib/images/toolbar/sig.pngbin0 -> 471 bytes
-rw-r--r--lib/images/toolbar/smiley.pngbin0 -> 684 bytes
-rw-r--r--lib/images/toolbar/strike.pngbin0 -> 318 bytes
-rw-r--r--lib/images/toolbar/ul.pngbin0 -> 291 bytes
-rw-r--r--lib/images/toolbar/underline.pngbin0 -> 317 bytes
-rw-r--r--lib/images/trash.pngbin0 -> 423 bytes
-rw-r--r--lib/images/up.pngbin0 -> 248 bytes
-rw-r--r--lib/images/wrap.gifbin0 -> 86 bytes
-rw-r--r--lib/index.html12
-rw-r--r--lib/plugins/acl/admin.php824
-rw-r--r--lib/plugins/acl/ajax.php53
-rw-r--r--lib/plugins/acl/lang/af/lang.php10
-rw-r--r--lib/plugins/acl/lang/ar/help.txt11
-rw-r--r--lib/plugins/acl/lang/ar/lang.php38
-rw-r--r--lib/plugins/acl/lang/bg/help.txt11
-rw-r--r--lib/plugins/acl/lang/bg/lang.php37
-rw-r--r--lib/plugins/acl/lang/ca-valencia/help.txt15
-rw-r--r--lib/plugins/acl/lang/ca-valencia/lang.php37
-rw-r--r--lib/plugins/acl/lang/ca/help.txt11
-rw-r--r--lib/plugins/acl/lang/ca/lang.php38
-rw-r--r--lib/plugins/acl/lang/cs/help.txt11
-rw-r--r--lib/plugins/acl/lang/cs/lang.php41
-rw-r--r--lib/plugins/acl/lang/da/help.txt11
-rw-r--r--lib/plugins/acl/lang/da/lang.php44
-rw-r--r--lib/plugins/acl/lang/de-informal/help.txt11
-rw-r--r--lib/plugins/acl/lang/de-informal/lang.php39
-rw-r--r--lib/plugins/acl/lang/de/help.txt11
-rw-r--r--lib/plugins/acl/lang/de/lang.php52
-rw-r--r--lib/plugins/acl/lang/el/help.txt10
-rw-r--r--lib/plugins/acl/lang/el/lang.php45
-rw-r--r--lib/plugins/acl/lang/en/help.txt12
-rw-r--r--lib/plugins/acl/lang/en/lang.php46
-rw-r--r--lib/plugins/acl/lang/eo/help.txt11
-rw-r--r--lib/plugins/acl/lang/eo/lang.php42
-rw-r--r--lib/plugins/acl/lang/es/help.txt11
-rw-r--r--lib/plugins/acl/lang/es/lang.php53
-rw-r--r--lib/plugins/acl/lang/et/lang.php28
-rw-r--r--lib/plugins/acl/lang/eu/help.txt11
-rw-r--r--lib/plugins/acl/lang/eu/lang.php34
-rw-r--r--lib/plugins/acl/lang/fa/help.txt11
-rw-r--r--lib/plugins/acl/lang/fa/lang.php38
-rw-r--r--lib/plugins/acl/lang/fi/help.txt11
-rw-r--r--lib/plugins/acl/lang/fi/lang.php37
-rw-r--r--lib/plugins/acl/lang/fr/help.txt9
-rw-r--r--lib/plugins/acl/lang/fr/lang.php53
-rw-r--r--lib/plugins/acl/lang/gl/help.txt11
-rw-r--r--lib/plugins/acl/lang/gl/lang.php35
-rw-r--r--lib/plugins/acl/lang/he/help.txt11
-rw-r--r--lib/plugins/acl/lang/he/lang.php37
-rw-r--r--lib/plugins/acl/lang/hi/lang.php7
-rw-r--r--lib/plugins/acl/lang/hr/help.txt11
-rw-r--r--lib/plugins/acl/lang/hr/lang.php36
-rw-r--r--lib/plugins/acl/lang/hu/help.txt12
-rw-r--r--lib/plugins/acl/lang/hu/lang.php39
-rw-r--r--lib/plugins/acl/lang/ia/help.txt11
-rw-r--r--lib/plugins/acl/lang/ia/lang.php35
-rw-r--r--lib/plugins/acl/lang/id-ni/lang.php7
-rw-r--r--lib/plugins/acl/lang/id/lang.php21
-rw-r--r--lib/plugins/acl/lang/is/lang.php15
-rw-r--r--lib/plugins/acl/lang/it/help.txt11
-rw-r--r--lib/plugins/acl/lang/it/lang.php44
-rw-r--r--lib/plugins/acl/lang/ja/help.txt11
-rw-r--r--lib/plugins/acl/lang/ja/lang.php39
-rw-r--r--lib/plugins/acl/lang/kk/lang.php6
-rw-r--r--lib/plugins/acl/lang/ko/help.txt11
-rw-r--r--lib/plugins/acl/lang/ko/lang.php42
-rw-r--r--lib/plugins/acl/lang/la/help.txt11
-rw-r--r--lib/plugins/acl/lang/la/lang.php34
-rw-r--r--lib/plugins/acl/lang/lb/help.txt11
-rw-r--r--lib/plugins/acl/lang/lb/lang.php6
-rw-r--r--lib/plugins/acl/lang/lt/lang.php22
-rw-r--r--lib/plugins/acl/lang/lv/help.txt11
-rw-r--r--lib/plugins/acl/lang/lv/lang.php35
-rw-r--r--lib/plugins/acl/lang/mk/lang.php22
-rw-r--r--lib/plugins/acl/lang/mr/help.txt12
-rw-r--r--lib/plugins/acl/lang/mr/lang.php37
-rw-r--r--lib/plugins/acl/lang/ms/lang.php6
-rw-r--r--lib/plugins/acl/lang/ne/lang.php27
-rw-r--r--lib/plugins/acl/lang/nl/help.txt11
-rw-r--r--lib/plugins/acl/lang/nl/lang.php49
-rw-r--r--lib/plugins/acl/lang/no/help.txt11
-rw-r--r--lib/plugins/acl/lang/no/lang.php49
-rw-r--r--lib/plugins/acl/lang/pl/help.txt11
-rw-r--r--lib/plugins/acl/lang/pl/lang.php44
-rw-r--r--lib/plugins/acl/lang/pt-br/help.txt11
-rw-r--r--lib/plugins/acl/lang/pt-br/lang.php50
-rw-r--r--lib/plugins/acl/lang/pt/help.txt9
-rw-r--r--lib/plugins/acl/lang/pt/lang.php40
-rw-r--r--lib/plugins/acl/lang/ro/help.txt11
-rw-r--r--lib/plugins/acl/lang/ro/lang.php41
-rw-r--r--lib/plugins/acl/lang/ru/help.txt7
-rw-r--r--lib/plugins/acl/lang/ru/lang.php46
-rw-r--r--lib/plugins/acl/lang/sk/help.txt11
-rw-r--r--lib/plugins/acl/lang/sk/lang.php38
-rw-r--r--lib/plugins/acl/lang/sl/help.txt11
-rw-r--r--lib/plugins/acl/lang/sl/lang.php37
-rw-r--r--lib/plugins/acl/lang/sq/help.txt11
-rw-r--r--lib/plugins/acl/lang/sq/lang.php34
-rw-r--r--lib/plugins/acl/lang/sr/help.txt11
-rw-r--r--lib/plugins/acl/lang/sr/lang.php38
-rw-r--r--lib/plugins/acl/lang/sv/help.txt8
-rw-r--r--lib/plugins/acl/lang/sv/lang.php47
-rw-r--r--lib/plugins/acl/lang/th/help.txt11
-rw-r--r--lib/plugins/acl/lang/th/lang.php27
-rw-r--r--lib/plugins/acl/lang/tr/help.txt11
-rw-r--r--lib/plugins/acl/lang/tr/lang.php39
-rw-r--r--lib/plugins/acl/lang/uk/help.txt11
-rw-r--r--lib/plugins/acl/lang/uk/lang.php40
-rw-r--r--lib/plugins/acl/lang/vi/lang.php21
-rw-r--r--lib/plugins/acl/lang/zh-tw/help.txt12
-rw-r--r--lib/plugins/acl/lang/zh-tw/lang.php42
-rw-r--r--lib/plugins/acl/lang/zh/help.txt11
-rw-r--r--lib/plugins/acl/lang/zh/lang.php46
-rw-r--r--lib/plugins/acl/pix/group.pngbin0 -> 700 bytes
-rw-r--r--lib/plugins/acl/pix/ns.pngbin0 -> 800 bytes
-rw-r--r--lib/plugins/acl/pix/page.pngbin0 -> 582 bytes
-rw-r--r--lib/plugins/acl/pix/user.pngbin0 -> 653 bytes
-rw-r--r--lib/plugins/acl/plugin.info.txt6
-rw-r--r--lib/plugins/acl/rtl.css40
-rw-r--r--lib/plugins/acl/script.js127
-rw-r--r--lib/plugins/acl/style.css97
-rw-r--r--lib/plugins/action.php23
-rw-r--r--lib/plugins/admin.php46
-rw-r--r--lib/plugins/config/admin.php357
-rw-r--r--lib/plugins/config/images/danger.pngbin0 -> 648 bytes
-rw-r--r--lib/plugins/config/images/security.pngbin0 -> 706 bytes
-rw-r--r--lib/plugins/config/images/warning.pngbin0 -> 613 bytes
-rw-r--r--lib/plugins/config/lang/af/lang.php23
-rw-r--r--lib/plugins/config/lang/ar/intro.txt7
-rw-r--r--lib/plugins/config/lang/ar/lang.php185
-rw-r--r--lib/plugins/config/lang/bg/intro.txt7
-rw-r--r--lib/plugins/config/lang/bg/lang.php191
-rw-r--r--lib/plugins/config/lang/ca-valencia/intro.txt10
-rw-r--r--lib/plugins/config/lang/ca-valencia/lang.php182
-rw-r--r--lib/plugins/config/lang/ca/intro.txt7
-rw-r--r--lib/plugins/config/lang/ca/lang.php182
-rw-r--r--lib/plugins/config/lang/cs/intro.txt8
-rw-r--r--lib/plugins/config/lang/cs/lang.php201
-rw-r--r--lib/plugins/config/lang/da/intro.txt8
-rw-r--r--lib/plugins/config/lang/da/lang.php192
-rw-r--r--lib/plugins/config/lang/de-informal/intro.txt7
-rw-r--r--lib/plugins/config/lang/de-informal/lang.php191
-rw-r--r--lib/plugins/config/lang/de/intro.txt10
-rw-r--r--lib/plugins/config/lang/de/lang.php202
-rw-r--r--lib/plugins/config/lang/el/intro.txt7
-rw-r--r--lib/plugins/config/lang/el/lang.php195
-rw-r--r--lib/plugins/config/lang/en/intro.txt9
-rw-r--r--lib/plugins/config/lang/en/lang.php245
-rw-r--r--lib/plugins/config/lang/eo/intro.txt7
-rw-r--r--lib/plugins/config/lang/eo/lang.php196
-rw-r--r--lib/plugins/config/lang/es/intro.txt7
-rw-r--r--lib/plugins/config/lang/es/lang.php205
-rw-r--r--lib/plugins/config/lang/et/lang.php32
-rw-r--r--lib/plugins/config/lang/eu/intro.txt7
-rw-r--r--lib/plugins/config/lang/eu/lang.php184
-rw-r--r--lib/plugins/config/lang/fa/intro.txt8
-rw-r--r--lib/plugins/config/lang/fa/lang.php187
-rw-r--r--lib/plugins/config/lang/fi/intro.txt7
-rw-r--r--lib/plugins/config/lang/fi/lang.php191
-rw-r--r--lib/plugins/config/lang/fr/intro.txt9
-rw-r--r--lib/plugins/config/lang/fr/lang.php201
-rw-r--r--lib/plugins/config/lang/gl/intro.txt7
-rw-r--r--lib/plugins/config/lang/gl/lang.php188
-rw-r--r--lib/plugins/config/lang/he/intro.txt9
-rw-r--r--lib/plugins/config/lang/he/lang.php169
-rw-r--r--lib/plugins/config/lang/hi/lang.php14
-rw-r--r--lib/plugins/config/lang/hr/lang.php8
-rw-r--r--lib/plugins/config/lang/hu/intro.txt9
-rw-r--r--lib/plugins/config/lang/hu/lang.php190
-rw-r--r--lib/plugins/config/lang/ia/intro.txt7
-rw-r--r--lib/plugins/config/lang/ia/lang.php180
-rw-r--r--lib/plugins/config/lang/id-ni/intro.txt7
-rw-r--r--lib/plugins/config/lang/id-ni/lang.php69
-rw-r--r--lib/plugins/config/lang/id/intro.txt5
-rw-r--r--lib/plugins/config/lang/id/lang.php7
-rw-r--r--lib/plugins/config/lang/is/lang.php58
-rw-r--r--lib/plugins/config/lang/it/intro.txt9
-rw-r--r--lib/plugins/config/lang/it/lang.php195
-rw-r--r--lib/plugins/config/lang/ja/intro.txt9
-rw-r--r--lib/plugins/config/lang/ja/lang.php193
-rw-r--r--lib/plugins/config/lang/kk/lang.php6
-rw-r--r--lib/plugins/config/lang/ko/intro.txt9
-rw-r--r--lib/plugins/config/lang/ko/lang.php192
-rw-r--r--lib/plugins/config/lang/la/intro.txt7
-rw-r--r--lib/plugins/config/lang/la/lang.php181
-rw-r--r--lib/plugins/config/lang/lb/intro.txt7
-rw-r--r--lib/plugins/config/lang/lb/lang.php6
-rw-r--r--lib/plugins/config/lang/lt/intro.txt7
-rw-r--r--lib/plugins/config/lang/lt/lang.php22
-rw-r--r--lib/plugins/config/lang/lv/intro.txt7
-rw-r--r--lib/plugins/config/lang/lv/lang.php185
-rw-r--r--lib/plugins/config/lang/mk/lang.php6
-rw-r--r--lib/plugins/config/lang/mr/intro.txt10
-rw-r--r--lib/plugins/config/lang/mr/lang.php182
-rw-r--r--lib/plugins/config/lang/ms/lang.php6
-rw-r--r--lib/plugins/config/lang/ne/lang.php70
-rw-r--r--lib/plugins/config/lang/nl/intro.txt9
-rw-r--r--lib/plugins/config/lang/nl/lang.php198
-rw-r--r--lib/plugins/config/lang/no/intro.txt7
-rw-r--r--lib/plugins/config/lang/no/lang.php204
-rw-r--r--lib/plugins/config/lang/pl/intro.txt9
-rw-r--r--lib/plugins/config/lang/pl/lang.php199
-rw-r--r--lib/plugins/config/lang/pt-br/intro.txt7
-rw-r--r--lib/plugins/config/lang/pt-br/lang.php200
-rw-r--r--lib/plugins/config/lang/pt/intro.txt7
-rw-r--r--lib/plugins/config/lang/pt/lang.php189
-rw-r--r--lib/plugins/config/lang/ro/intro.txt7
-rw-r--r--lib/plugins/config/lang/ro/lang.php193
-rw-r--r--lib/plugins/config/lang/ru/intro.txt9
-rw-r--r--lib/plugins/config/lang/ru/lang.php196
-rw-r--r--lib/plugins/config/lang/sk/intro.txt7
-rw-r--r--lib/plugins/config/lang/sk/lang.php189
-rw-r--r--lib/plugins/config/lang/sl/intro.txt7
-rw-r--r--lib/plugins/config/lang/sl/lang.php191
-rw-r--r--lib/plugins/config/lang/sq/intro.txt7
-rw-r--r--lib/plugins/config/lang/sq/lang.php180
-rw-r--r--lib/plugins/config/lang/sr/intro.txt7
-rw-r--r--lib/plugins/config/lang/sr/lang.php184
-rw-r--r--lib/plugins/config/lang/sv/intro.txt9
-rw-r--r--lib/plugins/config/lang/sv/lang.php194
-rw-r--r--lib/plugins/config/lang/th/lang.php106
-rw-r--r--lib/plugins/config/lang/tr/intro.txt7
-rw-r--r--lib/plugins/config/lang/tr/lang.php135
-rw-r--r--lib/plugins/config/lang/uk/intro.txt7
-rw-r--r--lib/plugins/config/lang/uk/lang.php192
-rw-r--r--lib/plugins/config/lang/zh-tw/intro.txt7
-rw-r--r--lib/plugins/config/lang/zh-tw/lang.php192
-rw-r--r--lib/plugins/config/lang/zh/intro.txt9
-rw-r--r--lib/plugins/config/lang/zh/lang.php200
-rw-r--r--lib/plugins/config/plugin.info.txt6
-rw-r--r--lib/plugins/config/rtl.css45
-rw-r--r--lib/plugins/config/settings/config.class.php1057
-rw-r--r--lib/plugins/config/settings/config.metadata.php216
-rw-r--r--lib/plugins/config/settings/extra.class.php175
-rw-r--r--lib/plugins/config/style.css136
-rw-r--r--lib/plugins/index.html12
-rw-r--r--lib/plugins/info/lang/sl/lang.php12
-rw-r--r--lib/plugins/info/plugin.info.txt6
-rw-r--r--lib/plugins/info/syntax.php256
-rw-r--r--lib/plugins/plugin/admin.php151
-rw-r--r--lib/plugins/plugin/classes/ap_delete.class.php28
-rw-r--r--lib/plugins/plugin/classes/ap_download.class.php294
-rw-r--r--lib/plugins/plugin/classes/ap_enable.class.php49
-rw-r--r--lib/plugins/plugin/classes/ap_info.class.php144
-rw-r--r--lib/plugins/plugin/classes/ap_manage.class.php197
-rw-r--r--lib/plugins/plugin/classes/ap_update.class.php38
-rw-r--r--lib/plugins/plugin/lang/af/lang.php13
-rw-r--r--lib/plugins/plugin/lang/ar/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/ar/lang.php52
-rw-r--r--lib/plugins/plugin/lang/bg/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/bg/lang.php54
-rw-r--r--lib/plugins/plugin/lang/ca-valencia/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/ca-valencia/lang.php53
-rw-r--r--lib/plugins/plugin/lang/ca/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/ca/lang.php53
-rw-r--r--lib/plugins/plugin/lang/cs/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/cs/lang.php60
-rw-r--r--lib/plugins/plugin/lang/da/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/da/lang.php58
-rw-r--r--lib/plugins/plugin/lang/de-informal/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/de-informal/lang.php56
-rw-r--r--lib/plugins/plugin/lang/de/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/de/lang.php66
-rw-r--r--lib/plugins/plugin/lang/el/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/el/lang.php60
-rw-r--r--lib/plugins/plugin/lang/en/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/en/lang.php78
-rw-r--r--lib/plugins/plugin/lang/eo/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/eo/lang.php60
-rw-r--r--lib/plugins/plugin/lang/es/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/es/lang.php70
-rw-r--r--lib/plugins/plugin/lang/et/lang.php32
-rw-r--r--lib/plugins/plugin/lang/eu/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/eu/lang.php51
-rw-r--r--lib/plugins/plugin/lang/fa/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/fa/lang.php55
-rw-r--r--lib/plugins/plugin/lang/fi/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/fi/lang.php54
-rw-r--r--lib/plugins/plugin/lang/fr/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/fr/lang.php65
-rw-r--r--lib/plugins/plugin/lang/gl/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/gl/lang.php52
-rw-r--r--lib/plugins/plugin/lang/he/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/he/lang.php55
-rw-r--r--lib/plugins/plugin/lang/hi/lang.php12
-rw-r--r--lib/plugins/plugin/lang/hr/lang.php8
-rw-r--r--lib/plugins/plugin/lang/hu/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/hu/lang.php56
-rw-r--r--lib/plugins/plugin/lang/ia/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/ia/lang.php51
-rw-r--r--lib/plugins/plugin/lang/id-ni/lang.php7
-rw-r--r--lib/plugins/plugin/lang/id/lang.php31
-rw-r--r--lib/plugins/plugin/lang/is/lang.php47
-rw-r--r--lib/plugins/plugin/lang/it/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/it/lang.php60
-rw-r--r--lib/plugins/plugin/lang/ja/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/ja/lang.php56
-rw-r--r--lib/plugins/plugin/lang/kk/lang.php6
-rw-r--r--lib/plugins/plugin/lang/ko/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/ko/lang.php56
-rw-r--r--lib/plugins/plugin/lang/la/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/la/lang.php50
-rw-r--r--lib/plugins/plugin/lang/lb/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/lb/lang.php6
-rw-r--r--lib/plugins/plugin/lang/lt/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/lt/lang.php13
-rw-r--r--lib/plugins/plugin/lang/lv/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/lv/lang.php50
-rw-r--r--lib/plugins/plugin/lang/mk/lang.php43
-rw-r--r--lib/plugins/plugin/lang/mr/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/mr/lang.php53
-rw-r--r--lib/plugins/plugin/lang/ms/lang.php6
-rw-r--r--lib/plugins/plugin/lang/ne/lang.php45
-rw-r--r--lib/plugins/plugin/lang/nl/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/nl/lang.php61
-rw-r--r--lib/plugins/plugin/lang/no/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/no/lang.php63
-rw-r--r--lib/plugins/plugin/lang/pl/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/pl/lang.php62
-rw-r--r--lib/plugins/plugin/lang/pt-br/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/pt-br/lang.php64
-rw-r--r--lib/plugins/plugin/lang/pt/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/pt/lang.php55
-rw-r--r--lib/plugins/plugin/lang/ro/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/ro/lang.php58
-rw-r--r--lib/plugins/plugin/lang/ru/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/ru/lang.php63
-rw-r--r--lib/plugins/plugin/lang/sk/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/sk/lang.php54
-rw-r--r--lib/plugins/plugin/lang/sl/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/sl/lang.php54
-rw-r--r--lib/plugins/plugin/lang/sq/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/sq/lang.php50
-rw-r--r--lib/plugins/plugin/lang/sr/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/sr/lang.php52
-rw-r--r--lib/plugins/plugin/lang/sv/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/sv/lang.php63
-rw-r--r--lib/plugins/plugin/lang/th/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/th/lang.php50
-rw-r--r--lib/plugins/plugin/lang/tr/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/tr/lang.php53
-rw-r--r--lib/plugins/plugin/lang/uk/admin_plugin.txt7
-rw-r--r--lib/plugins/plugin/lang/uk/lang.php58
-rw-r--r--lib/plugins/plugin/lang/zh-tw/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/zh-tw/lang.php57
-rw-r--r--lib/plugins/plugin/lang/zh/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/zh/lang.php63
-rw-r--r--lib/plugins/plugin/rtl.css51
-rw-r--r--lib/plugins/plugin/style.css156
-rw-r--r--lib/plugins/popularity/action.php57
-rw-r--r--lib/plugins/popularity/admin.php148
-rw-r--r--lib/plugins/popularity/helper.php292
-rw-r--r--lib/plugins/popularity/lang/af/lang.php6
-rw-r--r--lib/plugins/popularity/lang/ar/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ar/lang.php15
-rw-r--r--lib/plugins/popularity/lang/ar/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/bg/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/bg/lang.php14
-rw-r--r--lib/plugins/popularity/lang/bg/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/ca-valencia/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ca-valencia/lang.php9
-rw-r--r--lib/plugins/popularity/lang/ca/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ca/lang.php10
-rw-r--r--lib/plugins/popularity/lang/cs/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/cs/lang.php18
-rw-r--r--lib/plugins/popularity/lang/cs/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/da/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/da/lang.php14
-rw-r--r--lib/plugins/popularity/lang/de-informal/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/de-informal/lang.php18
-rw-r--r--lib/plugins/popularity/lang/de-informal/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/de/intro.txt11
-rw-r--r--lib/plugins/popularity/lang/de/lang.php25
-rw-r--r--lib/plugins/popularity/lang/de/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/el/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/el/lang.php15
-rw-r--r--lib/plugins/popularity/lang/el/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/en/intro.txt11
-rw-r--r--lib/plugins/popularity/lang/en/lang.php9
-rw-r--r--lib/plugins/popularity/lang/en/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/eo/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/eo/lang.php20
-rw-r--r--lib/plugins/popularity/lang/eo/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/es/intro.txt10
-rw-r--r--lib/plugins/popularity/lang/es/lang.php29
-rw-r--r--lib/plugins/popularity/lang/es/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/et/lang.php7
-rw-r--r--lib/plugins/popularity/lang/eu/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/eu/lang.php13
-rw-r--r--lib/plugins/popularity/lang/eu/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/fa/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/fa/lang.php17
-rw-r--r--lib/plugins/popularity/lang/fa/submitted.txt2
-rw-r--r--lib/plugins/popularity/lang/fi/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/fi/lang.php15
-rw-r--r--lib/plugins/popularity/lang/fi/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/fr/intro.txt10
-rw-r--r--lib/plugins/popularity/lang/fr/lang.php24
-rw-r--r--lib/plugins/popularity/lang/fr/submitted.txt2
-rw-r--r--lib/plugins/popularity/lang/gl/intro.txt10
-rw-r--r--lib/plugins/popularity/lang/gl/lang.php14
-rw-r--r--lib/plugins/popularity/lang/gl/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/he/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/he/lang.php11
-rw-r--r--lib/plugins/popularity/lang/hi/lang.php8
-rw-r--r--lib/plugins/popularity/lang/hr/lang.php8
-rw-r--r--lib/plugins/popularity/lang/hu/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/hu/lang.php18
-rw-r--r--lib/plugins/popularity/lang/hu/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/ia/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ia/lang.php9
-rw-r--r--lib/plugins/popularity/lang/id-ni/intro.txt7
-rw-r--r--lib/plugins/popularity/lang/id-ni/lang.php9
-rw-r--r--lib/plugins/popularity/lang/id/lang.php6
-rw-r--r--lib/plugins/popularity/lang/is/lang.php9
-rw-r--r--lib/plugins/popularity/lang/it/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/it/lang.php19
-rw-r--r--lib/plugins/popularity/lang/it/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/ja/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ja/lang.php16
-rw-r--r--lib/plugins/popularity/lang/ja/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/kk/lang.php6
-rw-r--r--lib/plugins/popularity/lang/ko/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ko/lang.php17
-rw-r--r--lib/plugins/popularity/lang/ko/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/la/intro.txt10
-rw-r--r--lib/plugins/popularity/lang/la/lang.php13
-rw-r--r--lib/plugins/popularity/lang/la/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/lb/lang.php6
-rw-r--r--lib/plugins/popularity/lang/lt/lang.php9
-rw-r--r--lib/plugins/popularity/lang/lv/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/lv/lang.php13
-rw-r--r--lib/plugins/popularity/lang/lv/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/mk/lang.php6
-rw-r--r--lib/plugins/popularity/lang/mr/intro.txt8
-rw-r--r--lib/plugins/popularity/lang/mr/lang.php11
-rw-r--r--lib/plugins/popularity/lang/ms/lang.php6
-rw-r--r--lib/plugins/popularity/lang/ne/lang.php9
-rw-r--r--lib/plugins/popularity/lang/nl/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/nl/lang.php22
-rw-r--r--lib/plugins/popularity/lang/nl/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/no/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/no/lang.php23
-rw-r--r--lib/plugins/popularity/lang/no/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/pl/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/pl/lang.php22
-rw-r--r--lib/plugins/popularity/lang/pl/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/pt-br/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/pt-br/lang.php25
-rw-r--r--lib/plugins/popularity/lang/pt-br/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/pt/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/pt/lang.php16
-rw-r--r--lib/plugins/popularity/lang/pt/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/ro/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ro/lang.php18
-rw-r--r--lib/plugins/popularity/lang/ro/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/ru/intro.txt10
-rw-r--r--lib/plugins/popularity/lang/ru/lang.php23
-rw-r--r--lib/plugins/popularity/lang/ru/submitted.txt2
-rw-r--r--lib/plugins/popularity/lang/sk/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/sk/lang.php15
-rw-r--r--lib/plugins/popularity/lang/sk/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/sl/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/sl/lang.php13
-rw-r--r--lib/plugins/popularity/lang/sl/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/sq/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/sq/lang.php8
-rw-r--r--lib/plugins/popularity/lang/sr/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/sr/lang.php10
-rw-r--r--lib/plugins/popularity/lang/sv/intro.txt11
-rw-r--r--lib/plugins/popularity/lang/sv/lang.php23
-rw-r--r--lib/plugins/popularity/lang/sv/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/th/lang.php11
-rw-r--r--lib/plugins/popularity/lang/tr/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/tr/lang.php11
-rw-r--r--lib/plugins/popularity/lang/uk/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/uk/lang.php18
-rw-r--r--lib/plugins/popularity/lang/uk/submitted.txt2
-rw-r--r--lib/plugins/popularity/lang/zh-tw/intro.txt10
-rw-r--r--lib/plugins/popularity/lang/zh-tw/lang.php19
-rw-r--r--lib/plugins/popularity/lang/zh-tw/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/zh/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/zh/lang.php24
-rw-r--r--lib/plugins/popularity/lang/zh/submitted.txt3
-rw-r--r--lib/plugins/popularity/plugin.info.txt7
-rw-r--r--lib/plugins/revert/admin.php185
-rw-r--r--lib/plugins/revert/lang/af/lang.php5
-rw-r--r--lib/plugins/revert/lang/ar/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ar/lang.php18
-rw-r--r--lib/plugins/revert/lang/bg/intro.txt4
-rw-r--r--lib/plugins/revert/lang/bg/lang.php16
-rw-r--r--lib/plugins/revert/lang/ca-valencia/intro.txt4
-rw-r--r--lib/plugins/revert/lang/ca-valencia/lang.php15
-rw-r--r--lib/plugins/revert/lang/ca/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ca/lang.php18
-rw-r--r--lib/plugins/revert/lang/cs/intro.txt3
-rw-r--r--lib/plugins/revert/lang/cs/lang.php26
-rw-r--r--lib/plugins/revert/lang/da/intro.txt3
-rw-r--r--lib/plugins/revert/lang/da/lang.php21
-rw-r--r--lib/plugins/revert/lang/de-informal/intro.txt3
-rw-r--r--lib/plugins/revert/lang/de-informal/lang.php20
-rw-r--r--lib/plugins/revert/lang/de/intro.txt3
-rw-r--r--lib/plugins/revert/lang/de/lang.php28
-rw-r--r--lib/plugins/revert/lang/el/intro.txt3
-rw-r--r--lib/plugins/revert/lang/el/lang.php22
-rw-r--r--lib/plugins/revert/lang/en/intro.txt3
-rw-r--r--lib/plugins/revert/lang/en/lang.php23
-rw-r--r--lib/plugins/revert/lang/eo/intro.txt3
-rw-r--r--lib/plugins/revert/lang/eo/lang.php24
-rw-r--r--lib/plugins/revert/lang/es/intro.txt3
-rw-r--r--lib/plugins/revert/lang/es/lang.php32
-rw-r--r--lib/plugins/revert/lang/et/lang.php7
-rw-r--r--lib/plugins/revert/lang/eu/intro.txt3
-rw-r--r--lib/plugins/revert/lang/eu/lang.php17
-rw-r--r--lib/plugins/revert/lang/fa/intro.txt3
-rw-r--r--lib/plugins/revert/lang/fa/lang.php19
-rw-r--r--lib/plugins/revert/lang/fi/intro.txt3
-rw-r--r--lib/plugins/revert/lang/fi/lang.php18
-rw-r--r--lib/plugins/revert/lang/fr/intro.txt3
-rw-r--r--lib/plugins/revert/lang/fr/lang.php27
-rw-r--r--lib/plugins/revert/lang/gl/intro.txt3
-rw-r--r--lib/plugins/revert/lang/gl/lang.php16
-rw-r--r--lib/plugins/revert/lang/he/intro.txt3
-rw-r--r--lib/plugins/revert/lang/he/lang.php18
-rw-r--r--lib/plugins/revert/lang/hi/lang.php7
-rw-r--r--lib/plugins/revert/lang/hr/lang.php8
-rw-r--r--lib/plugins/revert/lang/hu/intro.txt3
-rw-r--r--lib/plugins/revert/lang/hu/lang.php20
-rw-r--r--lib/plugins/revert/lang/ia/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ia/lang.php16
-rw-r--r--lib/plugins/revert/lang/id-ni/lang.php7
-rw-r--r--lib/plugins/revert/lang/id/lang.php7
-rw-r--r--lib/plugins/revert/lang/is/lang.php10
-rw-r--r--lib/plugins/revert/lang/it/intro.txt3
-rw-r--r--lib/plugins/revert/lang/it/lang.php22
-rw-r--r--lib/plugins/revert/lang/ja/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ja/lang.php17
-rw-r--r--lib/plugins/revert/lang/kk/lang.php6
-rw-r--r--lib/plugins/revert/lang/ko/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ko/lang.php19
-rw-r--r--lib/plugins/revert/lang/la/intro.txt3
-rw-r--r--lib/plugins/revert/lang/la/lang.php15
-rw-r--r--lib/plugins/revert/lang/lb/intro.txt3
-rw-r--r--lib/plugins/revert/lang/lb/lang.php6
-rw-r--r--lib/plugins/revert/lang/lt/lang.php7
-rw-r--r--lib/plugins/revert/lang/lv/intro.txt3
-rw-r--r--lib/plugins/revert/lang/lv/lang.php15
-rw-r--r--lib/plugins/revert/lang/mk/lang.php6
-rw-r--r--lib/plugins/revert/lang/mr/intro.txt5
-rw-r--r--lib/plugins/revert/lang/mr/lang.php18
-rw-r--r--lib/plugins/revert/lang/ms/lang.php6
-rw-r--r--lib/plugins/revert/lang/ne/lang.php16
-rw-r--r--lib/plugins/revert/lang/nl/intro.txt3
-rw-r--r--lib/plugins/revert/lang/nl/lang.php25
-rw-r--r--lib/plugins/revert/lang/no/intro.txt3
-rw-r--r--lib/plugins/revert/lang/no/lang.php29
-rw-r--r--lib/plugins/revert/lang/pl/intro.txt3
-rw-r--r--lib/plugins/revert/lang/pl/lang.php23
-rw-r--r--lib/plugins/revert/lang/pt-br/intro.txt3
-rw-r--r--lib/plugins/revert/lang/pt-br/lang.php28
-rw-r--r--lib/plugins/revert/lang/pt/intro.txt3
-rw-r--r--lib/plugins/revert/lang/pt/lang.php19
-rw-r--r--lib/plugins/revert/lang/ro/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ro/lang.php22
-rw-r--r--lib/plugins/revert/lang/ru/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ru/lang.php26
-rw-r--r--lib/plugins/revert/lang/sk/intro.txt0
-rw-r--r--lib/plugins/revert/lang/sk/lang.php17
-rw-r--r--lib/plugins/revert/lang/sl/intro.txt3
-rw-r--r--lib/plugins/revert/lang/sl/lang.php15
-rw-r--r--lib/plugins/revert/lang/sq/intro.txt3
-rw-r--r--lib/plugins/revert/lang/sq/lang.php15
-rw-r--r--lib/plugins/revert/lang/sr/intro.txt3
-rw-r--r--lib/plugins/revert/lang/sr/lang.php17
-rw-r--r--lib/plugins/revert/lang/sv/intro.txt3
-rw-r--r--lib/plugins/revert/lang/sv/lang.php29
-rw-r--r--lib/plugins/revert/lang/th/intro.txt3
-rw-r--r--lib/plugins/revert/lang/th/lang.php19
-rw-r--r--lib/plugins/revert/lang/tr/intro.txt3
-rw-r--r--lib/plugins/revert/lang/tr/lang.php18
-rw-r--r--lib/plugins/revert/lang/uk/intro.txt3
-rw-r--r--lib/plugins/revert/lang/uk/lang.php20
-rw-r--r--lib/plugins/revert/lang/zh-tw/intro.txt3
-rw-r--r--lib/plugins/revert/lang/zh-tw/lang.php21
-rw-r--r--lib/plugins/revert/lang/zh/intro.txt3
-rw-r--r--lib/plugins/revert/lang/zh/lang.php27
-rw-r--r--lib/plugins/revert/plugin.info.txt6
-rw-r--r--lib/plugins/safefnrecode/action.php68
-rw-r--r--lib/plugins/safefnrecode/plugin.info.txt7
-rw-r--r--lib/plugins/syntax.php282
-rw-r--r--lib/plugins/usermanager/admin.php630
-rw-r--r--lib/plugins/usermanager/images/search.pngbin0 -> 550 bytes
-rw-r--r--lib/plugins/usermanager/lang/af/lang.php14
-rw-r--r--lib/plugins/usermanager/lang/ar/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ar/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ar/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ar/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ar/lang.php49
-rw-r--r--lib/plugins/usermanager/lang/ar/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/bg/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/bg/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/bg/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/bg/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/bg/lang.php49
-rw-r--r--lib/plugins/usermanager/lang/bg/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca-valencia/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca-valencia/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca-valencia/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca-valencia/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca-valencia/lang.php49
-rw-r--r--lib/plugins/usermanager/lang/ca-valencia/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/ca/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/cs/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/cs/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/cs/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/cs/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/cs/lang.php54
-rw-r--r--lib/plugins/usermanager/lang/cs/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/da/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/da/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/da/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/da/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/da/lang.php54
-rw-r--r--lib/plugins/usermanager/lang/da/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/de-informal/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/de-informal/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/de-informal/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/de-informal/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/de-informal/lang.php52
-rw-r--r--lib/plugins/usermanager/lang/de-informal/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/de/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/de/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/de/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/de/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/de/lang.php61
-rw-r--r--lib/plugins/usermanager/lang/de/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/el/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/el/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/el/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/el/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/el/lang.php55
-rw-r--r--lib/plugins/usermanager/lang/el/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/en/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/en/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/en/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/en/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/en/lang.php58
-rw-r--r--lib/plugins/usermanager/lang/en/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/eo/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/eo/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/eo/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/eo/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/eo/lang.php56
-rw-r--r--lib/plugins/usermanager/lang/eo/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/es/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/es/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/es/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/es/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/es/lang.php65
-rw-r--r--lib/plugins/usermanager/lang/es/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/et/lang.php30
-rw-r--r--lib/plugins/usermanager/lang/eu/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/eu/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/eu/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/eu/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/eu/lang.php47
-rw-r--r--lib/plugins/usermanager/lang/eu/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/fa/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/fa/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/fa/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/fa/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/fa/lang.php51
-rw-r--r--lib/plugins/usermanager/lang/fa/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/fi/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/fi/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/fi/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/fi/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/fi/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/fi/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/fr/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/fr/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/fr/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/fr/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/fr/lang.php60
-rw-r--r--lib/plugins/usermanager/lang/fr/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/gl/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/gl/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/gl/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/gl/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/gl/lang.php48
-rw-r--r--lib/plugins/usermanager/lang/gl/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/he/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/he/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/he/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/he/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/he/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/he/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/hi/lang.php7
-rw-r--r--lib/plugins/usermanager/lang/hr/lang.php8
-rw-r--r--lib/plugins/usermanager/lang/hu/add.txt2
-rw-r--r--lib/plugins/usermanager/lang/hu/delete.txt2
-rw-r--r--lib/plugins/usermanager/lang/hu/edit.txt2
-rw-r--r--lib/plugins/usermanager/lang/hu/intro.txt2
-rw-r--r--lib/plugins/usermanager/lang/hu/lang.php52
-rw-r--r--lib/plugins/usermanager/lang/hu/list.txt2
-rw-r--r--lib/plugins/usermanager/lang/ia/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ia/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ia/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ia/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ia/lang.php49
-rw-r--r--lib/plugins/usermanager/lang/ia/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/id-ni/lang.php7
-rw-r--r--lib/plugins/usermanager/lang/id/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/id/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/id/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/id/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/id/lang.php47
-rw-r--r--lib/plugins/usermanager/lang/id/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/is/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/is/lang.php18
-rw-r--r--lib/plugins/usermanager/lang/it/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/it/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/it/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/it/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/it/lang.php56
-rw-r--r--lib/plugins/usermanager/lang/it/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/ja/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ja/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ja/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ja/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ja/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/ja/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/kk/lang.php6
-rw-r--r--lib/plugins/usermanager/lang/ko/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ko/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ko/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ko/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ko/lang.php51
-rw-r--r--lib/plugins/usermanager/lang/ko/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/la/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/la/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/la/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/la/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/la/lang.php47
-rw-r--r--lib/plugins/usermanager/lang/la/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/lb/lang.php6
-rw-r--r--lib/plugins/usermanager/lang/lb/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/lt/add.txt2
-rw-r--r--lib/plugins/usermanager/lang/lt/delete.txt2
-rw-r--r--lib/plugins/usermanager/lang/lt/edit.txt2
-rw-r--r--lib/plugins/usermanager/lang/lt/intro.txt2
-rw-r--r--lib/plugins/usermanager/lang/lt/lang.php48
-rw-r--r--lib/plugins/usermanager/lang/lt/list.txt2
-rw-r--r--lib/plugins/usermanager/lang/lv/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/lv/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/lv/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/lv/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/lv/lang.php48
-rw-r--r--lib/plugins/usermanager/lang/lv/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/mk/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/mk/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/mk/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/mk/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/mk/lang.php38
-rw-r--r--lib/plugins/usermanager/lang/mk/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/mr/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/mr/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/mr/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/mr/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/mr/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/mr/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/ms/lang.php6
-rw-r--r--lib/plugins/usermanager/lang/ne/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ne/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ne/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ne/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ne/lang.php49
-rw-r--r--lib/plugins/usermanager/lang/ne/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/nl/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/nl/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/nl/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/nl/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/nl/lang.php57
-rw-r--r--lib/plugins/usermanager/lang/nl/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/no/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/no/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/no/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/no/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/no/lang.php59
-rw-r--r--lib/plugins/usermanager/lang/no/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/pl/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/pl/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/pl/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/pl/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/pl/lang.php56
-rw-r--r--lib/plugins/usermanager/lang/pl/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt-br/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt-br/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt-br/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt-br/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt-br/lang.php60
-rw-r--r--lib/plugins/usermanager/lang/pt-br/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt/lang.php51
-rw-r--r--lib/plugins/usermanager/lang/pt/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/ro/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ro/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ro/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ro/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ro/lang.php54
-rw-r--r--lib/plugins/usermanager/lang/ro/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/ru/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ru/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ru/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ru/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ru/lang.php60
-rw-r--r--lib/plugins/usermanager/lang/ru/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/sk/add.txt2
-rw-r--r--lib/plugins/usermanager/lang/sk/delete.txt2
-rw-r--r--lib/plugins/usermanager/lang/sk/edit.txt2
-rw-r--r--lib/plugins/usermanager/lang/sk/intro.txt2
-rw-r--r--lib/plugins/usermanager/lang/sk/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/sk/list.txt2
-rw-r--r--lib/plugins/usermanager/lang/sl/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/sl/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/sl/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/sl/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/sl/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/sl/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/sq/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/sq/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/sq/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/sq/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/sq/lang.php48
-rw-r--r--lib/plugins/usermanager/lang/sq/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/sr/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/sr/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/sr/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/sr/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/sr/lang.php49
-rw-r--r--lib/plugins/usermanager/lang/sr/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/sv/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/sv/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/sv/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/sv/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/sv/lang.php59
-rw-r--r--lib/plugins/usermanager/lang/sv/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/th/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/th/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/th/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/th/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/th/lang.php47
-rw-r--r--lib/plugins/usermanager/lang/th/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/tr/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/tr/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/tr/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/tr/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/tr/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/tr/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/uk/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/uk/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/uk/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/uk/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/uk/lang.php53
-rw-r--r--lib/plugins/usermanager/lang/uk/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh-tw/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh-tw/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh-tw/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh-tw/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh-tw/lang.php54
-rw-r--r--lib/plugins/usermanager/lang/zh-tw/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh/lang.php58
-rw-r--r--lib/plugins/usermanager/lang/zh/list.txt1
-rw-r--r--lib/plugins/usermanager/plugin.info.txt6
-rw-r--r--lib/plugins/usermanager/script.js8
-rw-r--r--lib/plugins/usermanager/style.css20
-rw-r--r--lib/scripts/behaviour.js180
-rw-r--r--lib/scripts/compatibility.js414
-rw-r--r--lib/scripts/cookie.js64
-rw-r--r--lib/scripts/delay.js70
-rw-r--r--lib/scripts/drag.js87
-rw-r--r--lib/scripts/edit.js268
-rw-r--r--lib/scripts/editor.js204
-rw-r--r--lib/scripts/fileuploader.js1247
-rw-r--r--lib/scripts/fileuploaderextended.js344
-rw-r--r--lib/scripts/helpers.js70
-rw-r--r--lib/scripts/hotkeys.js302
-rw-r--r--lib/scripts/index.html12
-rw-r--r--lib/scripts/index.js16
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_0_aaaaaa_40x100.pngbin0 -> 180 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_75_ffffff_40x100.pngbin0 -> 178 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_55_fbf9ee_1x400.pngbin0 -> 120 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_65_ffffff_1x400.pngbin0 -> 105 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_dadada_1x400.pngbin0 -> 111 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_e6e6e6_1x400.pngbin0 -> 110 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_95_fef1ec_1x400.pngbin0 -> 119 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.pngbin0 -> 101 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-icons_222222_256x240.pngbin0 -> 4369 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-icons_2e83ff_256x240.pngbin0 -> 4369 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-icons_454545_256x240.pngbin0 -> 4369 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-icons_888888_256x240.pngbin0 -> 4369 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-icons_cd0a0a_256x240.pngbin0 -> 4369 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/smoothness.css568
-rw-r--r--lib/scripts/jquery/jquery-ui.js11767
-rw-r--r--lib/scripts/jquery/jquery-ui.min.js414
-rw-r--r--lib/scripts/jquery/jquery.cookie.js41
-rw-r--r--lib/scripts/jquery/jquery.js9046
-rw-r--r--lib/scripts/jquery/jquery.min.js4
-rwxr-xr-xlib/scripts/jquery/update.sh28
-rw-r--r--lib/scripts/linkwiz.js308
-rw-r--r--lib/scripts/locktimer.js126
-rw-r--r--lib/scripts/media.js940
-rw-r--r--lib/scripts/page.js141
-rw-r--r--lib/scripts/qsearch.js146
-rw-r--r--lib/scripts/script.js63
-rw-r--r--lib/scripts/textselection.js233
-rw-r--r--lib/scripts/toolbar.js255
-rw-r--r--lib/scripts/tree.js93
-rw-r--r--lib/scripts/tw-sack.js139
-rw-r--r--lib/styles/all.css65
-rw-r--r--lib/styles/feed.css63
-rw-r--r--lib/styles/index.html12
-rw-r--r--lib/styles/print.css23
-rw-r--r--lib/styles/screen.css103
-rw-r--r--lib/tpl/default/_admin.css48
-rw-r--r--lib/tpl/default/_fileuploader.css111
-rw-r--r--lib/tpl/default/_linkwiz.css40
-rw-r--r--lib/tpl/default/_mediamanager.css432
-rw-r--r--lib/tpl/default/_mediaoptions.css18
-rw-r--r--lib/tpl/default/_subscription.css21
-rw-r--r--lib/tpl/default/_tabs.css37
-rw-r--r--lib/tpl/default/design.css851
-rw-r--r--lib/tpl/default/detail.php89
-rw-r--r--lib/tpl/default/footer.html41
-rw-r--r--lib/tpl/default/images/UWEB.pngbin0 -> 462 bytes
-rw-r--r--lib/tpl/default/images/UWEBshadow.pngbin0 -> 900 bytes
-rw-r--r--lib/tpl/default/images/apple-touch-icon.pngbin0 -> 17728 bytes
-rw-r--r--lib/tpl/default/images/bullet.gifbin0 -> 50 bytes
-rw-r--r--lib/tpl/default/images/button-cc.gifbin0 -> 359 bytes
-rw-r--r--lib/tpl/default/images/button-css.pngbin0 -> 299 bytes
-rw-r--r--lib/tpl/default/images/button-donate.gifbin0 -> 187 bytes
-rw-r--r--lib/tpl/default/images/button-dw.pngbin0 -> 404 bytes
-rw-r--r--lib/tpl/default/images/button-php.gifbin0 -> 207 bytes
-rw-r--r--lib/tpl/default/images/button-rss.pngbin0 -> 191 bytes
-rw-r--r--lib/tpl/default/images/button-xhtml.pngbin0 -> 321 bytes
-rw-r--r--lib/tpl/default/images/buttonshadow.pngbin0 -> 218 bytes
-rw-r--r--lib/tpl/default/images/closed.gifbin0 -> 54 bytes
-rw-r--r--lib/tpl/default/images/favicon.icobin0 -> 7406 bytes
-rw-r--r--lib/tpl/default/images/inputshadow.pngbin0 -> 93 bytes
-rw-r--r--lib/tpl/default/images/link_icon.gifbin0 -> 168 bytes
-rw-r--r--lib/tpl/default/images/mail_icon.gifbin0 -> 151 bytes
-rw-r--r--lib/tpl/default/images/open.gifbin0 -> 54 bytes
-rw-r--r--lib/tpl/default/images/resizecol.pngbin0 -> 225 bytes
-rw-r--r--lib/tpl/default/images/tocdot2.gifbin0 -> 50 bytes
-rw-r--r--lib/tpl/default/images/windows.gifbin0 -> 170 bytes
-rw-r--r--lib/tpl/default/layout.css79
-rw-r--r--lib/tpl/default/main.php138
-rw-r--r--lib/tpl/default/media.css213
-rw-r--r--lib/tpl/default/mediamanager.php44
-rw-r--r--lib/tpl/default/print.css228
-rw-r--r--lib/tpl/default/rtl.css154
-rw-r--r--lib/tpl/default/style.ini72
-rw-r--r--lib/tpl/index.php68
1184 files changed, 59074 insertions, 0 deletions
diff --git a/lib/exe/ajax.php b/lib/exe/ajax.php
new file mode 100644
index 000000000..3d1584244
--- /dev/null
+++ b/lib/exe/ajax.php
@@ -0,0 +1,435 @@
+<?php
+/**
+ * DokuWiki AJAX call handler
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+require_once(DOKU_INC.'inc/init.php');
+//close session
+session_write_close();
+
+header('Content-Type: text/html; charset=utf-8');
+
+
+//call the requested function
+if(isset($_POST['call'])){
+ $call = $_POST['call'];
+}else if(isset($_GET['call'])){
+ $call = $_GET['call'];
+}else{
+ exit;
+}
+$callfn = 'ajax_'.$call;
+
+if(function_exists($callfn)){
+ $callfn();
+}else{
+ $evt = new Doku_Event('AJAX_CALL_UNKNOWN', $call);
+ if ($evt->advise_before()) {
+ print "AJAX call '".htmlspecialchars($call)."' unknown!\n";
+ exit;
+ }
+ $evt->advise_after();
+ unset($evt);
+}
+
+/**
+ * Searches for matching pagenames
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function ajax_qsearch(){
+ global $conf;
+ global $lang;
+
+ $query = $_POST['q'];
+ if(empty($query)) $query = $_GET['q'];
+ if(empty($query)) return;
+
+ $query = urldecode($query);
+
+ $data = ft_pageLookup($query, true, useHeading('navigation'));
+
+ if(!count($data)) return;
+
+ print '<strong>'.$lang['quickhits'].'</strong>';
+ print '<ul>';
+ foreach($data as $id => $title){
+ if (useHeading('navigation')) {
+ $name = $title;
+ } else {
+ $ns = getNS($id);
+ if($ns){
+ $name = noNS($id).' ('.$ns.')';
+ }else{
+ $name = $id;
+ }
+ }
+ echo '<li>' . html_wikilink(':'.$id,$name) . '</li>';
+ }
+ print '</ul>';
+}
+
+/**
+ * Support OpenSearch suggestions
+ *
+ * @link http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0
+ * @author Mike Frysinger <vapier@gentoo.org>
+ */
+function ajax_suggestions() {
+ global $conf;
+ global $lang;
+
+ $query = cleanID($_POST['q']);
+ if(empty($query)) $query = cleanID($_GET['q']);
+ if(empty($query)) return;
+
+ $data = array();
+ $data = ft_pageLookup($query);
+ if(!count($data)) return;
+ $data = array_keys($data);
+
+ // limit results to 15 hits
+ $data = array_slice($data, 0, 15);
+ $data = array_map('trim',$data);
+ $data = array_map('noNS',$data);
+ $data = array_unique($data);
+ sort($data);
+
+ /* now construct a json */
+ $suggestions = array(
+ $query, // the original query
+ $data, // some suggestions
+ array(), // no description
+ array() // no urls
+ );
+ $json = new JSON();
+
+ header('Content-Type: application/x-suggestions+json');
+ print $json->encode($suggestions);
+}
+
+/**
+ * Refresh a page lock and save draft
+ *
+ * Andreas Gohr <andi@splitbrain.org>
+ */
+function ajax_lock(){
+ global $conf;
+ global $lang;
+ global $ID;
+ global $INFO;
+
+ $ID = cleanID($_POST['id']);
+ if(empty($ID)) return;
+
+ $INFO = pageinfo();
+
+ if (!$INFO['writable']) {
+ echo 'Permission denied';
+ return;
+ }
+
+ if(!checklock($ID)){
+ lock($ID);
+ echo 1;
+ }
+
+ if($conf['usedraft'] && $_POST['wikitext']){
+ $client = $_SERVER['REMOTE_USER'];
+ if(!$client) $client = clientIP(true);
+
+ $draft = array('id' => $ID,
+ 'prefix' => substr($_POST['prefix'], 0, -1),
+ 'text' => $_POST['wikitext'],
+ 'suffix' => $_POST['suffix'],
+ 'date' => (int) $_POST['date'],
+ 'client' => $client,
+ );
+ $cname = getCacheName($draft['client'].$ID,'.draft');
+ if(io_saveFile($cname,serialize($draft))){
+ echo $lang['draftdate'].' '.dformat();
+ }
+ }
+
+}
+
+/**
+ * Delete a draft
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function ajax_draftdel(){
+ $id = cleanID($_REQUEST['id']);
+ if(empty($id)) return;
+
+ $client = $_SERVER['REMOTE_USER'];
+ if(!$client) $client = clientIP(true);
+
+ $cname = getCacheName($client.$id,'.draft');
+ @unlink($cname);
+}
+
+/**
+ * Return subnamespaces for the Mediamanager
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function ajax_medians(){
+ global $conf;
+
+ // wanted namespace
+ $ns = cleanID($_POST['ns']);
+ $dir = utf8_encodeFN(str_replace(':','/',$ns));
+
+ $lvl = count(explode(':',$ns));
+
+ $data = array();
+ search($data,$conf['mediadir'],'search_index',array('nofiles' => true),$dir);
+ foreach(array_keys($data) as $item){
+ $data[$item]['level'] = $lvl+1;
+ }
+ echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li');
+}
+
+/**
+ * Return list of files for the Mediamanager
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function ajax_medialist(){
+ global $conf;
+ global $NS;
+
+ $NS = $_POST['ns'];
+ if ($_POST['do'] == 'media') {
+ tpl_mediaFileList();
+ } else {
+ tpl_mediaContent(true);
+ }
+}
+
+/**
+ * Return the content of the right column
+ * (image details) for the Mediamanager
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function ajax_mediadetails(){
+ global $DEL, $NS, $IMG, $AUTH, $JUMPTO, $REV, $lang, $fullscreen, $conf;
+ $fullscreen = true;
+ require_once(DOKU_INC.'lib/exe/mediamanager.php');
+
+ if ($_REQUEST['image']) $image = cleanID($_REQUEST['image']);
+ if (isset($IMG)) $image = $IMG;
+ if (isset($JUMPTO)) $image = $JUMPTO;
+ if (isset($REV) && !$JUMPTO) $rev = $REV;
+
+ html_msgarea();
+ tpl_mediaFileDetails($image, $rev);
+}
+
+/**
+ * Returns image diff representation for mediamanager
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function ajax_mediadiff(){
+ global $NS;
+
+ if ($_REQUEST['image']) $image = cleanID($_REQUEST['image']);
+ $NS = $_POST['ns'];
+ $auth = auth_quickaclcheck("$ns:*");
+ media_diff($image, $NS, $auth, true);
+}
+
+function ajax_mediaupload(){
+ global $NS, $MSG;
+
+ if ($_FILES['qqfile']['tmp_name']) {
+ $id = ((empty($_POST['mediaid'])) ? $_FILES['qqfile']['name'] : $_POST['mediaid']);
+ } elseif (isset($_GET['qqfile'])) {
+ $id = $_GET['qqfile'];
+ }
+
+ $id = cleanID($id);
+
+ $NS = $_REQUEST['ns'];
+ $ns = $NS.':'.getNS($id);
+
+ $AUTH = auth_quickaclcheck("$ns:*");
+ if($AUTH >= AUTH_UPLOAD) { io_createNamespace("$ns:xxx", 'media'); }
+
+ if ($_FILES['qqfile']['error']) unset($_FILES['qqfile']);
+
+ if ($_FILES['qqfile']['tmp_name']) $res = media_upload($NS, $AUTH, $_FILES['qqfile']);
+ if (isset($_GET['qqfile'])) $res = media_upload_xhr($NS, $AUTH);
+
+ if ($res) $result = array('success' => true,
+ 'link' => media_managerURL(array('ns' => $ns, 'image' => $NS.':'.$id), '&'),
+ 'id' => $NS.':'.$id, 'ns' => $NS);
+
+ if (!$result) {
+ $error = '';
+ if (isset($MSG)) {
+ foreach($MSG as $msg) $error .= $msg['msg'];
+ }
+ $result = array('error' => $msg['msg'], 'ns' => $NS);
+ }
+ $json = new JSON;
+ echo htmlspecialchars($json->encode($result), ENT_NOQUOTES);
+}
+
+function dir_delete($path) {
+ if (!is_string($path) || $path == "") return false;
+
+ if (is_dir($path) && !is_link($path)) {
+ if (!$dh = @opendir($path)) return false;
+
+ while ($f = readdir($dh)) {
+ if ($f == '..' || $f == '.') continue;
+ dir_delete("$path/$f");
+ }
+
+ closedir($dh);
+ return @rmdir($path);
+ } else {
+ return @unlink($path);
+ }
+
+ return false;
+}
+
+/**
+ * Return sub index for index view
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function ajax_index(){
+ global $conf;
+
+ // wanted namespace
+ $ns = cleanID($_POST['idx']);
+ $dir = utf8_encodeFN(str_replace(':','/',$ns));
+
+ $lvl = count(explode(':',$ns));
+
+ $data = array();
+ search($data,$conf['datadir'],'search_index',array('ns' => $ns),$dir);
+ foreach(array_keys($data) as $item){
+ $data[$item]['level'] = $lvl+1;
+ }
+ echo html_buildlist($data, 'idx', 'html_list_index', 'html_li_index');
+}
+
+/**
+ * List matching namespaces and pages for the link wizard
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+function ajax_linkwiz(){
+ global $conf;
+ global $lang;
+
+ $q = ltrim(trim($_POST['q']),':');
+ $id = noNS($q);
+ $ns = getNS($q);
+
+ $ns = cleanID($ns);
+ $id = cleanID($id);
+
+ $nsd = utf8_encodeFN(str_replace(':','/',$ns));
+ $idd = utf8_encodeFN(str_replace(':','/',$id));
+
+ $data = array();
+ if($q && !$ns){
+
+ // use index to lookup matching pages
+ $pages = array();
+ $pages = ft_pageLookup($id,true);
+
+ // result contains matches in pages and namespaces
+ // we now extract the matching namespaces to show
+ // them seperately
+ $dirs = array();
+
+ foreach($pages as $pid => $title){
+ if(strpos(noNS($pid),$id) === false){
+ // match was in the namespace
+ $dirs[getNS($pid)] = 1; // assoc array avoids dupes
+ }else{
+ // it is a matching page, add it to the result
+ $data[] = array(
+ 'id' => $pid,
+ 'title' => $title,
+ 'type' => 'f',
+ );
+ }
+ unset($pages[$pid]);
+ }
+ foreach($dirs as $dir => $junk){
+ $data[] = array(
+ 'id' => $dir,
+ 'type' => 'd',
+ );
+ }
+
+ }else{
+
+ $opts = array(
+ 'depth' => 1,
+ 'listfiles' => true,
+ 'listdirs' => true,
+ 'pagesonly' => true,
+ 'firsthead' => true,
+ 'sneakyacl' => $conf['sneaky_index'],
+ );
+ if($id) $opts['filematch'] = '^.*\/'.$id;
+ if($id) $opts['dirmatch'] = '^.*\/'.$id;
+ search($data,$conf['datadir'],'search_universal',$opts,$nsd);
+
+ // add back to upper
+ if($ns){
+ array_unshift($data,array(
+ 'id' => getNS($ns),
+ 'type' => 'u',
+ ));
+ }
+ }
+
+ // fixme sort results in a useful way ?
+
+ if(!count($data)){
+ echo $lang['nothingfound'];
+ exit;
+ }
+
+ // output the found data
+ $even = 1;
+ foreach($data as $item){
+ $even *= -1; //zebra
+
+ if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id']) $item['id'] .= ':';
+ $link = wl($item['id']);
+
+ echo '<div class="'.(($even > 0)?'even':'odd').' type_'.$item['type'].'">';
+
+ if($item['type'] == 'u'){
+ $name = $lang['upperns'];
+ }else{
+ $name = htmlspecialchars($item['id']);
+ }
+
+ echo '<a href="'.$link.'" title="'.htmlspecialchars($item['id']).'" class="wikilink1">'.$name.'</a>';
+
+ if($item['title']){
+ echo '<span>'.htmlspecialchars($item['title']).'</span>';
+ }
+ echo '</div>';
+ }
+
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/lib/exe/css.php b/lib/exe/css.php
new file mode 100644
index 000000000..69b512205
--- /dev/null
+++ b/lib/exe/css.php
@@ -0,0 +1,343 @@
+<?php
+/**
+ * DokuWiki StyleSheet creator
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching)
+if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT',1); // we gzip ourself here
+require_once(DOKU_INC.'inc/init.php');
+
+// Main (don't run when UNIT test)
+if(!defined('SIMPLE_TEST')){
+ header('Content-Type: text/css; charset=utf-8');
+ css_out();
+}
+
+
+// ---------------------- functions ------------------------------
+
+/**
+ * Output all needed Styles
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function css_out(){
+ global $conf;
+ global $lang;
+ global $config_cascade;
+
+ $mediatype = 'screen';
+ if (isset($_REQUEST['s']) &&
+ in_array($_REQUEST['s'], array('all', 'print', 'feed'))) {
+ $mediatype = $_REQUEST['s'];
+ }
+
+ $tpl = trim(preg_replace('/[^\w-]+/','',$_REQUEST['t']));
+ if($tpl){
+ $tplinc = DOKU_INC.'lib/tpl/'.$tpl.'/';
+ $tpldir = DOKU_BASE.'lib/tpl/'.$tpl.'/';
+ }else{
+ $tplinc = tpl_incdir();
+ $tpldir = tpl_basedir();
+ }
+
+ // The generated script depends on some dynamic options
+ $cache = new cache('styles'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].DOKU_BASE.$tplinc.$mediatype,'.css');
+
+ // load template styles
+ $tplstyles = array();
+ if(@file_exists($tplinc.'style.ini')){
+ $ini = parse_ini_file($tplinc.'style.ini',true);
+ foreach($ini['stylesheets'] as $file => $mode){
+ $tplstyles[$mode][$tplinc.$file] = $tpldir;
+ }
+ }
+
+ // Array of needed files and their web locations, the latter ones
+ // are needed to fix relative paths in the stylesheets
+ $files = array();
+ // load core styles
+ $files[DOKU_INC.'lib/styles/'.$mediatype.'.css'] = DOKU_BASE.'lib/styles/';
+ // load jQuery-UI theme
+ $files[DOKU_INC.'lib/scripts/jquery/jquery-ui-theme/smoothness.css'] = DOKU_BASE.'lib/scripts/jquery/jquery-ui-theme/';
+ // load plugin styles
+ $files = array_merge($files, css_pluginstyles($mediatype));
+ // load template styles
+ if (isset($tplstyles[$mediatype])) {
+ $files = array_merge($files, $tplstyles[$mediatype]);
+ }
+ // if old 'default' userstyle setting exists, make it 'screen' userstyle for backwards compatibility
+ if (isset($config_cascade['userstyle']['default'])) {
+ $config_cascade['userstyle']['screen'] = $config_cascade['userstyle']['default'];
+ }
+ // load user styles
+ if(isset($config_cascade['userstyle'][$mediatype])){
+ $files[$config_cascade['userstyle'][$mediatype]] = DOKU_BASE;
+ }
+ // load rtl styles
+ // @todo: this currently adds the rtl styles only to the 'screen' media type
+ // but 'print' and 'all' should also be supported
+ if ($mediatype=='screen') {
+ if($lang['direction'] == 'rtl'){
+ if (isset($tplstyles['rtl'])) $files = array_merge($files, $tplstyles['rtl']);
+ }
+ }
+
+ $cache_files = array_merge(array_keys($files), getConfigFiles('main'));
+ $cache_files[] = $tplinc.'style.ini';
+ $cache_files[] = __FILE__;
+
+ // check cache age & handle conditional request
+ // This may exit if a cache can be used
+ http_cached($cache->cache,
+ $cache->useCache(array('files' => $cache_files)));
+
+ // start output buffering and build the stylesheet
+ ob_start();
+
+ // print the default classes for interwiki links and file downloads
+ css_interwiki();
+ css_filetypes();
+
+ // load files
+ foreach($files as $file => $location){
+ print css_loadfile($file, $location);
+ }
+
+ // end output buffering and get contents
+ $css = ob_get_contents();
+ ob_end_clean();
+
+ // apply style replacements
+ $css = css_applystyle($css,$tplinc);
+
+ // place all @import statements at the top of the file
+ $css = css_moveimports($css);
+
+ // compress whitespace and comments
+ if($conf['compress']){
+ $css = css_compress($css);
+ }
+
+ // embed small images right into the stylesheet
+ if($conf['cssdatauri']){
+ $base = preg_quote(DOKU_BASE,'#');
+ $css = preg_replace_callback('#(url\([ \'"]*)('.$base.')(.*?(?:\.(png|gif)))#i','css_datauri',$css);
+ }
+
+ http_cached_finish($cache->cache, $css);
+}
+
+/**
+ * Does placeholder replacements in the style according to
+ * the ones defined in a templates style.ini file
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function css_applystyle($css,$tplinc){
+ if(@file_exists($tplinc.'style.ini')){
+ $ini = parse_ini_file($tplinc.'style.ini',true);
+ $css = strtr($css,$ini['replacements']);
+ }
+ return $css;
+}
+
+/**
+ * Prints classes for interwikilinks
+ *
+ * Interwiki links have two classes: 'interwiki' and 'iw_$name>' where
+ * $name is the identifier given in the config. All Interwiki links get
+ * an default style with a default icon. If a special icon is available
+ * for an interwiki URL it is set in it's own class. Both classes can be
+ * overwritten in the template or userstyles.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function css_interwiki(){
+
+ // default style
+ echo 'a.interwiki {';
+ echo ' background: transparent url('.DOKU_BASE.'lib/images/interwiki.png) 0px 1px no-repeat;';
+ echo ' padding: 1px 0px 1px 16px;';
+ echo '}';
+
+ // additional styles when icon available
+ $iwlinks = getInterwiki();
+ foreach(array_keys($iwlinks) as $iw){
+ $class = preg_replace('/[^_\-a-z0-9]+/i','_',$iw);
+ if(@file_exists(DOKU_INC.'lib/images/interwiki/'.$iw.'.png')){
+ echo "a.iw_$class {";
+ echo ' background-image: url('.DOKU_BASE.'lib/images/interwiki/'.$iw.'.png)';
+ echo '}';
+ }elseif(@file_exists(DOKU_INC.'lib/images/interwiki/'.$iw.'.gif')){
+ echo "a.iw_$class {";
+ echo ' background-image: url('.DOKU_BASE.'lib/images/interwiki/'.$iw.'.gif)';
+ echo '}';
+ }
+ }
+}
+
+/**
+ * Prints classes for file download links
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function css_filetypes(){
+
+ // default style
+ echo '.mediafile {';
+ echo ' background: transparent url('.DOKU_BASE.'lib/images/fileicons/file.png) 0px 1px no-repeat;';
+ echo ' padding-left: 18px;';
+ echo ' padding-bottom: 1px;';
+ echo '}';
+
+ // additional styles when icon available
+ // scan directory for all icons
+ $exts = array();
+ if($dh = opendir(DOKU_INC.'lib/images/fileicons')){
+ while(false !== ($file = readdir($dh))){
+ if(preg_match('/([_\-a-z0-9]+(?:\.[_\-a-z0-9]+)*?)\.(png|gif)/i',$file,$match)){
+ $ext = strtolower($match[1]);
+ $type = '.'.strtolower($match[2]);
+ if($ext!='file' && (!isset($exts[$ext]) || $type=='.png')){
+ $exts[$ext] = $type;
+ }
+ }
+ }
+ closedir($dh);
+ }
+ foreach($exts as $ext=>$type){
+ $class = preg_replace('/[^_\-a-z0-9]+/','_',$ext);
+ echo ".mf_$class {";
+ echo ' background-image: url('.DOKU_BASE.'lib/images/fileicons/'.$ext.$type.')';
+ echo '}';
+ }
+}
+
+/**
+ * Loads a given file and fixes relative URLs with the
+ * given location prefix
+ */
+function css_loadfile($file,$location=''){
+ if(!@file_exists($file)) return '';
+ $css = io_readFile($file);
+ if(!$location) return $css;
+
+ $css = preg_replace('#(url\([ \'"]*)(?!/|data:|http://|https://| |\'|")#','\\1'.$location,$css);
+ $css = preg_replace('#(@import\s+[\'"])(?!/|data:|http://|https://)#', '\\1'.$location, $css);
+
+ return $css;
+}
+
+/**
+ * Converte local image URLs to data URLs if the filesize is small
+ *
+ * Callback for preg_replace_callback
+ */
+function css_datauri($match){
+ global $conf;
+
+ $pre = unslash($match[1]);
+ $base = unslash($match[2]);
+ $url = unslash($match[3]);
+ $ext = unslash($match[4]);
+
+ $local = DOKU_INC.$url;
+ $size = @filesize($local);
+ if($size && $size < $conf['cssdatauri']){
+ $data = base64_encode(file_get_contents($local));
+ }
+ if($data){
+ $url = 'data:image/'.$ext.';base64,'.$data;
+ }else{
+ $url = $base.$url;
+ }
+ return $pre.$url;
+}
+
+
+/**
+ * Returns a list of possible Plugin Styles (no existance check here)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function css_pluginstyles($mediatype='screen'){
+ global $lang;
+ $list = array();
+ $plugins = plugin_list();
+ foreach ($plugins as $p){
+ $list[DOKU_PLUGIN."$p/$mediatype.css"] = DOKU_BASE."lib/plugins/$p/";
+ // alternative for screen.css
+ if ($mediatype=='screen') {
+ $list[DOKU_PLUGIN."$p/style.css"] = DOKU_BASE."lib/plugins/$p/";
+ }
+ if($lang['direction'] == 'rtl'){
+ $list[DOKU_PLUGIN."$p/rtl.css"] = DOKU_BASE."lib/plugins/$p/";
+ }
+ }
+ return $list;
+}
+
+/**
+ * Move all @import statements in a combined stylesheet to the top so they
+ * aren't ignored by the browser.
+ *
+ * @author Gabriel Birke <birke@d-scribe.de>
+ */
+function css_moveimports($css)
+{
+ if(!preg_match_all('/@import\s+(?:url\([^)]+\)|"[^"]+")\s*[^;]*;\s*/', $css, $matches, PREG_OFFSET_CAPTURE)) {
+ return $css;
+ }
+ $newCss = "";
+ $imports = "";
+ $offset = 0;
+ foreach($matches[0] as $match) {
+ $newCss .= substr($css, $offset, $match[1] - $offset);
+ $imports .= $match[0];
+ $offset = $match[1] + strlen($match[0]);
+ }
+ $newCss .= substr($css, $offset);
+ return $imports.$newCss;
+}
+
+/**
+ * Very simple CSS optimizer
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function css_compress($css){
+ //strip comments through a callback
+ $css = preg_replace_callback('#(/\*)(.*?)(\*/)#s','css_comment_cb',$css);
+
+ //strip (incorrect but common) one line comments
+ $css = preg_replace('/(?<!:)\/\/.*$/m','',$css);
+
+ // strip whitespaces
+ $css = preg_replace('![\r\n\t ]+!',' ',$css);
+ $css = preg_replace('/ ?([;,{}\/]) ?/','\\1',$css);
+ $css = preg_replace('/ ?: /',':',$css);
+
+ // shorten colors
+ $css = preg_replace("/#([0-9a-fA-F]{1})\\1([0-9a-fA-F]{1})\\2([0-9a-fA-F]{1})\\3/", "#\\1\\2\\3",$css);
+
+ return $css;
+}
+
+/**
+ * Callback for css_compress()
+ *
+ * Keeps short comments (< 5 chars) to maintain typical browser hacks
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function css_comment_cb($matches){
+ if(strlen($matches[2]) > 4) return '';
+ return $matches[0];
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/exe/detail.php b/lib/exe/detail.php
new file mode 100644
index 000000000..35186f5dd
--- /dev/null
+++ b/lib/exe/detail.php
@@ -0,0 +1,48 @@
+<?php
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+define('DOKU_MEDIADETAIL',1);
+require_once(DOKU_INC.'inc/init.php');
+//close session
+session_write_close();
+
+$IMG = getID('media');
+$ID = cleanID($_REQUEST['id']);
+
+if($conf['allowdebug'] && $_REQUEST['debug']){
+ print '<pre>';
+ foreach(explode(' ','basedir userewrite baseurl useslash') as $x){
+ print '$'."conf['$x'] = '".$conf[$x]."';\n";
+ }
+ foreach(explode(' ','DOCUMENT_ROOT HTTP_HOST SCRIPT_FILENAME PHP_SELF '.
+ 'REQUEST_URI SCRIPT_NAME PATH_INFO PATH_TRANSLATED') as $x){
+ print '$'."_SERVER['$x'] = '".$_SERVER[$x]."';\n";
+ }
+ print "getID('media'): ".getID('media')."\n";
+ print "getID('media',false): ".getID('media',false)."\n";
+ print '</pre>';
+}
+
+$ERROR = false;
+// check image permissions
+$AUTH = auth_quickaclcheck($IMG);
+if($AUTH >= AUTH_READ){
+ // check if image exists
+ $SRC = mediaFN($IMG);
+ if(!@file_exists($SRC)){
+ //doesn't exist!
+ header("HTTP/1.0 404 File not Found");
+ $ERROR = 'File not found';
+ }
+}else{
+ // no auth
+ $ERROR = p_locale_xhtml('denied');
+}
+
+// this makes some general infos available as well as the info about the
+// "parent" page
+$INFO = pageinfo();
+
+//start output and load template
+header('Content-Type: text/html; charset=utf-8');
+include(template('detail.php'));
+
diff --git a/lib/exe/fetch.php b/lib/exe/fetch.php
new file mode 100644
index 000000000..143d40f22
--- /dev/null
+++ b/lib/exe/fetch.php
@@ -0,0 +1,205 @@
+<?php
+/**
+ * DokuWiki media passthrough file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+ if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+ define('DOKU_DISABLE_GZIP_OUTPUT', 1);
+ require_once(DOKU_INC.'inc/init.php');
+
+ //close session
+ session_write_close();
+
+ $mimetypes = getMimeTypes();
+
+ //get input
+ $MEDIA = stripctl(getID('media',false)); // no cleaning except control chars - maybe external
+ $CACHE = calc_cache($_REQUEST['cache']);
+ $WIDTH = (int) $_REQUEST['w'];
+ $HEIGHT = (int) $_REQUEST['h'];
+ $REV = (int) @$_REQUEST['rev'];
+ //sanitize revision
+ $REV = preg_replace('/[^0-9]/','',$REV);
+
+ list($EXT,$MIME,$DL) = mimetype($MEDIA,false);
+ if($EXT === false){
+ $EXT = 'unknown';
+ $MIME = 'application/octet-stream';
+ $DL = true;
+ }
+
+ // check for permissions, preconditions and cache external files
+ list($STATUS, $STATUSMESSAGE) = checkFileStatus($MEDIA, $FILE, $REV);
+
+ // prepare data for plugin events
+ $data = array('media' => $MEDIA,
+ 'file' => $FILE,
+ 'orig' => $FILE,
+ 'mime' => $MIME,
+ 'download' => $DL,
+ 'cache' => $CACHE,
+ 'ext' => $EXT,
+ 'width' => $WIDTH,
+ 'height' => $HEIGHT,
+ 'status' => $STATUS,
+ 'statusmessage' => $STATUSMESSAGE,
+ );
+
+ // handle the file status
+ $evt = new Doku_Event('FETCH_MEDIA_STATUS', $data);
+ if ( $evt->advise_before() ) {
+ // redirects
+ if($data['status'] > 300 && $data['status'] <= 304){
+ send_redirect($data['statusmessage']);
+ }
+ // send any non 200 status
+ if($data['status'] != 200){
+ header('HTTP/1.0 ' . $data['status'] . ' ' . $data['statusmessage']);
+ }
+ // die on errors
+ if($data['status'] > 203){
+ print $data['statusmessage'];
+ exit;
+ }
+ }
+ $evt->advise_after();
+ unset($evt);
+
+ //handle image resizing/cropping
+ if((substr($MIME,0,5) == 'image') && $WIDTH){
+ if($HEIGHT){
+ $data['file'] = $FILE = media_crop_image($data['file'],$EXT,$WIDTH,$HEIGHT);
+ }else{
+ $data['file'] = $FILE = media_resize_image($data['file'],$EXT,$WIDTH,$HEIGHT);
+ }
+ }
+
+ // finally send the file to the client
+ $evt = new Doku_Event('MEDIA_SENDFILE', $data);
+ if ($evt->advise_before()) {
+ sendFile($data['file'],$data['mime'],$data['download'],$data['cache']);
+ }
+ // Do something after the download finished.
+ $evt->advise_after();
+
+/* ------------------------------------------------------------------------ */
+
+/**
+ * Set headers and send the file to the client
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function sendFile($file,$mime,$dl,$cache){
+ global $conf;
+ $fmtime = @filemtime($file);
+ // send headers
+ header("Content-Type: $mime");
+ // smart http caching headers
+ if ($cache==-1) {
+ // cache
+ // cachetime or one hour
+ header('Expires: '.gmdate("D, d M Y H:i:s", time()+max($conf['cachetime'], 3600)).' GMT');
+ header('Cache-Control: public, proxy-revalidate, no-transform, max-age='.max($conf['cachetime'], 3600));
+ header('Pragma: public');
+ } else if ($cache>0) {
+ // recache
+ // remaining cachetime + 10 seconds so the newly recached media is used
+ header('Expires: '.gmdate("D, d M Y H:i:s", $fmtime+$conf['cachetime']+10).' GMT');
+ header('Cache-Control: public, proxy-revalidate, no-transform, max-age='.max($fmtime-time()+$conf['cachetime']+10, 0));
+ header('Pragma: public');
+ } else if ($cache==0) {
+ // nocache
+ header('Cache-Control: must-revalidate, no-transform, post-check=0, pre-check=0');
+ header('Pragma: public');
+ }
+ //send important headers first, script stops here if '304 Not Modified' response
+ http_conditionalRequest($fmtime);
+
+
+ //download or display?
+ if($dl){
+ header('Content-Disposition: attachment; filename="'.basename($file).'";');
+ }else{
+ header('Content-Disposition: inline; filename="'.basename($file).'";');
+ }
+
+ //use x-sendfile header to pass the delivery to compatible webservers
+ if (http_sendfile($file)) exit;
+
+ // send file contents
+ $fp = @fopen($file,"rb");
+ if($fp){
+ http_rangeRequest($fp,filesize($file),$mime);
+ }else{
+ header("HTTP/1.0 500 Internal Server Error");
+ print "Could not read $file - bad permissions?";
+ }
+}
+
+/**
+ * Check for media for preconditions and return correct status code
+ *
+ * READ: MEDIA, MIME, EXT, CACHE
+ * WRITE: MEDIA, FILE, array( STATUS, STATUSMESSAGE )
+ *
+ * @author Gerry Weissbach <gerry.w@gammaproduction.de>
+ * @param $media reference to the media id
+ * @param $file reference to the file variable
+ * @returns array(STATUS, STATUSMESSAGE)
+ */
+function checkFileStatus(&$media, &$file, $rev='') {
+ global $MIME, $EXT, $CACHE;
+
+ //media to local file
+ if(preg_match('#^(https?)://#i',$media)){
+ //check hash
+ if(substr(md5(auth_cookiesalt().$media),0,6) != $_REQUEST['hash']){
+ return array( 412, 'Precondition Failed');
+ }
+ //handle external images
+ if(strncmp($MIME,'image/',6) == 0) $file = media_get_from_URL($media,$EXT,$CACHE);
+ if(!$file){
+ //download failed - redirect to original URL
+ return array( 302, $media );
+ }
+ }else{
+ $media = cleanID($media);
+ if(empty($media)){
+ return array( 400, 'Bad request' );
+ }
+
+ //check permissions (namespace only)
+ if(auth_quickaclcheck(getNS($media).':X') < AUTH_READ){
+ return array( 403, 'Forbidden' );
+ }
+ $file = mediaFN($media, $rev);
+ }
+
+ //check file existance
+ if(!@file_exists($file)){
+ return array( 404, 'Not Found' );
+ }
+
+ return array(200, null);
+}
+
+/**
+ * Returns the wanted cachetime in seconds
+ *
+ * Resolves named constants
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function calc_cache($cache){
+ global $conf;
+
+ if(strtolower($cache) == 'nocache') return 0; //never cache
+ if(strtolower($cache) == 'recache') return $conf['cachetime']; //use standard cache
+ return -1; //cache endless
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/lib/exe/index.html b/lib/exe/index.html
new file mode 100644
index 000000000..d614603ac
--- /dev/null
+++ b/lib/exe/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="refresh" content="0; URL=../../" />
+<meta name="robots" content="noindex" />
+<title>nothing here...</title>
+</head>
+<body>
+<!-- this is just here to prevent directory browsing -->
+</body>
+</html>
diff --git a/lib/exe/indexer.php b/lib/exe/indexer.php
new file mode 100644
index 000000000..95e2af05b
--- /dev/null
+++ b/lib/exe/indexer.php
@@ -0,0 +1,271 @@
+<?php
+/**
+ * DokuWiki indexer
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+define('DOKU_DISABLE_GZIP_OUTPUT',1);
+require_once(DOKU_INC.'inc/init.php');
+session_write_close(); //close session
+if(!defined('NL')) define('NL',"\n");
+
+// keep running after browser closes connection
+@ignore_user_abort(true);
+
+// check if user abort worked, if yes send output early
+$defer = !@ignore_user_abort() || $conf['broken_iua'];
+if(!$defer){
+ sendGIF(); // send gif
+}
+
+$ID = cleanID($_REQUEST['id']);
+
+// Catch any possible output (e.g. errors)
+$output = isset($_REQUEST['debug']) && $conf['allowdebug'];
+if(!$output) ob_start();
+
+// run one of the jobs
+$tmp = array(); // No event data
+$evt = new Doku_Event('INDEXER_TASKS_RUN', $tmp);
+if ($evt->advise_before()) {
+ runIndexer() or
+ runSitemapper() or
+ sendDigest() or
+ runTrimRecentChanges() or
+ runTrimRecentChanges(true) or
+ $evt->advise_after();
+}
+if($defer) sendGIF();
+
+if(!$output) ob_end_clean();
+exit;
+
+// --------------------------------------------------------------------
+
+/**
+ * Trims the recent changes cache (or imports the old changelog) as needed.
+ *
+ * @param media_changes If the media changelog shall be trimmed instead of
+ * the page changelog
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function runTrimRecentChanges($media_changes = false) {
+ global $conf;
+
+ $fn = ($media_changes ? $conf['media_changelog'] : $conf['changelog']);
+
+ // Trim the Recent Changes
+ // Trims the recent changes cache to the last $conf['changes_days'] recent
+ // changes or $conf['recent'] items, which ever is larger.
+ // The trimming is only done once a day.
+ if (@file_exists($fn) &&
+ (@filemtime($fn.'.trimmed')+86400)<time() &&
+ !@file_exists($fn.'_tmp')) {
+ @touch($fn.'.trimmed');
+ io_lock($fn);
+ $lines = file($fn);
+ if (count($lines)<=$conf['recent']) {
+ // nothing to trim
+ io_unlock($fn);
+ return false;
+ }
+
+ io_saveFile($fn.'_tmp', ''); // presave tmp as 2nd lock
+ $trim_time = time() - $conf['recent_days']*86400;
+ $out_lines = array();
+
+ for ($i=0; $i<count($lines); $i++) {
+ $log = parseChangelogLine($lines[$i]);
+ if ($log === false) continue; // discard junk
+ if ($log['date'] < $trim_time) {
+ $old_lines[$log['date'].".$i"] = $lines[$i]; // keep old lines for now (append .$i to prevent key collisions)
+ } else {
+ $out_lines[$log['date'].".$i"] = $lines[$i]; // definitely keep these lines
+ }
+ }
+
+ if (count($lines)==count($out_lines)) {
+ // nothing to trim
+ @unlink($fn.'_tmp');
+ io_unlock($fn);
+ return false;
+ }
+
+ // sort the final result, it shouldn't be necessary,
+ // however the extra robustness in making the changelog cache self-correcting is worth it
+ ksort($out_lines);
+ $extra = $conf['recent'] - count($out_lines); // do we need extra lines do bring us up to minimum
+ if ($extra > 0) {
+ ksort($old_lines);
+ $out_lines = array_merge(array_slice($old_lines,-$extra),$out_lines);
+ }
+
+ // save trimmed changelog
+ io_saveFile($fn.'_tmp', implode('', $out_lines));
+ @unlink($fn);
+ if (!rename($fn.'_tmp', $fn)) {
+ // rename failed so try another way...
+ io_unlock($fn);
+ io_saveFile($fn, implode('', $out_lines));
+ @unlink($fn.'_tmp');
+ } else {
+ io_unlock($fn);
+ }
+ return true;
+ }
+
+ // nothing done
+ return false;
+}
+
+/**
+ * Runs the indexer for the current page
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function runIndexer(){
+ global $ID;
+ global $conf;
+ print "runIndexer(): started".NL;
+
+ if(!$ID) return false;
+
+ // do the work
+ return idx_addPage($ID, true);
+}
+
+/**
+ * Builds a Google Sitemap of all public pages known to the indexer
+ *
+ * The map is placed in the root directory named sitemap.xml.gz - This
+ * file needs to be writable!
+ *
+ * @author Andreas Gohr
+ * @link https://www.google.com/webmasters/sitemaps/docs/en/about.html
+ */
+function runSitemapper(){
+ print "runSitemapper(): started".NL;
+ $result = Sitemapper::generate() && Sitemapper::pingSearchEngines();
+ print 'runSitemapper(): finished'.NL;
+ return $result;
+}
+
+/**
+ * Send digest and list mails for all subscriptions which are in effect for the
+ * current page
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function sendDigest() {
+ echo 'sendDigest(): start'.NL;
+ global $ID;
+ global $conf;
+ if (!$conf['subscribers']) {
+ return;
+ }
+ $subscriptions = subscription_find($ID, array('style' => '(digest|list)',
+ 'escaped' => true));
+ global $auth;
+ global $lang;
+ global $conf;
+ global $USERINFO;
+
+ // remember current user info
+ $olduinfo = $USERINFO;
+ $olduser = $_SERVER['REMOTE_USER'];
+
+ foreach($subscriptions as $id => $users) {
+ if (!subscription_lock($id)) {
+ continue;
+ }
+ foreach($users as $data) {
+ list($user, $style, $lastupdate) = $data;
+ $lastupdate = (int) $lastupdate;
+ if ($lastupdate + $conf['subscribe_time'] > time()) {
+ // Less than the configured time period passed since last
+ // update.
+ continue;
+ }
+
+ // Work as the user to make sure ACLs apply correctly
+ $USERINFO = $auth->getUserData($user);
+ $_SERVER['REMOTE_USER'] = $user;
+ if ($USERINFO === false) {
+ continue;
+ }
+
+ if (substr($id, -1, 1) === ':') {
+ // The subscription target is a namespace
+ $changes = getRecentsSince($lastupdate, null, getNS($id));
+ } else {
+ if(auth_quickaclcheck($id) < AUTH_READ) continue;
+
+ $meta = p_get_metadata($id);
+ $changes = array($meta['last_change']);
+ }
+
+ // Filter out pages only changed in small and own edits
+ $change_ids = array();
+ foreach($changes as $rev) {
+ $n = 0;
+ while (!is_null($rev) && $rev['date'] >= $lastupdate &&
+ ($_SERVER['REMOTE_USER'] === $rev['user'] ||
+ $rev['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT)) {
+ $rev = getRevisions($rev['id'], $n++, 1);
+ $rev = (count($rev) > 0) ? $rev[0] : null;
+ }
+
+ if (!is_null($rev) && $rev['date'] >= $lastupdate) {
+ // Some change was not a minor one and not by myself
+ $change_ids[] = $rev['id'];
+ }
+ }
+
+ if ($style === 'digest') {
+ foreach($change_ids as $change_id) {
+ subscription_send_digest($USERINFO['mail'], $change_id,
+ $lastupdate);
+ }
+ } elseif ($style === 'list') {
+ subscription_send_list($USERINFO['mail'], $change_ids, $id);
+ }
+ // TODO: Handle duplicate subscriptions.
+
+ // Update notification time.
+ subscription_set($user, $id, $style, time(), true);
+ }
+ subscription_unlock($id);
+ }
+
+ // restore current user info
+ $USERINFO = $olduinfo;
+ $_SERVER['REMOTE_USER'] = $olduser;
+}
+
+/**
+ * Just send a 1x1 pixel blank gif to the browser
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Harry Fuecks <fuecks@gmail.com>
+ */
+function sendGIF(){
+ if(isset($_REQUEST['debug'])){
+ header('Content-Type: text/plain');
+ return;
+ }
+ $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
+ header('Content-Type: image/gif');
+ header('Content-Length: '.strlen($img));
+ header('Connection: Close');
+ print $img;
+ flush();
+ // Browser should drop connection after this
+ // Thinks it's got the whole image
+}
+
+//Setup VIM: ex: et ts=4 :
+// No trailing PHP closing tag - no output please!
+// See Note at http://www.php.net/manual/en/language.basic-syntax.instruction-separation.php
diff --git a/lib/exe/js.php b/lib/exe/js.php
new file mode 100644
index 000000000..963eebd5f
--- /dev/null
+++ b/lib/exe/js.php
@@ -0,0 +1,358 @@
+<?php
+/**
+ * DokuWiki JavaScript creator
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching)
+if(!defined('NL')) define('NL',"\n");
+if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT',1); // we gzip ourself here
+require_once(DOKU_INC.'inc/init.php');
+
+// Main (don't run when UNIT test)
+if(!defined('SIMPLE_TEST')){
+ header('Content-Type: text/javascript; charset=utf-8');
+ js_out();
+}
+
+
+// ---------------------- functions ------------------------------
+
+/**
+ * Output all needed JavaScript
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function js_out(){
+ global $conf;
+ global $lang;
+ global $config_cascade;
+
+ // The generated script depends on some dynamic options
+ $cache = new cache('scripts'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'],
+ '.js');
+
+ // load minified version for some files
+ $min = $conf['compress'] ? '.min' : '';
+
+ // array of core files
+ $files = array(
+ DOKU_INC."lib/scripts/jquery/jquery$min.js",
+ DOKU_INC.'lib/scripts/jquery/jquery.cookie.js',
+ DOKU_INC."lib/scripts/jquery/jquery-ui$min.js",
+ DOKU_INC."lib/scripts/fileuploader.js",
+ DOKU_INC."lib/scripts/fileuploaderextended.js",
+ DOKU_INC.'lib/scripts/helpers.js',
+ DOKU_INC.'lib/scripts/delay.js',
+ DOKU_INC.'lib/scripts/cookie.js',
+ DOKU_INC.'lib/scripts/script.js',
+ DOKU_INC.'lib/scripts/tw-sack.js',
+ DOKU_INC.'lib/scripts/qsearch.js',
+ DOKU_INC.'lib/scripts/tree.js',
+ DOKU_INC.'lib/scripts/index.js',
+ DOKU_INC.'lib/scripts/drag.js',
+ DOKU_INC.'lib/scripts/textselection.js',
+ DOKU_INC.'lib/scripts/toolbar.js',
+ DOKU_INC.'lib/scripts/edit.js',
+ DOKU_INC.'lib/scripts/editor.js',
+ DOKU_INC.'lib/scripts/locktimer.js',
+ DOKU_INC.'lib/scripts/linkwiz.js',
+ DOKU_INC.'lib/scripts/media.js',
+ DOKU_INC.'lib/scripts/compatibility.js',
+# disabled for FS#1958 DOKU_INC.'lib/scripts/hotkeys.js',
+ DOKU_INC.'lib/scripts/behaviour.js',
+ DOKU_INC.'lib/scripts/page.js',
+ tpl_incdir().'script.js',
+ );
+
+ // add possible plugin scripts and userscript
+ $files = array_merge($files,js_pluginscripts());
+ if(isset($config_cascade['userscript']['default'])){
+ $files[] = $config_cascade['userscript']['default'];
+ }
+
+ $cache_files = array_merge($files, getConfigFiles('main'));
+ $cache_files[] = __FILE__;
+
+ // check cache age & handle conditional request
+ // This may exit if a cache can be used
+ http_cached($cache->cache,
+ $cache->useCache(array('files' => $cache_files)));
+
+ // start output buffering and build the script
+ ob_start();
+
+ // add some global variables
+ print "var DOKU_BASE = '".DOKU_BASE."';";
+ print "var DOKU_TPL = '".tpl_basedir()."';";
+ // FIXME: Move those to JSINFO
+ print "var DOKU_UHN = ".((int) useHeading('navigation')).";";
+ print "var DOKU_UHC = ".((int) useHeading('content')).";";
+
+ // load JS specific translations
+ $json = new JSON();
+ $lang['js']['plugins'] = js_pluginstrings();
+ echo 'LANG = '.$json->encode($lang['js']).";\n";
+
+ // load toolbar
+ toolbar_JSdefines('toolbar');
+
+ // load files
+ foreach($files as $file){
+ echo "\n\n/* XXXXXXXXXX begin of ".str_replace(DOKU_INC, '', $file) ." XXXXXXXXXX */\n\n";
+ js_load($file);
+ echo "\n\n/* XXXXXXXXXX end of " . str_replace(DOKU_INC, '', $file) . " XXXXXXXXXX */\n\n";
+ }
+
+ // init stuff
+ if($conf['locktime'] != 0){
+ js_runonstart("dw_locktimer.init(".($conf['locktime'] - 60).",".$conf['usedraft'].")");
+ }
+ // init hotkeys - must have been done after init of toolbar
+# disabled for FS#1958 js_runonstart('initializeHotkeys()');
+
+ // end output buffering and get contents
+ $js = ob_get_contents();
+ ob_end_clean();
+
+ // compress whitespace and comments
+ if($conf['compress']){
+ $js = js_compress($js);
+ }
+
+ $js .= "\n"; // https://bugzilla.mozilla.org/show_bug.cgi?id=316033
+
+ http_cached_finish($cache->cache, $js);
+}
+
+/**
+ * Load the given file, handle include calls and print it
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function js_load($file){
+ if(!@file_exists($file)) return;
+ static $loaded = array();
+
+ $data = io_readFile($file);
+ while(preg_match('#/\*\s*DOKUWIKI:include(_once)?\s+([\w\.\-_/]+)\s*\*/#',$data,$match)){
+ $ifile = $match[2];
+
+ // is it a include_once?
+ if($match[1]){
+ $base = basename($ifile);
+ if($loaded[$base]) continue;
+ $loaded[$base] = true;
+ }
+
+ if($ifile{0} != '/') $ifile = dirname($file).'/'.$ifile;
+
+ if(@file_exists($ifile)){
+ $idata = io_readFile($ifile);
+ }else{
+ $idata = '';
+ }
+ $data = str_replace($match[0],$idata,$data);
+ }
+ echo "$data\n";
+}
+
+/**
+ * Returns a list of possible Plugin Scripts (no existance check here)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function js_pluginscripts(){
+ $list = array();
+ $plugins = plugin_list();
+ foreach ($plugins as $p){
+ $list[] = DOKU_PLUGIN."$p/script.js";
+ }
+ return $list;
+}
+
+/**
+ * Return an two-dimensional array with strings from the language file of each plugin.
+ *
+ * - $lang['js'] must be an array.
+ * - Nothing is returned for plugins without an entry for $lang['js']
+ *
+ * @author Gabriel Birke <birke@d-scribe.de>
+ */
+function js_pluginstrings()
+{
+ global $conf;
+ $pluginstrings = array();
+ $plugins = plugin_list();
+ foreach ($plugins as $p){
+ if (isset($lang)) unset($lang);
+ if (@file_exists(DOKU_PLUGIN."$p/lang/en/lang.php")) {
+ include DOKU_PLUGIN."$p/lang/en/lang.php";
+ }
+ if (isset($conf['lang']) && $conf['lang']!='en' && @file_exists(DOKU_PLUGIN."$p/lang/".$conf['lang']."/lang.php")) {
+ include DOKU_PLUGIN."$p/lang/".$conf['lang']."/lang.php";
+ }
+ if (isset($lang['js'])) {
+ $pluginstrings[$p] = $lang['js'];
+ }
+ }
+ return $pluginstrings;
+}
+
+/**
+ * Escapes a String to be embedded in a JavaScript call, keeps \n
+ * as newline
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function js_escape($string){
+ return str_replace('\\\\n','\\n',addslashes($string));
+}
+
+/**
+ * Adds the given JavaScript code to the window.onload() event
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function js_runonstart($func){
+ echo "jQuery(function(){ $func; });".NL;
+}
+
+/**
+ * Strip comments and whitespaces from given JavaScript Code
+ *
+ * This is a port of Nick Galbreath's python tool jsstrip.py which is
+ * released under BSD license. See link for original code.
+ *
+ * @author Nick Galbreath <nickg@modp.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @link http://code.google.com/p/jsstrip/
+ */
+function js_compress($s){
+ $s = ltrim($s); // strip all initial whitespace
+ $s .= "\n";
+ $i = 0; // char index for input string
+ $j = 0; // char forward index for input string
+ $line = 0; // line number of file (close to it anyways)
+ $slen = strlen($s); // size of input string
+ $lch = ''; // last char added
+ $result = ''; // we store the final result here
+
+ // items that don't need spaces next to them
+ $chars = "^&|!+\-*\/%=\?:;,{}()<>% \t\n\r'\"[]";
+
+ $regex_starters = array("(", "=", "[", "," , ":", "!");
+
+ $whitespaces_chars = array(" ", "\t", "\n", "\r", "\0", "\x0B");
+
+ while($i < $slen){
+ // skip all "boring" characters. This is either
+ // reserved word (e.g. "for", "else", "if") or a
+ // variable/object/method (e.g. "foo.color")
+ while ($i < $slen && (strpos($chars,$s[$i]) === false) ){
+ $result .= $s{$i};
+ $i = $i + 1;
+ }
+
+ $ch = $s{$i};
+ // multiline comments (keeping IE conditionals)
+ if($ch == '/' && $s{$i+1} == '*' && $s{$i+2} != '@'){
+ $endC = strpos($s,'*/',$i+2);
+ if($endC === false) trigger_error('Found invalid /*..*/ comment', E_USER_ERROR);
+ $i = $endC + 2;
+ continue;
+ }
+
+ // singleline
+ if($ch == '/' && $s{$i+1} == '/'){
+ $endC = strpos($s,"\n",$i+2);
+ if($endC === false) trigger_error('Invalid comment', E_USER_ERROR);
+ $i = $endC;
+ continue;
+ }
+
+ // tricky. might be an RE
+ if($ch == '/'){
+ // rewind, skip white space
+ $j = 1;
+ while(in_array($s{$i-$j}, $whitespaces_chars)){
+ $j = $j + 1;
+ }
+ if( in_array($s{$i-$j}, $regex_starters) ){
+ // yes, this is an re
+ // now move forward and find the end of it
+ $j = 1;
+ while($s{$i+$j} != '/'){
+ while( ($s{$i+$j} != '\\') && ($s{$i+$j} != '/')){
+ $j = $j + 1;
+ }
+ if($s{$i+$j} == '\\') $j = $j + 2;
+ }
+ $result .= substr($s,$i,$j+1);
+ $i = $i + $j + 1;
+ continue;
+ }
+ }
+
+ // double quote strings
+ if($ch == '"'){
+ $j = 1;
+ while( $s{$i+$j} != '"' && ($i+$j < $slen)){
+ if( $s{$i+$j} == '\\' && ($s{$i+$j+1} == '"' || $s{$i+$j+1} == '\\') ){
+ $j += 2;
+ }else{
+ $j += 1;
+ }
+ }
+ $result .= substr($s,$i,$j+1);
+ $i = $i + $j + 1;
+ continue;
+ }
+
+ // single quote strings
+ if($ch == "'"){
+ $j = 1;
+ while( $s{$i+$j} != "'" && ($i+$j < $slen)){
+ if( $s{$i+$j} == '\\' && ($s{$i+$j+1} == "'" || $s{$i+$j+1} == '\\') ){
+ $j += 2;
+ }else{
+ $j += 1;
+ }
+ }
+ $result .= substr($s,$i,$j+1);
+ $i = $i + $j + 1;
+ continue;
+ }
+
+ // whitespaces
+ if( $ch == ' ' || $ch == "\r" || $ch == "\n" || $ch == "\t" ){
+ // leading spaces
+ if($i+1 < $slen && (strpos($chars,$s[$i+1]) !== false)){
+ $i = $i + 1;
+ continue;
+ }
+ // trailing spaces
+ // if this ch is space AND the last char processed
+ // is special, then skip the space
+ $lch = substr($result,-1);
+ if($lch && (strpos($chars,$lch) !== false)){
+ $i = $i + 1;
+ continue;
+ }
+ // else after all of this convert the "whitespace" to
+ // a single space. It will get appended below
+ $ch = ' ';
+ }
+
+ // other chars
+ $result .= $ch;
+ $i = $i + 1;
+ }
+
+ return trim($result);
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/exe/mediamanager.php b/lib/exe/mediamanager.php
new file mode 100644
index 000000000..5f09fe1f8
--- /dev/null
+++ b/lib/exe/mediamanager.php
@@ -0,0 +1,122 @@
+<?php
+ if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+ define('DOKU_MEDIAMANAGER',1);
+
+ // for multi uploader:
+ @ini_set('session.use_only_cookies',0);
+
+ require_once(DOKU_INC.'inc/init.php');
+
+ trigger_event('MEDIAMANAGER_STARTED',$tmp=array());
+ session_write_close(); //close session
+
+ // handle passed message
+ if($_REQUEST['msg1']) msg(hsc($_REQUEST['msg1']),1);
+ if($_REQUEST['err']) msg(hsc($_REQUEST['err']),-1);
+
+
+ // get namespace to display (either direct or from deletion order)
+ if($_REQUEST['delete']){
+ $DEL = cleanID($_REQUEST['delete']);
+ $IMG = $DEL;
+ $NS = getNS($DEL);
+ }elseif($_REQUEST['edit']){
+ $IMG = cleanID($_REQUEST['edit']);
+ $NS = getNS($IMG);
+ }elseif($_REQUEST['img']){
+ $IMG = cleanID($_REQUEST['img']);
+ $NS = getNS($IMG);
+ }else{
+ $NS = $_REQUEST['ns'];
+ $NS = cleanID($NS);
+ }
+
+ // check auth
+ $AUTH = auth_quickaclcheck("$NS:*");
+
+ // do not display the manager if user does not have read access
+ if($AUTH < AUTH_READ && !$fullscreen) {
+ header('HTTP/1.0 403 Forbidden');
+ die($lang['accessdenied']);
+ }
+
+ // create the given namespace (just for beautification)
+ if($AUTH >= AUTH_UPLOAD) { io_createNamespace("$NS:xxx", 'media'); }
+
+ // handle flash upload
+ if(isset($_FILES['Filedata'])){
+ $_FILES['upload'] =& $_FILES['Filedata'];
+ $JUMPTO = media_upload($NS,$AUTH);
+ if($JUMPTO == false){
+ header("HTTP/1.0 400 Bad Request");
+ echo 'Upload failed';
+ }
+ echo 'ok';
+ exit;
+ }
+
+ // give info on PHP catched upload errors
+ if($_FILES['upload']['error']){
+ switch($_FILES['upload']['error']){
+ case 1:
+ case 2:
+ msg(sprintf($lang['uploadsize'],
+ filesize_h(php_to_byte(ini_get('upload_max_filesize')))),-1);
+ break;
+ default:
+ msg($lang['uploadfail'].' ('.$_FILES['upload']['error'].')',-1);
+ }
+ unset($_FILES['upload']);
+ }
+
+ // handle upload
+ if($_FILES['upload']['tmp_name']){
+ $JUMPTO = media_upload($NS,$AUTH);
+ if($JUMPTO) $NS = getNS($JUMPTO);
+ }
+
+ // handle meta saving
+ if($IMG && @array_key_exists('save', $_REQUEST['do'])){
+ $JUMPTO = media_metasave($IMG,$AUTH,$_REQUEST['meta']);
+ }
+
+ if($IMG && ($_REQUEST['mediado'] == 'save' || @array_key_exists('save', $_REQUEST['mediado']))) {
+ $JUMPTO = media_metasave($IMG,$AUTH,$_REQUEST['meta']);
+ }
+
+ if ($_REQUEST['rev'] && $conf['mediarevisions']) $REV = (int) $_REQUEST['rev'];
+
+ if($_REQUEST['mediado'] == 'restore' && $conf['mediarevisions']){
+ $JUMPTO = media_restore($_REQUEST['image'], $REV, $AUTH);
+ }
+
+ // handle deletion
+ if($DEL) {
+ $res = 0;
+ if(checkSecurityToken()) {
+ $res = media_delete($DEL,$AUTH);
+ }
+ if ($res & DOKU_MEDIA_DELETED) {
+ $msg = sprintf($lang['deletesucc'], noNS($DEL));
+ if ($res & DOKU_MEDIA_EMPTY_NS && !$fullscreen) {
+ // current namespace was removed. redirecting to root ns passing msg along
+ send_redirect(DOKU_URL.'lib/exe/mediamanager.php?msg1='.
+ rawurlencode($msg).'&edid='.$_REQUEST['edid']);
+ }
+ msg($msg,1);
+ } elseif ($res & DOKU_MEDIA_INUSE) {
+ if(!$conf['refshow']) {
+ msg(sprintf($lang['mediainuse'],noNS($DEL)),0);
+ }
+ } else {
+ msg(sprintf($lang['deletefail'],noNS($DEL)),-1);
+ }
+ }
+ // finished - start output
+
+ if (!$fullscreen) {
+ header('Content-Type: text/html; charset=utf-8');
+ include(template('mediamanager.php'));
+ }
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
diff --git a/lib/exe/opensearch.php b/lib/exe/opensearch.php
new file mode 100644
index 000000000..73939c347
--- /dev/null
+++ b/lib/exe/opensearch.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * DokuWiki OpenSearch creator
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @link http://www.opensearch.org/
+ * @author Mike Frysinger <vapier@gentoo.org>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching)
+if(!defined('NL')) define('NL',"\n");
+require_once(DOKU_INC.'inc/init.php');
+
+// try to be clever about the favicon location
+if(file_exists(DOKU_INC.'favicon.ico')){
+ $ico = DOKU_URL.'favicon.ico';
+}elseif(file_exists(tpl_incdir().'images/favicon.ico')){
+ $ico = DOKU_URL.'lib/tpl/'.$conf['template'].'/images/favicon.ico';
+}elseif(file_exists(tpl_incdir().'favicon.ico')){
+ $ico = DOKU_URL.'lib/tpl/'.$conf['template'].'/favicon.ico';
+}else{
+ $ico = DOKU_URL.'lib/tpl/default/images/favicon.ico';
+}
+
+// output
+header('Content-Type: application/opensearchdescription+xml; charset=utf-8');
+echo '<?xml version="1.0"?>'.NL;
+echo '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">'.NL;
+echo ' <ShortName>'.htmlspecialchars($conf['title']).'</ShortName>'.NL;
+echo ' <Image width="16" height="16" type="image/x-icon">'.$ico.'</Image>'.NL;
+echo ' <Url type="text/html" template="'.DOKU_URL.DOKU_SCRIPT.'?do=search&amp;id={searchTerms}" />'.NL;
+echo ' <Url type="application/x-suggestions+json" template="'.
+ DOKU_URL.'lib/exe/ajax.php?call=suggestions&amp;q={searchTerms}" />'.NL;
+echo '</OpenSearchDescription>'.NL;
+
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/exe/xmlrpc.php b/lib/exe/xmlrpc.php
new file mode 100644
index 000000000..1264ff333
--- /dev/null
+++ b/lib/exe/xmlrpc.php
@@ -0,0 +1,888 @@
+<?php
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+
+// fix when '< ?xml' isn't on the very first line
+if(isset($HTTP_RAW_POST_DATA)) $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);
+
+/**
+ * Increased whenever the API is changed
+ */
+define('DOKU_XMLRPC_API_VERSION', 7);
+
+require_once(DOKU_INC.'inc/init.php');
+session_write_close(); //close session
+
+if(!$conf['xmlrpc']) die('XML-RPC server not enabled.');
+
+/**
+ * Contains needed wrapper functions and registers all available
+ * XMLRPC functions.
+ */
+class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer {
+ var $methods = array();
+ var $public_methods = array();
+
+ /**
+ * Checks if the current user is allowed to execute non anonymous methods
+ */
+ function checkAuth(){
+ global $conf;
+ global $USERINFO;
+
+ if(!$conf['useacl']) return true; //no ACL - then no checks
+ if(trim($conf['xmlrpcuser']) == '') return true; //no restrictions
+
+ return auth_isMember($conf['xmlrpcuser'],$_SERVER['REMOTE_USER'],(array) $USERINFO['grps']);
+ }
+
+ /**
+ * Adds a callback, extends parent method
+ *
+ * add another parameter to define if anonymous access to
+ * this method should be granted.
+ */
+ function addCallback($method, $callback, $args, $help, $public=false){
+ if($public) $this->public_methods[] = $method;
+ return parent::addCallback($method, $callback, $args, $help);
+ }
+
+ /**
+ * Execute a call, extends parent method
+ *
+ * Checks for authentication first
+ */
+ function call($methodname, $args){
+ if(!in_array($methodname,$this->public_methods) && !$this->checkAuth()){
+ if (!isset($_SERVER['REMOTE_USER'])) {
+ header('HTTP/1.1 401 Unauthorized');
+ } else {
+ header('HTTP/1.1 403 Forbidden');
+ }
+ return new IXR_Error(-32603, 'server error. not authorized to call method "'.$methodname.'".');
+ }
+ return parent::call($methodname, $args);
+ }
+
+ /**
+ * Constructor. Register methods and run Server
+ */
+ function dokuwiki_xmlrpc_server(){
+ $this->IXR_IntrospectionServer();
+
+ /* DokuWiki's own methods */
+ $this->addCallback(
+ 'dokuwiki.getXMLRPCAPIVersion',
+ 'this:getAPIVersion',
+ array('integer'),
+ 'Returns the XMLRPC API version.',
+ true
+ );
+
+ $this->addCallback(
+ 'dokuwiki.getVersion',
+ 'getVersion',
+ array('string'),
+ 'Returns the running DokuWiki version.',
+ true
+ );
+
+ $this->addCallback(
+ 'dokuwiki.login',
+ 'this:login',
+ array('integer','string','string'),
+ 'Tries to login with the given credentials and sets auth cookies.',
+ true
+ );
+
+ $this->addCallback(
+ 'dokuwiki.getPagelist',
+ 'this:readNamespace',
+ array('struct','string','struct'),
+ 'List all pages within the given namespace.'
+ );
+
+ $this->addCallback(
+ 'dokuwiki.search',
+ 'this:search',
+ array('struct','string'),
+ 'Perform a fulltext search and return a list of matching pages'
+ );
+
+ $this->addCallback(
+ 'dokuwiki.getTime',
+ 'time',
+ array('int'),
+ 'Return the current time at the wiki server.'
+ );
+
+ $this->addCallback(
+ 'dokuwiki.setLocks',
+ 'this:setLocks',
+ array('struct','struct'),
+ 'Lock or unlock pages.'
+ );
+
+
+ $this->addCallback(
+ 'dokuwiki.getTitle',
+ 'this:getTitle',
+ array('string'),
+ 'Returns the wiki title.',
+ true
+ );
+
+ $this->addCallback(
+ 'dokuwiki.appendPage',
+ 'this:appendPage',
+ array('int', 'string', 'string', 'struct'),
+ 'Append text to a wiki page.'
+ );
+
+ /* Wiki API v2 http://www.jspwiki.org/wiki/WikiRPCInterface2 */
+ $this->addCallback(
+ 'wiki.getRPCVersionSupported',
+ 'this:wiki_RPCVersion',
+ array('int'),
+ 'Returns 2 with the supported RPC API version.',
+ true
+ );
+ $this->addCallback(
+ 'wiki.getPage',
+ 'this:rawPage',
+ array('string','string'),
+ 'Get the raw Wiki text of page, latest version.'
+ );
+ $this->addCallback(
+ 'wiki.getPageVersion',
+ 'this:rawPage',
+ array('string','string','int'),
+ 'Get the raw Wiki text of page.'
+ );
+ $this->addCallback(
+ 'wiki.getPageHTML',
+ 'this:htmlPage',
+ array('string','string'),
+ 'Return page in rendered HTML, latest version.'
+ );
+ $this->addCallback(
+ 'wiki.getPageHTMLVersion',
+ 'this:htmlPage',
+ array('string','string','int'),
+ 'Return page in rendered HTML.'
+ );
+ $this->addCallback(
+ 'wiki.getAllPages',
+ 'this:listPages',
+ array('struct'),
+ 'Returns a list of all pages. The result is an array of utf8 pagenames.'
+ );
+ $this->addCallback(
+ 'wiki.getAttachments',
+ 'this:listAttachments',
+ array('struct', 'string', 'struct'),
+ 'Returns a list of all media files.'
+ );
+ $this->addCallback(
+ 'wiki.getBackLinks',
+ 'this:listBackLinks',
+ array('struct','string'),
+ 'Returns the pages that link to this page.'
+ );
+ $this->addCallback(
+ 'wiki.getPageInfo',
+ 'this:pageInfo',
+ array('struct','string'),
+ 'Returns a struct with infos about the page.'
+ );
+ $this->addCallback(
+ 'wiki.getPageInfoVersion',
+ 'this:pageInfo',
+ array('struct','string','int'),
+ 'Returns a struct with infos about the page.'
+ );
+ $this->addCallback(
+ 'wiki.getPageVersions',
+ 'this:pageVersions',
+ array('struct','string','int'),
+ 'Returns the available revisions of the page.'
+ );
+ $this->addCallback(
+ 'wiki.putPage',
+ 'this:putPage',
+ array('int', 'string', 'string', 'struct'),
+ 'Saves a wiki page.'
+ );
+ $this->addCallback(
+ 'wiki.listLinks',
+ 'this:listLinks',
+ array('struct','string'),
+ 'Lists all links contained in a wiki page.'
+ );
+ $this->addCallback(
+ 'wiki.getRecentChanges',
+ 'this:getRecentChanges',
+ array('struct','int'),
+ 'Returns a struct about all recent changes since given timestamp.'
+ );
+ $this->addCallback(
+ 'wiki.getRecentMediaChanges',
+ 'this:getRecentMediaChanges',
+ array('struct','int'),
+ 'Returns a struct about all recent media changes since given timestamp.'
+ );
+ $this->addCallback(
+ 'wiki.aclCheck',
+ 'this:aclCheck',
+ array('int', 'string'),
+ 'Returns the permissions of a given wiki page.'
+ );
+ $this->addCallback(
+ 'wiki.putAttachment',
+ 'this:putAttachment',
+ array('struct', 'string', 'base64', 'struct'),
+ 'Upload a file to the wiki.'
+ );
+ $this->addCallback(
+ 'wiki.deleteAttachment',
+ 'this:deleteAttachment',
+ array('int', 'string'),
+ 'Delete a file from the wiki.'
+ );
+ $this->addCallback(
+ 'wiki.getAttachment',
+ 'this:getAttachment',
+ array('base64', 'string'),
+ 'Download a file from the wiki.'
+ );
+ $this->addCallback(
+ 'wiki.getAttachmentInfo',
+ 'this:getAttachmentInfo',
+ array('struct', 'string'),
+ 'Returns a struct with infos about the attachment.'
+ );
+
+ /**
+ * Trigger XMLRPC_CALLBACK_REGISTER, action plugins can use this event
+ * to extend the XMLRPC interface and register their own callbacks.
+ *
+ * Event data:
+ * The XMLRPC server object:
+ *
+ * $event->data->addCallback() - register a callback, the second
+ * paramter has to be of the form "plugin:<pluginname>:<plugin
+ * method>"
+ *
+ * $event->data->callbacks - an array which holds all awaylable
+ * callbacks
+ */
+ trigger_event('XMLRPC_CALLBACK_REGISTER', $this);
+
+ $this->serve();
+ }
+
+ /**
+ * Return a raw wiki page
+ */
+ function rawPage($id,$rev=''){
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_READ){
+ return new IXR_Error(111, 'You are not allowed to read this page');
+ }
+ $text = rawWiki($id,$rev);
+ if(!$text) {
+ return pageTemplate($id);
+ } else {
+ return $text;
+ }
+ }
+
+ /**
+ * Return a media file encoded in base64
+ *
+ * @author Gina Haeussge <osd@foosel.net>
+ */
+ function getAttachment($id){
+ $id = cleanID($id);
+ if (auth_quickaclcheck(getNS($id).':*') < AUTH_READ)
+ return new IXR_Error(211, 'You are not allowed to read this file');
+
+ $file = mediaFN($id);
+ if (!@ file_exists($file))
+ return new IXR_Error(221, 'The requested file does not exist');
+
+ $data = io_readFile($file, false);
+ $base64 = new IXR_Base64($data);
+ return $base64;
+ }
+
+ /**
+ * Return info about a media file
+ *
+ * @author Gina Haeussge <osd@foosel.net>
+ */
+ function getAttachmentInfo($id){
+ $id = cleanID($id);
+ $info = array(
+ 'lastModified' => 0,
+ 'size' => 0,
+ );
+
+ $file = mediaFN($id);
+ if ((auth_quickaclcheck(getNS($id).':*') >= AUTH_READ) && file_exists($file)){
+ $info['lastModified'] = new IXR_Date(filemtime($file));
+ $info['size'] = filesize($file);
+ }
+
+ return $info;
+ }
+
+ /**
+ * Return a wiki page rendered to html
+ */
+ function htmlPage($id,$rev=''){
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_READ){
+ return new IXR_Error(111, 'You are not allowed to read this page');
+ }
+ return p_wiki_xhtml($id,$rev,false);
+ }
+
+ /**
+ * List all pages - we use the indexer list here
+ */
+ function listPages(){
+ $list = array();
+ $pages = idx_get_indexer()->getPages();
+ $pages = array_filter(array_filter($pages,'isVisiblePage'),'page_exists');
+
+ foreach(array_keys($pages) as $idx) {
+ $perm = auth_quickaclcheck($pages[$idx]);
+ if($perm < AUTH_READ) {
+ continue;
+ }
+ $page = array();
+ $page['id'] = trim($pages[$idx]);
+ $page['perms'] = $perm;
+ $page['size'] = @filesize(wikiFN($pages[$idx]));
+ $page['lastModified'] = new IXR_Date(@filemtime(wikiFN($pages[$idx])));
+ $list[] = $page;
+ }
+
+ return $list;
+ }
+
+ /**
+ * List all pages in the given namespace (and below)
+ */
+ function readNamespace($ns,$opts){
+ global $conf;
+
+ if(!is_array($opts)) $opts=array();
+
+ $ns = cleanID($ns);
+ $dir = utf8_encodeFN(str_replace(':', '/', $ns));
+ $data = array();
+ $opts['skipacl'] = 0; // no ACL skipping for XMLRPC
+ search($data, $conf['datadir'], 'search_allpages', $opts, $dir);
+ return $data;
+ }
+
+ /**
+ * List all pages in the given namespace (and below)
+ */
+ function search($query){
+ require_once(DOKU_INC.'inc/fulltext.php');
+
+ $regex = '';
+ $data = ft_pageSearch($query,$regex);
+ $pages = array();
+
+ // prepare additional data
+ $idx = 0;
+ foreach($data as $id => $score){
+ $file = wikiFN($id);
+
+ if($idx < FT_SNIPPET_NUMBER){
+ $snippet = ft_snippet($id,$regex);
+ $idx++;
+ }else{
+ $snippet = '';
+ }
+
+ $pages[] = array(
+ 'id' => $id,
+ 'score' => intval($score),
+ 'rev' => filemtime($file),
+ 'mtime' => filemtime($file),
+ 'size' => filesize($file),
+ 'snippet' => $snippet,
+ );
+ }
+ return $pages;
+ }
+
+ /**
+ * Returns the wiki title.
+ */
+ function getTitle(){
+ global $conf;
+ return $conf['title'];
+ }
+
+ /**
+ * List all media files.
+ *
+ * Available options are 'recursive' for also including the subnamespaces
+ * in the listing, and 'pattern' for filtering the returned files against
+ * a regular expression matching their name.
+ *
+ * @author Gina Haeussge <osd@foosel.net>
+ */
+ function listAttachments($ns, $options = array()) {
+ global $conf;
+ global $lang;
+
+ $ns = cleanID($ns);
+
+ if (!is_array($options)) $options = array();
+ $options['skipacl'] = 0; // no ACL skipping for XMLRPC
+
+
+ if(auth_quickaclcheck($ns.':*') >= AUTH_READ) {
+ $dir = utf8_encodeFN(str_replace(':', '/', $ns));
+
+ $data = array();
+ search($data, $conf['mediadir'], 'search_media', $options, $dir);
+ $len = count($data);
+ if(!$len) return array();
+
+ for($i=0; $i<$len; $i++) {
+ unset($data[$i]['meta']);
+ $data[$i]['lastModified'] = new IXR_Date($data[$i]['mtime']);
+ }
+ return $data;
+ } else {
+ return new IXR_Error(215, 'You are not allowed to list media files.');
+ }
+ }
+
+ /**
+ * Return a list of backlinks
+ */
+ function listBackLinks($id){
+ return ft_backlinks(cleanID($id));
+ }
+
+ /**
+ * Return some basic data about a page
+ */
+ function pageInfo($id,$rev=''){
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_READ){
+ return new IXR_Error(111, 'You are not allowed to read this page');
+ }
+ $file = wikiFN($id,$rev);
+ $time = @filemtime($file);
+ if(!$time){
+ return new IXR_Error(121, 'The requested page does not exist');
+ }
+
+ $info = getRevisionInfo($id, $time, 1024);
+
+ $data = array(
+ 'name' => $id,
+ 'lastModified' => new IXR_Date($time),
+ 'author' => (($info['user']) ? $info['user'] : $info['ip']),
+ 'version' => $time
+ );
+
+ return ($data);
+ }
+
+ /**
+ * Save a wiki page
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ */
+ function putPage($id, $text, $params) {
+ global $TEXT;
+ global $lang;
+ global $conf;
+
+ $id = cleanID($id);
+ $TEXT = cleanText($text);
+ $sum = $params['sum'];
+ $minor = $params['minor'];
+
+ if(empty($id))
+ return new IXR_Error(131, 'Empty page ID');
+
+ if(!page_exists($id) && trim($TEXT) == '' ) {
+ return new IXR_ERROR(132, 'Refusing to write an empty new wiki page');
+ }
+
+ if(auth_quickaclcheck($id) < AUTH_EDIT)
+ return new IXR_Error(112, 'You are not allowed to edit this page');
+
+ // Check, if page is locked
+ if(checklock($id))
+ return new IXR_Error(133, 'The page is currently locked');
+
+ // SPAM check
+ if(checkwordblock())
+ return new IXR_Error(134, 'Positive wordblock check');
+
+ // autoset summary on new pages
+ if(!page_exists($id) && empty($sum)) {
+ $sum = $lang['created'];
+ }
+
+ // autoset summary on deleted pages
+ if(page_exists($id) && empty($TEXT) && empty($sum)) {
+ $sum = $lang['deleted'];
+ }
+
+ lock($id);
+
+ saveWikiText($id,$TEXT,$sum,$minor);
+
+ unlock($id);
+
+ // run the indexer if page wasn't indexed yet
+ idx_addPage($id);
+
+ return 0;
+ }
+
+ /**
+ * Appends text to a wiki page.
+ */
+ function appendPage($id, $text, $params) {
+ $currentpage = $this->rawPage($id);
+ if (!is_string($currentpage)) {
+ return $currentpage;
+ }
+ return $this->putPage($id, $currentpage.$text, $params);
+ }
+
+ /**
+ * Uploads a file to the wiki.
+ *
+ * Michael Klier <chi@chimeric.de>
+ */
+ function putAttachment($id, $file, $params) {
+ $id = cleanID($id);
+ $auth = auth_quickaclcheck(getNS($id).':*');
+
+ if(!isset($id)) {
+ return new IXR_ERROR(231, 'Filename not given.');
+ }
+
+ global $conf;
+
+ $ftmp = $conf['tmpdir'] . '/' . md5($id.clientIP());
+
+ // save temporary file
+ @unlink($ftmp);
+ if (preg_match('/^[A-Za-z0-9\+\/]*={0,2}$/', $file) === 1) {
+ // DEPRECATED: Double-decode file if it still looks like base64
+ // after first decoding (which is done by the library)
+ $file = base64_decode($file);
+ }
+ io_saveFile($ftmp, $file);
+
+ $res = media_save(array('name' => $ftmp), $id, $params['ow'], $auth, 'rename');
+ if (is_array($res)) {
+ return new IXR_ERROR(-$res[1], $res[0]);
+ } else {
+ return $res;
+ }
+ }
+
+ /**
+ * Deletes a file from the wiki.
+ *
+ * @author Gina Haeussge <osd@foosel.net>
+ */
+ function deleteAttachment($id){
+ $id = cleanID($id);
+ $auth = auth_quickaclcheck(getNS($id).':*');
+ $res = media_delete($id, $auth);
+ if ($res & DOKU_MEDIA_DELETED) {
+ return 0;
+ } elseif ($res & DOKU_MEDIA_NOT_AUTH) {
+ return new IXR_ERROR(212, "You don't have permissions to delete files.");
+ } elseif ($res & DOKU_MEDIA_INUSE) {
+ return new IXR_ERROR(232, 'File is still referenced');
+ } else {
+ return new IXR_ERROR(233, 'Could not delete file');
+ }
+ }
+
+ /**
+ * Returns the permissions of a given wiki page
+ */
+ function aclCheck($id) {
+ $id = cleanID($id);
+ return auth_quickaclcheck($id);
+ }
+
+ /**
+ * Lists all links contained in a wiki page
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ */
+ function listLinks($id) {
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_READ){
+ return new IXR_Error(111, 'You are not allowed to read this page');
+ }
+ $links = array();
+
+ // resolve page instructions
+ $ins = p_cached_instructions(wikiFN($id));
+
+ // instantiate new Renderer - needed for interwiki links
+ include(DOKU_INC.'inc/parser/xhtml.php');
+ $Renderer = new Doku_Renderer_xhtml();
+ $Renderer->interwiki = getInterwiki();
+
+ // parse parse instructions
+ foreach($ins as $in) {
+ $link = array();
+ switch($in[0]) {
+ case 'internallink':
+ $link['type'] = 'local';
+ $link['page'] = $in[1][0];
+ $link['href'] = wl($in[1][0]);
+ array_push($links,$link);
+ break;
+ case 'externallink':
+ $link['type'] = 'extern';
+ $link['page'] = $in[1][0];
+ $link['href'] = $in[1][0];
+ array_push($links,$link);
+ break;
+ case 'interwikilink':
+ $url = $Renderer->_resolveInterWiki($in[1][2],$in[1][3]);
+ $link['type'] = 'extern';
+ $link['page'] = $url;
+ $link['href'] = $url;
+ array_push($links,$link);
+ break;
+ }
+ }
+
+ return ($links);
+ }
+
+ /**
+ * Returns a list of recent changes since give timestamp
+ *
+ * @author Michael Hamann <michael@content-space.de>
+ * @author Michael Klier <chi@chimeric.de>
+ */
+ function getRecentChanges($timestamp) {
+ if(strlen($timestamp) != 10)
+ return new IXR_Error(311, 'The provided value is not a valid timestamp');
+
+ $recents = getRecentsSince($timestamp);
+
+ $changes = array();
+
+ foreach ($recents as $recent) {
+ $change = array();
+ $change['name'] = $recent['id'];
+ $change['lastModified'] = new IXR_Date($recent['date']);
+ $change['author'] = $recent['user'];
+ $change['version'] = $recent['date'];
+ $change['perms'] = $recent['perms'];
+ $change['size'] = @filesize(wikiFN($recent['id']));
+ array_push($changes, $change);
+ }
+
+ if (!empty($changes)) {
+ return $changes;
+ } else {
+ // in case we still have nothing at this point
+ return new IXR_Error(321, 'There are no changes in the specified timeframe');
+ }
+ }
+
+ /**
+ * Returns a list of recent media changes since give timestamp
+ *
+ * @author Michael Hamann <michael@content-space.de>
+ * @author Michael Klier <chi@chimeric.de>
+ */
+ function getRecentMediaChanges($timestamp) {
+ if(strlen($timestamp) != 10)
+ return new IXR_Error(311, 'The provided value is not a valid timestamp');
+
+ $recents = getRecentsSince($timestamp, null, '', RECENTS_MEDIA_CHANGES);
+
+ $changes = array();
+
+ foreach ($recents as $recent) {
+ $change = array();
+ $change['name'] = $recent['id'];
+ $change['lastModified'] = new IXR_Date($recent['date']);
+ $change['author'] = $recent['user'];
+ $change['version'] = $recent['date'];
+ $change['perms'] = $recent['perms'];
+ $change['size'] = @filesize(mediaFN($recent['id']));
+ array_push($changes, $change);
+ }
+
+ if (!empty($changes)) {
+ return $changes;
+ } else {
+ // in case we still have nothing at this point
+ return new IXR_Error(321, 'There are no changes in the specified timeframe');
+ }
+ }
+
+ /**
+ * Returns a list of available revisions of a given wiki page
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ */
+ function pageVersions($id, $first) {
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_READ){
+ return new IXR_Error(111, 'You are not allowed to read this page');
+ }
+ global $conf;
+
+ $versions = array();
+
+ if(empty($id))
+ return new IXR_Error(131, 'Empty page ID');
+
+ $revisions = getRevisions($id, $first, $conf['recent']+1);
+
+ if(count($revisions)==0 && $first!=0) {
+ $first=0;
+ $revisions = getRevisions($id, $first, $conf['recent']+1);
+ }
+
+ if(count($revisions)>0 && $first==0) {
+ array_unshift($revisions, ''); // include current revision
+ array_pop($revisions); // remove extra log entry
+ }
+
+ $hasNext = false;
+ if(count($revisions)>$conf['recent']) {
+ $hasNext = true;
+ array_pop($revisions); // remove extra log entry
+ }
+
+ if(!empty($revisions)) {
+ foreach($revisions as $rev) {
+ $file = wikiFN($id,$rev);
+ $time = @filemtime($file);
+ // we check if the page actually exists, if this is not the
+ // case this can lead to less pages being returned than
+ // specified via $conf['recent']
+ if($time){
+ $info = getRevisionInfo($id, $time, 1024);
+ if(!empty($info)) {
+ $data['user'] = $info['user'];
+ $data['ip'] = $info['ip'];
+ $data['type'] = $info['type'];
+ $data['sum'] = $info['sum'];
+ $data['modified'] = new IXR_Date($info['date']);
+ $data['version'] = $info['date'];
+ array_push($versions, $data);
+ }
+ }
+ }
+ return $versions;
+ } else {
+ return array();
+ }
+ }
+
+ /**
+ * The version of Wiki RPC API supported
+ */
+ function wiki_RPCVersion(){
+ return 2;
+ }
+
+
+ /**
+ * Locks or unlocks a given batch of pages
+ *
+ * Give an associative array with two keys: lock and unlock. Both should contain a
+ * list of pages to lock or unlock
+ *
+ * Returns an associative array with the keys locked, lockfail, unlocked and
+ * unlockfail, each containing lists of pages.
+ */
+ function setLocks($set){
+ $locked = array();
+ $lockfail = array();
+ $unlocked = array();
+ $unlockfail = array();
+
+ foreach((array) $set['lock'] as $id){
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_EDIT || checklock($id)){
+ $lockfail[] = $id;
+ }else{
+ lock($id);
+ $locked[] = $id;
+ }
+ }
+
+ foreach((array) $set['unlock'] as $id){
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_EDIT || !unlock($id)){
+ $unlockfail[] = $id;
+ }else{
+ $unlocked[] = $id;
+ }
+ }
+
+ return array(
+ 'locked' => $locked,
+ 'lockfail' => $lockfail,
+ 'unlocked' => $unlocked,
+ 'unlockfail' => $unlockfail,
+ );
+ }
+
+ function getAPIVersion(){
+ return DOKU_XMLRPC_API_VERSION;
+ }
+
+ function login($user,$pass){
+ global $conf;
+ global $auth;
+ if(!$conf['useacl']) return 0;
+ if(!$auth) return 0;
+
+ @session_start(); // reopen session for login
+ if($auth->canDo('external')){
+ $ok = $auth->trustExternal($user,$pass,false);
+ }else{
+ $evdata = array(
+ 'user' => $user,
+ 'password' => $pass,
+ 'sticky' => false,
+ 'silent' => true,
+ );
+ $ok = trigger_event('AUTH_LOGIN_CHECK', $evdata, 'auth_login_wrapper');
+ }
+ session_write_close(); // we're done with the session
+
+ return $ok;
+ }
+
+
+}
+
+$server = new dokuwiki_xmlrpc_server();
+
+// vim:ts=4:sw=4:et:
diff --git a/lib/images/admin/README b/lib/images/admin/README
new file mode 100644
index 000000000..90bab9578
--- /dev/null
+++ b/lib/images/admin/README
@@ -0,0 +1,2 @@
+These icons were taken from the nuvoX KDE icon theme and are GPL licensed
+See http://www.kde-look.org/content/show.php/nuvoX?content=38467
diff --git a/lib/images/admin/acl.png b/lib/images/admin/acl.png
new file mode 100644
index 000000000..c8f610c12
--- /dev/null
+++ b/lib/images/admin/acl.png
Binary files differ
diff --git a/lib/images/admin/config.png b/lib/images/admin/config.png
new file mode 100644
index 000000000..3ec3923d1
--- /dev/null
+++ b/lib/images/admin/config.png
Binary files differ
diff --git a/lib/images/admin/plugin.png b/lib/images/admin/plugin.png
new file mode 100644
index 000000000..f71124e5c
--- /dev/null
+++ b/lib/images/admin/plugin.png
Binary files differ
diff --git a/lib/images/admin/popularity.png b/lib/images/admin/popularity.png
new file mode 100644
index 000000000..19392367a
--- /dev/null
+++ b/lib/images/admin/popularity.png
Binary files differ
diff --git a/lib/images/admin/revert.png b/lib/images/admin/revert.png
new file mode 100644
index 000000000..5304f1b76
--- /dev/null
+++ b/lib/images/admin/revert.png
Binary files differ
diff --git a/lib/images/admin/usermanager.png b/lib/images/admin/usermanager.png
new file mode 100644
index 000000000..898544ce9
--- /dev/null
+++ b/lib/images/admin/usermanager.png
Binary files differ
diff --git a/lib/images/arrow_down.gif b/lib/images/arrow_down.gif
new file mode 100644
index 000000000..ff13b9585
--- /dev/null
+++ b/lib/images/arrow_down.gif
Binary files differ
diff --git a/lib/images/arrow_up.gif b/lib/images/arrow_up.gif
new file mode 100644
index 000000000..d491c18db
--- /dev/null
+++ b/lib/images/arrow_up.gif
Binary files differ
diff --git a/lib/images/at.gif b/lib/images/at.gif
new file mode 100644
index 000000000..8bdf40d54
--- /dev/null
+++ b/lib/images/at.gif
Binary files differ
diff --git a/lib/images/blank.gif b/lib/images/blank.gif
new file mode 100644
index 000000000..9935f8210
--- /dev/null
+++ b/lib/images/blank.gif
Binary files differ
diff --git a/lib/images/close.png b/lib/images/close.png
new file mode 100644
index 000000000..4ccef0603
--- /dev/null
+++ b/lib/images/close.png
Binary files differ
diff --git a/lib/images/del.png b/lib/images/del.png
new file mode 100644
index 000000000..e59ded55f
--- /dev/null
+++ b/lib/images/del.png
Binary files differ
diff --git a/lib/images/diff.png b/lib/images/diff.png
new file mode 100644
index 000000000..657b10999
--- /dev/null
+++ b/lib/images/diff.png
Binary files differ
diff --git a/lib/images/edit.gif b/lib/images/edit.gif
new file mode 100644
index 000000000..a2a23de7b
--- /dev/null
+++ b/lib/images/edit.gif
Binary files differ
diff --git a/lib/images/error.png b/lib/images/error.png
new file mode 100644
index 000000000..7bd84f7a3
--- /dev/null
+++ b/lib/images/error.png
Binary files differ
diff --git a/lib/images/fileicons/7z.png b/lib/images/fileicons/7z.png
new file mode 100644
index 000000000..52f7d5d72
--- /dev/null
+++ b/lib/images/fileicons/7z.png
Binary files differ
diff --git a/lib/images/fileicons/audio.png b/lib/images/fileicons/audio.png
new file mode 100644
index 000000000..98883256d
--- /dev/null
+++ b/lib/images/fileicons/audio.png
Binary files differ
diff --git a/lib/images/fileicons/bz2.png b/lib/images/fileicons/bz2.png
new file mode 100644
index 000000000..6ec2f98ef
--- /dev/null
+++ b/lib/images/fileicons/bz2.png
Binary files differ
diff --git a/lib/images/fileicons/c.png b/lib/images/fileicons/c.png
new file mode 100644
index 000000000..6f57337c7
--- /dev/null
+++ b/lib/images/fileicons/c.png
Binary files differ
diff --git a/lib/images/fileicons/conf.png b/lib/images/fileicons/conf.png
new file mode 100644
index 000000000..20c20fa3d
--- /dev/null
+++ b/lib/images/fileicons/conf.png
Binary files differ
diff --git a/lib/images/fileicons/cpp.png b/lib/images/fileicons/cpp.png
new file mode 100644
index 000000000..6f2797da5
--- /dev/null
+++ b/lib/images/fileicons/cpp.png
Binary files differ
diff --git a/lib/images/fileicons/cs.png b/lib/images/fileicons/cs.png
new file mode 100644
index 000000000..d3afa112c
--- /dev/null
+++ b/lib/images/fileicons/cs.png
Binary files differ
diff --git a/lib/images/fileicons/css.png b/lib/images/fileicons/css.png
new file mode 100644
index 000000000..89c1537fd
--- /dev/null
+++ b/lib/images/fileicons/css.png
Binary files differ
diff --git a/lib/images/fileicons/csv.png b/lib/images/fileicons/csv.png
new file mode 100644
index 000000000..b604453c4
--- /dev/null
+++ b/lib/images/fileicons/csv.png
Binary files differ
diff --git a/lib/images/fileicons/deb.png b/lib/images/fileicons/deb.png
new file mode 100644
index 000000000..8fe57327a
--- /dev/null
+++ b/lib/images/fileicons/deb.png
Binary files differ
diff --git a/lib/images/fileicons/doc.png b/lib/images/fileicons/doc.png
new file mode 100644
index 000000000..79d8ff1cd
--- /dev/null
+++ b/lib/images/fileicons/doc.png
Binary files differ
diff --git a/lib/images/fileicons/docx.png b/lib/images/fileicons/docx.png
new file mode 100644
index 000000000..79d8ff1cd
--- /dev/null
+++ b/lib/images/fileicons/docx.png
Binary files differ
diff --git a/lib/images/fileicons/file.png b/lib/images/fileicons/file.png
new file mode 100644
index 000000000..8158a8a21
--- /dev/null
+++ b/lib/images/fileicons/file.png
Binary files differ
diff --git a/lib/images/fileicons/gif.png b/lib/images/fileicons/gif.png
new file mode 100644
index 000000000..1d9dd562a
--- /dev/null
+++ b/lib/images/fileicons/gif.png
Binary files differ
diff --git a/lib/images/fileicons/gz.png b/lib/images/fileicons/gz.png
new file mode 100644
index 000000000..48f19596c
--- /dev/null
+++ b/lib/images/fileicons/gz.png
Binary files differ
diff --git a/lib/images/fileicons/htm.png b/lib/images/fileicons/htm.png
new file mode 100644
index 000000000..d45e4c19a
--- /dev/null
+++ b/lib/images/fileicons/htm.png
Binary files differ
diff --git a/lib/images/fileicons/html.png b/lib/images/fileicons/html.png
new file mode 100644
index 000000000..d45e4c19a
--- /dev/null
+++ b/lib/images/fileicons/html.png
Binary files differ
diff --git a/lib/images/fileicons/index.php b/lib/images/fileicons/index.php
new file mode 100644
index 000000000..c1e64fe2a
--- /dev/null
+++ b/lib/images/fileicons/index.php
@@ -0,0 +1,50 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
+ lang="en" dir="ltr">
+<head>
+ <title>filetype icons</title>
+
+ <style type="text/css">
+ body {
+ background-color: #ccc;
+ font-family: Arial;
+ }
+
+ .box {
+ width: 200px;
+ float:left;
+ padding: 0.5em;
+ margin: 0;
+ }
+
+ .white {
+ background-color: #fff;
+ }
+
+ .black {
+ background-color: #000;
+ }
+ </style>
+
+</head>
+<body>
+
+<div class="white box">
+<?php
+foreach (glob('*.png') as $img) {
+ echo '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
+}
+?>
+</div>
+
+<div class="black box">
+<?php
+foreach (glob('*.png') as $img) {
+ echo '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
+}
+?>
+</div>
+
+</body>
+</html>
diff --git a/lib/images/fileicons/java.png b/lib/images/fileicons/java.png
new file mode 100644
index 000000000..c5f2fd09f
--- /dev/null
+++ b/lib/images/fileicons/java.png
Binary files differ
diff --git a/lib/images/fileicons/jpeg.png b/lib/images/fileicons/jpeg.png
new file mode 100644
index 000000000..1d9dd562a
--- /dev/null
+++ b/lib/images/fileicons/jpeg.png
Binary files differ
diff --git a/lib/images/fileicons/jpg.png b/lib/images/fileicons/jpg.png
new file mode 100644
index 000000000..1d9dd562a
--- /dev/null
+++ b/lib/images/fileicons/jpg.png
Binary files differ
diff --git a/lib/images/fileicons/js.png b/lib/images/fileicons/js.png
new file mode 100644
index 000000000..0c314eb56
--- /dev/null
+++ b/lib/images/fileicons/js.png
Binary files differ
diff --git a/lib/images/fileicons/lua.png b/lib/images/fileicons/lua.png
new file mode 100644
index 000000000..994c6e8f0
--- /dev/null
+++ b/lib/images/fileicons/lua.png
Binary files differ
diff --git a/lib/images/fileicons/mp3.png b/lib/images/fileicons/mp3.png
new file mode 100644
index 000000000..411dad080
--- /dev/null
+++ b/lib/images/fileicons/mp3.png
Binary files differ
diff --git a/lib/images/fileicons/odc.png b/lib/images/fileicons/odc.png
new file mode 100644
index 000000000..4d6676c3a
--- /dev/null
+++ b/lib/images/fileicons/odc.png
Binary files differ
diff --git a/lib/images/fileicons/odf.png b/lib/images/fileicons/odf.png
new file mode 100644
index 000000000..cb88d68e6
--- /dev/null
+++ b/lib/images/fileicons/odf.png
Binary files differ
diff --git a/lib/images/fileicons/odg.png b/lib/images/fileicons/odg.png
new file mode 100644
index 000000000..a07216f4a
--- /dev/null
+++ b/lib/images/fileicons/odg.png
Binary files differ
diff --git a/lib/images/fileicons/odi.png b/lib/images/fileicons/odi.png
new file mode 100644
index 000000000..a07216f4a
--- /dev/null
+++ b/lib/images/fileicons/odi.png
Binary files differ
diff --git a/lib/images/fileicons/odp.png b/lib/images/fileicons/odp.png
new file mode 100644
index 000000000..2f2574af6
--- /dev/null
+++ b/lib/images/fileicons/odp.png
Binary files differ
diff --git a/lib/images/fileicons/ods.png b/lib/images/fileicons/ods.png
new file mode 100644
index 000000000..4d6676c3a
--- /dev/null
+++ b/lib/images/fileicons/ods.png
Binary files differ
diff --git a/lib/images/fileicons/odt.png b/lib/images/fileicons/odt.png
new file mode 100644
index 000000000..f9c126efd
--- /dev/null
+++ b/lib/images/fileicons/odt.png
Binary files differ
diff --git a/lib/images/fileicons/ogg.png b/lib/images/fileicons/ogg.png
new file mode 100644
index 000000000..0a21eae65
--- /dev/null
+++ b/lib/images/fileicons/ogg.png
Binary files differ
diff --git a/lib/images/fileicons/pdf.png b/lib/images/fileicons/pdf.png
new file mode 100644
index 000000000..029dcffec
--- /dev/null
+++ b/lib/images/fileicons/pdf.png
Binary files differ
diff --git a/lib/images/fileicons/php.png b/lib/images/fileicons/php.png
new file mode 100644
index 000000000..f81e405de
--- /dev/null
+++ b/lib/images/fileicons/php.png
Binary files differ
diff --git a/lib/images/fileicons/pl.png b/lib/images/fileicons/pl.png
new file mode 100644
index 000000000..92f3f9754
--- /dev/null
+++ b/lib/images/fileicons/pl.png
Binary files differ
diff --git a/lib/images/fileicons/png.png b/lib/images/fileicons/png.png
new file mode 100644
index 000000000..1d9dd562a
--- /dev/null
+++ b/lib/images/fileicons/png.png
Binary files differ
diff --git a/lib/images/fileicons/ppt.png b/lib/images/fileicons/ppt.png
new file mode 100644
index 000000000..b7afb2266
--- /dev/null
+++ b/lib/images/fileicons/ppt.png
Binary files differ
diff --git a/lib/images/fileicons/pptx.png b/lib/images/fileicons/pptx.png
new file mode 100644
index 000000000..b7afb2266
--- /dev/null
+++ b/lib/images/fileicons/pptx.png
Binary files differ
diff --git a/lib/images/fileicons/ps.png b/lib/images/fileicons/ps.png
new file mode 100644
index 000000000..40a80baad
--- /dev/null
+++ b/lib/images/fileicons/ps.png
Binary files differ
diff --git a/lib/images/fileicons/py.png b/lib/images/fileicons/py.png
new file mode 100644
index 000000000..15a727c54
--- /dev/null
+++ b/lib/images/fileicons/py.png
Binary files differ
diff --git a/lib/images/fileicons/rar.png b/lib/images/fileicons/rar.png
new file mode 100644
index 000000000..c761a4f7f
--- /dev/null
+++ b/lib/images/fileicons/rar.png
Binary files differ
diff --git a/lib/images/fileicons/rb.png b/lib/images/fileicons/rb.png
new file mode 100644
index 000000000..408f708a1
--- /dev/null
+++ b/lib/images/fileicons/rb.png
Binary files differ
diff --git a/lib/images/fileicons/rpm.png b/lib/images/fileicons/rpm.png
new file mode 100644
index 000000000..5cf727de0
--- /dev/null
+++ b/lib/images/fileicons/rpm.png
Binary files differ
diff --git a/lib/images/fileicons/rtf.png b/lib/images/fileicons/rtf.png
new file mode 100644
index 000000000..99fe3d8fd
--- /dev/null
+++ b/lib/images/fileicons/rtf.png
Binary files differ
diff --git a/lib/images/fileicons/sql.png b/lib/images/fileicons/sql.png
new file mode 100644
index 000000000..a7b0684c7
--- /dev/null
+++ b/lib/images/fileicons/sql.png
Binary files differ
diff --git a/lib/images/fileicons/swf.png b/lib/images/fileicons/swf.png
new file mode 100644
index 000000000..ecc7309ad
--- /dev/null
+++ b/lib/images/fileicons/swf.png
Binary files differ
diff --git a/lib/images/fileicons/sxc.png b/lib/images/fileicons/sxc.png
new file mode 100644
index 000000000..4d6676c3a
--- /dev/null
+++ b/lib/images/fileicons/sxc.png
Binary files differ
diff --git a/lib/images/fileicons/sxd.png b/lib/images/fileicons/sxd.png
new file mode 100644
index 000000000..a07216f4a
--- /dev/null
+++ b/lib/images/fileicons/sxd.png
Binary files differ
diff --git a/lib/images/fileicons/sxi.png b/lib/images/fileicons/sxi.png
new file mode 100644
index 000000000..2f2574af6
--- /dev/null
+++ b/lib/images/fileicons/sxi.png
Binary files differ
diff --git a/lib/images/fileicons/sxw.png b/lib/images/fileicons/sxw.png
new file mode 100644
index 000000000..f9c126efd
--- /dev/null
+++ b/lib/images/fileicons/sxw.png
Binary files differ
diff --git a/lib/images/fileicons/tar.png b/lib/images/fileicons/tar.png
new file mode 100644
index 000000000..a28c86f2d
--- /dev/null
+++ b/lib/images/fileicons/tar.png
Binary files differ
diff --git a/lib/images/fileicons/tgz.png b/lib/images/fileicons/tgz.png
new file mode 100644
index 000000000..48f19596c
--- /dev/null
+++ b/lib/images/fileicons/tgz.png
Binary files differ
diff --git a/lib/images/fileicons/txt.png b/lib/images/fileicons/txt.png
new file mode 100644
index 000000000..bb94949f6
--- /dev/null
+++ b/lib/images/fileicons/txt.png
Binary files differ
diff --git a/lib/images/fileicons/wav.png b/lib/images/fileicons/wav.png
new file mode 100644
index 000000000..c167f4fdb
--- /dev/null
+++ b/lib/images/fileicons/wav.png
Binary files differ
diff --git a/lib/images/fileicons/xls.png b/lib/images/fileicons/xls.png
new file mode 100644
index 000000000..24911b802
--- /dev/null
+++ b/lib/images/fileicons/xls.png
Binary files differ
diff --git a/lib/images/fileicons/xlsx.png b/lib/images/fileicons/xlsx.png
new file mode 100644
index 000000000..24911b802
--- /dev/null
+++ b/lib/images/fileicons/xlsx.png
Binary files differ
diff --git a/lib/images/fileicons/xml.png b/lib/images/fileicons/xml.png
new file mode 100644
index 000000000..ae9831b34
--- /dev/null
+++ b/lib/images/fileicons/xml.png
Binary files differ
diff --git a/lib/images/fileicons/zip.png b/lib/images/fileicons/zip.png
new file mode 100644
index 000000000..fb8850c9a
--- /dev/null
+++ b/lib/images/fileicons/zip.png
Binary files differ
diff --git a/lib/images/history.png b/lib/images/history.png
new file mode 100644
index 000000000..82a418d44
--- /dev/null
+++ b/lib/images/history.png
Binary files differ
diff --git a/lib/images/icon-file.png b/lib/images/icon-file.png
new file mode 100644
index 000000000..d350c8c31
--- /dev/null
+++ b/lib/images/icon-file.png
Binary files differ
diff --git a/lib/images/icon-list.png b/lib/images/icon-list.png
new file mode 100644
index 000000000..ecfeed92d
--- /dev/null
+++ b/lib/images/icon-list.png
Binary files differ
diff --git a/lib/images/icon-sort.png b/lib/images/icon-sort.png
new file mode 100644
index 000000000..c6403dd3c
--- /dev/null
+++ b/lib/images/icon-sort.png
Binary files differ
diff --git a/lib/images/icon-thumb.png b/lib/images/icon-thumb.png
new file mode 100644
index 000000000..ccc7a101d
--- /dev/null
+++ b/lib/images/icon-thumb.png
Binary files differ
diff --git a/lib/images/index.html b/lib/images/index.html
new file mode 100644
index 000000000..d614603ac
--- /dev/null
+++ b/lib/images/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="refresh" content="0; URL=../../" />
+<meta name="robots" content="noindex" />
+<title>nothing here...</title>
+</head>
+<body>
+<!-- this is just here to prevent directory browsing -->
+</body>
+</html>
diff --git a/lib/images/info.png b/lib/images/info.png
new file mode 100644
index 000000000..121c7336d
--- /dev/null
+++ b/lib/images/info.png
Binary files differ
diff --git a/lib/images/interwiki.png b/lib/images/interwiki.png
new file mode 100644
index 000000000..f957e71e5
--- /dev/null
+++ b/lib/images/interwiki.png
Binary files differ
diff --git a/lib/images/interwiki/amazon.de.gif b/lib/images/interwiki/amazon.de.gif
new file mode 100644
index 000000000..6e36a051a
--- /dev/null
+++ b/lib/images/interwiki/amazon.de.gif
Binary files differ
diff --git a/lib/images/interwiki/amazon.gif b/lib/images/interwiki/amazon.gif
new file mode 100644
index 000000000..6e36a051a
--- /dev/null
+++ b/lib/images/interwiki/amazon.gif
Binary files differ
diff --git a/lib/images/interwiki/amazon.uk.gif b/lib/images/interwiki/amazon.uk.gif
new file mode 100644
index 000000000..6e36a051a
--- /dev/null
+++ b/lib/images/interwiki/amazon.uk.gif
Binary files differ
diff --git a/lib/images/interwiki/callto.gif b/lib/images/interwiki/callto.gif
new file mode 100644
index 000000000..f6d424554
--- /dev/null
+++ b/lib/images/interwiki/callto.gif
Binary files differ
diff --git a/lib/images/interwiki/coral.gif b/lib/images/interwiki/coral.gif
new file mode 100644
index 000000000..0f9f67587
--- /dev/null
+++ b/lib/images/interwiki/coral.gif
Binary files differ
diff --git a/lib/images/interwiki/doku.gif b/lib/images/interwiki/doku.gif
new file mode 100644
index 000000000..3ccf01227
--- /dev/null
+++ b/lib/images/interwiki/doku.gif
Binary files differ
diff --git a/lib/images/interwiki/dokubug.gif b/lib/images/interwiki/dokubug.gif
new file mode 100644
index 000000000..3432b8d57
--- /dev/null
+++ b/lib/images/interwiki/dokubug.gif
Binary files differ
diff --git a/lib/images/interwiki/google.gif b/lib/images/interwiki/google.gif
new file mode 100644
index 000000000..3a28437f3
--- /dev/null
+++ b/lib/images/interwiki/google.gif
Binary files differ
diff --git a/lib/images/interwiki/meatball.gif b/lib/images/interwiki/meatball.gif
new file mode 100644
index 000000000..8a4cbdbfc
--- /dev/null
+++ b/lib/images/interwiki/meatball.gif
Binary files differ
diff --git a/lib/images/interwiki/paypal.gif b/lib/images/interwiki/paypal.gif
new file mode 100644
index 000000000..1d2834062
--- /dev/null
+++ b/lib/images/interwiki/paypal.gif
Binary files differ
diff --git a/lib/images/interwiki/phpfn.gif b/lib/images/interwiki/phpfn.gif
new file mode 100644
index 000000000..89ac1db94
--- /dev/null
+++ b/lib/images/interwiki/phpfn.gif
Binary files differ
diff --git a/lib/images/interwiki/sb.gif b/lib/images/interwiki/sb.gif
new file mode 100644
index 000000000..710e4945b
--- /dev/null
+++ b/lib/images/interwiki/sb.gif
Binary files differ
diff --git a/lib/images/interwiki/skype.png b/lib/images/interwiki/skype.png
new file mode 100644
index 000000000..c70216702
--- /dev/null
+++ b/lib/images/interwiki/skype.png
Binary files differ
diff --git a/lib/images/interwiki/wiki.gif b/lib/images/interwiki/wiki.gif
new file mode 100644
index 000000000..df241d6bb
--- /dev/null
+++ b/lib/images/interwiki/wiki.gif
Binary files differ
diff --git a/lib/images/interwiki/wp.gif b/lib/images/interwiki/wp.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wp.gif
Binary files differ
diff --git a/lib/images/interwiki/wpde.gif b/lib/images/interwiki/wpde.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wpde.gif
Binary files differ
diff --git a/lib/images/interwiki/wpes.gif b/lib/images/interwiki/wpes.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wpes.gif
Binary files differ
diff --git a/lib/images/interwiki/wpfr.gif b/lib/images/interwiki/wpfr.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wpfr.gif
Binary files differ
diff --git a/lib/images/interwiki/wpjp.gif b/lib/images/interwiki/wpjp.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wpjp.gif
Binary files differ
diff --git a/lib/images/interwiki/wpmeta.gif b/lib/images/interwiki/wpmeta.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wpmeta.gif
Binary files differ
diff --git a/lib/images/interwiki/wppl.gif b/lib/images/interwiki/wppl.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wppl.gif
Binary files differ
diff --git a/lib/images/larger.gif b/lib/images/larger.gif
new file mode 100644
index 000000000..e137c92fa
--- /dev/null
+++ b/lib/images/larger.gif
Binary files differ
diff --git a/lib/images/license/badge/cc-by-nc-nd.png b/lib/images/license/badge/cc-by-nc-nd.png
new file mode 100644
index 000000000..94aae9e09
--- /dev/null
+++ b/lib/images/license/badge/cc-by-nc-nd.png
Binary files differ
diff --git a/lib/images/license/badge/cc-by-nc-sa.png b/lib/images/license/badge/cc-by-nc-sa.png
new file mode 100644
index 000000000..51141f5ec
--- /dev/null
+++ b/lib/images/license/badge/cc-by-nc-sa.png
Binary files differ
diff --git a/lib/images/license/badge/cc-by-nc.png b/lib/images/license/badge/cc-by-nc.png
new file mode 100644
index 000000000..aeb8cdc8c
--- /dev/null
+++ b/lib/images/license/badge/cc-by-nc.png
Binary files differ
diff --git a/lib/images/license/badge/cc-by-nd.png b/lib/images/license/badge/cc-by-nd.png
new file mode 100644
index 000000000..6a2e59a68
--- /dev/null
+++ b/lib/images/license/badge/cc-by-nd.png
Binary files differ
diff --git a/lib/images/license/badge/cc-by-sa.png b/lib/images/license/badge/cc-by-sa.png
new file mode 100644
index 000000000..f0aa4aaf0
--- /dev/null
+++ b/lib/images/license/badge/cc-by-sa.png
Binary files differ
diff --git a/lib/images/license/badge/cc-by.png b/lib/images/license/badge/cc-by.png
new file mode 100644
index 000000000..c7389b2f6
--- /dev/null
+++ b/lib/images/license/badge/cc-by.png
Binary files differ
diff --git a/lib/images/license/badge/cc-zero.png b/lib/images/license/badge/cc-zero.png
new file mode 100644
index 000000000..fd3dff422
--- /dev/null
+++ b/lib/images/license/badge/cc-zero.png
Binary files differ
diff --git a/lib/images/license/badge/cc.png b/lib/images/license/badge/cc.png
new file mode 100644
index 000000000..8ac73aa4e
--- /dev/null
+++ b/lib/images/license/badge/cc.png
Binary files differ
diff --git a/lib/images/license/badge/gnufdl.png b/lib/images/license/badge/gnufdl.png
new file mode 100644
index 000000000..e92910128
--- /dev/null
+++ b/lib/images/license/badge/gnufdl.png
Binary files differ
diff --git a/lib/images/license/badge/publicdomain.png b/lib/images/license/badge/publicdomain.png
new file mode 100644
index 000000000..8148d037a
--- /dev/null
+++ b/lib/images/license/badge/publicdomain.png
Binary files differ
diff --git a/lib/images/license/button/cc-by-nc-nd.png b/lib/images/license/button/cc-by-nc-nd.png
new file mode 100644
index 000000000..ac58d8627
--- /dev/null
+++ b/lib/images/license/button/cc-by-nc-nd.png
Binary files differ
diff --git a/lib/images/license/button/cc-by-nc-sa.png b/lib/images/license/button/cc-by-nc-sa.png
new file mode 100644
index 000000000..a9d23c0b6
--- /dev/null
+++ b/lib/images/license/button/cc-by-nc-sa.png
Binary files differ
diff --git a/lib/images/license/button/cc-by-nc.png b/lib/images/license/button/cc-by-nc.png
new file mode 100644
index 000000000..d936464ad
--- /dev/null
+++ b/lib/images/license/button/cc-by-nc.png
Binary files differ
diff --git a/lib/images/license/button/cc-by-nd.png b/lib/images/license/button/cc-by-nd.png
new file mode 100644
index 000000000..3fc490870
--- /dev/null
+++ b/lib/images/license/button/cc-by-nd.png
Binary files differ
diff --git a/lib/images/license/button/cc-by-sa.png b/lib/images/license/button/cc-by-sa.png
new file mode 100644
index 000000000..3c6270a0d
--- /dev/null
+++ b/lib/images/license/button/cc-by-sa.png
Binary files differ
diff --git a/lib/images/license/button/cc-by.png b/lib/images/license/button/cc-by.png
new file mode 100644
index 000000000..867daaee4
--- /dev/null
+++ b/lib/images/license/button/cc-by.png
Binary files differ
diff --git a/lib/images/license/button/cc-zero.png b/lib/images/license/button/cc-zero.png
new file mode 100644
index 000000000..251efcd1c
--- /dev/null
+++ b/lib/images/license/button/cc-zero.png
Binary files differ
diff --git a/lib/images/license/button/cc.png b/lib/images/license/button/cc.png
new file mode 100644
index 000000000..9c492950f
--- /dev/null
+++ b/lib/images/license/button/cc.png
Binary files differ
diff --git a/lib/images/license/button/gnufdl.png b/lib/images/license/button/gnufdl.png
new file mode 100644
index 000000000..0b52ea12e
--- /dev/null
+++ b/lib/images/license/button/gnufdl.png
Binary files differ
diff --git a/lib/images/license/button/publicdomain.png b/lib/images/license/button/publicdomain.png
new file mode 100644
index 000000000..54ea38b64
--- /dev/null
+++ b/lib/images/license/button/publicdomain.png
Binary files differ
diff --git a/lib/images/list-minus.gif b/lib/images/list-minus.gif
new file mode 100644
index 000000000..36902f159
--- /dev/null
+++ b/lib/images/list-minus.gif
Binary files differ
diff --git a/lib/images/list-plus.gif b/lib/images/list-plus.gif
new file mode 100644
index 000000000..adc3fac8a
--- /dev/null
+++ b/lib/images/list-plus.gif
Binary files differ
diff --git a/lib/images/loading.gif b/lib/images/loading.gif
new file mode 100644
index 000000000..35058e20f
--- /dev/null
+++ b/lib/images/loading.gif
Binary files differ
diff --git a/lib/images/magnifier.png b/lib/images/magnifier.png
new file mode 100644
index 000000000..89febff10
--- /dev/null
+++ b/lib/images/magnifier.png
Binary files differ
diff --git a/lib/images/media_align_center.png b/lib/images/media_align_center.png
new file mode 100644
index 000000000..807f9d9a8
--- /dev/null
+++ b/lib/images/media_align_center.png
Binary files differ
diff --git a/lib/images/media_align_left.png b/lib/images/media_align_left.png
new file mode 100644
index 000000000..fa6cf33ca
--- /dev/null
+++ b/lib/images/media_align_left.png
Binary files differ
diff --git a/lib/images/media_align_noalign.png b/lib/images/media_align_noalign.png
new file mode 100644
index 000000000..263e090fe
--- /dev/null
+++ b/lib/images/media_align_noalign.png
Binary files differ
diff --git a/lib/images/media_align_right.png b/lib/images/media_align_right.png
new file mode 100644
index 000000000..33539dbdb
--- /dev/null
+++ b/lib/images/media_align_right.png
Binary files differ
diff --git a/lib/images/media_link_direct.png b/lib/images/media_link_direct.png
new file mode 100644
index 000000000..4350b803d
--- /dev/null
+++ b/lib/images/media_link_direct.png
Binary files differ
diff --git a/lib/images/media_link_displaylnk.png b/lib/images/media_link_displaylnk.png
new file mode 100644
index 000000000..53927566a
--- /dev/null
+++ b/lib/images/media_link_displaylnk.png
Binary files differ
diff --git a/lib/images/media_link_lnk.png b/lib/images/media_link_lnk.png
new file mode 100644
index 000000000..5ff4ee182
--- /dev/null
+++ b/lib/images/media_link_lnk.png
Binary files differ
diff --git a/lib/images/media_link_nolnk.png b/lib/images/media_link_nolnk.png
new file mode 100644
index 000000000..c9378c7fd
--- /dev/null
+++ b/lib/images/media_link_nolnk.png
Binary files differ
diff --git a/lib/images/media_size_large.png b/lib/images/media_size_large.png
new file mode 100644
index 000000000..012a418c3
--- /dev/null
+++ b/lib/images/media_size_large.png
Binary files differ
diff --git a/lib/images/media_size_medium.png b/lib/images/media_size_medium.png
new file mode 100644
index 000000000..1469f519f
--- /dev/null
+++ b/lib/images/media_size_medium.png
Binary files differ
diff --git a/lib/images/media_size_original.png b/lib/images/media_size_original.png
new file mode 100644
index 000000000..f58d056aa
--- /dev/null
+++ b/lib/images/media_size_original.png
Binary files differ
diff --git a/lib/images/media_size_small.png b/lib/images/media_size_small.png
new file mode 100644
index 000000000..a0aafa4a7
--- /dev/null
+++ b/lib/images/media_size_small.png
Binary files differ
diff --git a/lib/images/mediamanager.png b/lib/images/mediamanager.png
new file mode 100644
index 000000000..822b8458a
--- /dev/null
+++ b/lib/images/mediamanager.png
Binary files differ
diff --git a/lib/images/minus.gif b/lib/images/minus.gif
new file mode 100644
index 000000000..7e8cbd754
--- /dev/null
+++ b/lib/images/minus.gif
Binary files differ
diff --git a/lib/images/notify.png b/lib/images/notify.png
new file mode 100644
index 000000000..c18ef1001
--- /dev/null
+++ b/lib/images/notify.png
Binary files differ
diff --git a/lib/images/ns.png b/lib/images/ns.png
new file mode 100644
index 000000000..c35e832da
--- /dev/null
+++ b/lib/images/ns.png
Binary files differ
diff --git a/lib/images/page.png b/lib/images/page.png
new file mode 100644
index 000000000..b1b7ebe94
--- /dev/null
+++ b/lib/images/page.png
Binary files differ
diff --git a/lib/images/pencil.png b/lib/images/pencil.png
new file mode 100644
index 000000000..78142b61e
--- /dev/null
+++ b/lib/images/pencil.png
Binary files differ
diff --git a/lib/images/plus.gif b/lib/images/plus.gif
new file mode 100644
index 000000000..3da3b9458
--- /dev/null
+++ b/lib/images/plus.gif
Binary files differ
diff --git a/lib/images/smaller.gif b/lib/images/smaller.gif
new file mode 100644
index 000000000..66d3a51e7
--- /dev/null
+++ b/lib/images/smaller.gif
Binary files differ
diff --git a/lib/images/smileys/delete.gif b/lib/images/smileys/delete.gif
new file mode 100644
index 000000000..e94c68c56
--- /dev/null
+++ b/lib/images/smileys/delete.gif
Binary files differ
diff --git a/lib/images/smileys/facepalm.gif b/lib/images/smileys/facepalm.gif
new file mode 100644
index 000000000..5bebb2097
--- /dev/null
+++ b/lib/images/smileys/facepalm.gif
Binary files differ
diff --git a/lib/images/smileys/fixme.gif b/lib/images/smileys/fixme.gif
new file mode 100644
index 000000000..e19141370
--- /dev/null
+++ b/lib/images/smileys/fixme.gif
Binary files differ
diff --git a/lib/images/smileys/icon_arrow.gif b/lib/images/smileys/icon_arrow.gif
new file mode 100644
index 000000000..6771defd3
--- /dev/null
+++ b/lib/images/smileys/icon_arrow.gif
Binary files differ
diff --git a/lib/images/smileys/icon_biggrin.gif b/lib/images/smileys/icon_biggrin.gif
new file mode 100644
index 000000000..aa29c14f6
--- /dev/null
+++ b/lib/images/smileys/icon_biggrin.gif
Binary files differ
diff --git a/lib/images/smileys/icon_confused.gif b/lib/images/smileys/icon_confused.gif
new file mode 100644
index 000000000..0ea9ed241
--- /dev/null
+++ b/lib/images/smileys/icon_confused.gif
Binary files differ
diff --git a/lib/images/smileys/icon_cool.gif b/lib/images/smileys/icon_cool.gif
new file mode 100644
index 000000000..3469ad482
--- /dev/null
+++ b/lib/images/smileys/icon_cool.gif
Binary files differ
diff --git a/lib/images/smileys/icon_cry.gif b/lib/images/smileys/icon_cry.gif
new file mode 100644
index 000000000..25aea5753
--- /dev/null
+++ b/lib/images/smileys/icon_cry.gif
Binary files differ
diff --git a/lib/images/smileys/icon_doubt.gif b/lib/images/smileys/icon_doubt.gif
new file mode 100644
index 000000000..b4afc6da7
--- /dev/null
+++ b/lib/images/smileys/icon_doubt.gif
Binary files differ
diff --git a/lib/images/smileys/icon_doubt2.gif b/lib/images/smileys/icon_doubt2.gif
new file mode 100644
index 000000000..1f57eb963
--- /dev/null
+++ b/lib/images/smileys/icon_doubt2.gif
Binary files differ
diff --git a/lib/images/smileys/icon_eek.gif b/lib/images/smileys/icon_eek.gif
new file mode 100644
index 000000000..276b01d55
--- /dev/null
+++ b/lib/images/smileys/icon_eek.gif
Binary files differ
diff --git a/lib/images/smileys/icon_evil.gif b/lib/images/smileys/icon_evil.gif
new file mode 100644
index 000000000..d756916c9
--- /dev/null
+++ b/lib/images/smileys/icon_evil.gif
Binary files differ
diff --git a/lib/images/smileys/icon_exclaim.gif b/lib/images/smileys/icon_exclaim.gif
new file mode 100644
index 000000000..215b32e76
--- /dev/null
+++ b/lib/images/smileys/icon_exclaim.gif
Binary files differ
diff --git a/lib/images/smileys/icon_frown.gif b/lib/images/smileys/icon_frown.gif
new file mode 100644
index 000000000..d46caf78f
--- /dev/null
+++ b/lib/images/smileys/icon_frown.gif
Binary files differ
diff --git a/lib/images/smileys/icon_fun.gif b/lib/images/smileys/icon_fun.gif
new file mode 100644
index 000000000..6d3c44276
--- /dev/null
+++ b/lib/images/smileys/icon_fun.gif
Binary files differ
diff --git a/lib/images/smileys/icon_idea.gif b/lib/images/smileys/icon_idea.gif
new file mode 100644
index 000000000..41eaa0624
--- /dev/null
+++ b/lib/images/smileys/icon_idea.gif
Binary files differ
diff --git a/lib/images/smileys/icon_kaddi.gif b/lib/images/smileys/icon_kaddi.gif
new file mode 100644
index 000000000..56344bbb0
--- /dev/null
+++ b/lib/images/smileys/icon_kaddi.gif
Binary files differ
diff --git a/lib/images/smileys/icon_lol.gif b/lib/images/smileys/icon_lol.gif
new file mode 100644
index 000000000..d1c20c07a
--- /dev/null
+++ b/lib/images/smileys/icon_lol.gif
Binary files differ
diff --git a/lib/images/smileys/icon_mrgreen.gif b/lib/images/smileys/icon_mrgreen.gif
new file mode 100644
index 000000000..fc5d91683
--- /dev/null
+++ b/lib/images/smileys/icon_mrgreen.gif
Binary files differ
diff --git a/lib/images/smileys/icon_neutral.gif b/lib/images/smileys/icon_neutral.gif
new file mode 100644
index 000000000..c82a974c7
--- /dev/null
+++ b/lib/images/smileys/icon_neutral.gif
Binary files differ
diff --git a/lib/images/smileys/icon_question.gif b/lib/images/smileys/icon_question.gif
new file mode 100644
index 000000000..4e3092498
--- /dev/null
+++ b/lib/images/smileys/icon_question.gif
Binary files differ
diff --git a/lib/images/smileys/icon_razz.gif b/lib/images/smileys/icon_razz.gif
new file mode 100644
index 000000000..310655eec
--- /dev/null
+++ b/lib/images/smileys/icon_razz.gif
Binary files differ
diff --git a/lib/images/smileys/icon_redface.gif b/lib/images/smileys/icon_redface.gif
new file mode 100644
index 000000000..160c20f33
--- /dev/null
+++ b/lib/images/smileys/icon_redface.gif
Binary files differ
diff --git a/lib/images/smileys/icon_rolleyes.gif b/lib/images/smileys/icon_rolleyes.gif
new file mode 100644
index 000000000..502c5c174
--- /dev/null
+++ b/lib/images/smileys/icon_rolleyes.gif
Binary files differ
diff --git a/lib/images/smileys/icon_sad.gif b/lib/images/smileys/icon_sad.gif
new file mode 100644
index 000000000..d46caf78f
--- /dev/null
+++ b/lib/images/smileys/icon_sad.gif
Binary files differ
diff --git a/lib/images/smileys/icon_silenced.gif b/lib/images/smileys/icon_silenced.gif
new file mode 100644
index 000000000..5f722e04e
--- /dev/null
+++ b/lib/images/smileys/icon_silenced.gif
Binary files differ
diff --git a/lib/images/smileys/icon_smile.gif b/lib/images/smileys/icon_smile.gif
new file mode 100644
index 000000000..df125e2b5
--- /dev/null
+++ b/lib/images/smileys/icon_smile.gif
Binary files differ
diff --git a/lib/images/smileys/icon_smile2.gif b/lib/images/smileys/icon_smile2.gif
new file mode 100644
index 000000000..6b4909c81
--- /dev/null
+++ b/lib/images/smileys/icon_smile2.gif
Binary files differ
diff --git a/lib/images/smileys/icon_surprised.gif b/lib/images/smileys/icon_surprised.gif
new file mode 100644
index 000000000..aaa94f1da
--- /dev/null
+++ b/lib/images/smileys/icon_surprised.gif
Binary files differ
diff --git a/lib/images/smileys/icon_twisted.gif b/lib/images/smileys/icon_twisted.gif
new file mode 100644
index 000000000..eaec19338
--- /dev/null
+++ b/lib/images/smileys/icon_twisted.gif
Binary files differ
diff --git a/lib/images/smileys/icon_wink.gif b/lib/images/smileys/icon_wink.gif
new file mode 100644
index 000000000..78b6ad3db
--- /dev/null
+++ b/lib/images/smileys/icon_wink.gif
Binary files differ
diff --git a/lib/images/success.png b/lib/images/success.png
new file mode 100644
index 000000000..9241adbb2
--- /dev/null
+++ b/lib/images/success.png
Binary files differ
diff --git a/lib/images/throbber.gif b/lib/images/throbber.gif
new file mode 100644
index 000000000..27178a8cf
--- /dev/null
+++ b/lib/images/throbber.gif
Binary files differ
diff --git a/lib/images/toolbar/bold.png b/lib/images/toolbar/bold.png
new file mode 100644
index 000000000..51ddb8880
--- /dev/null
+++ b/lib/images/toolbar/bold.png
Binary files differ
diff --git a/lib/images/toolbar/chars.png b/lib/images/toolbar/chars.png
new file mode 100644
index 000000000..bad37e503
--- /dev/null
+++ b/lib/images/toolbar/chars.png
Binary files differ
diff --git a/lib/images/toolbar/h.png b/lib/images/toolbar/h.png
new file mode 100644
index 000000000..6a48cbbc0
--- /dev/null
+++ b/lib/images/toolbar/h.png
Binary files differ
diff --git a/lib/images/toolbar/h1.png b/lib/images/toolbar/h1.png
new file mode 100644
index 000000000..85bd06e6c
--- /dev/null
+++ b/lib/images/toolbar/h1.png
Binary files differ
diff --git a/lib/images/toolbar/h2.png b/lib/images/toolbar/h2.png
new file mode 100644
index 000000000..be2c60031
--- /dev/null
+++ b/lib/images/toolbar/h2.png
Binary files differ
diff --git a/lib/images/toolbar/h3.png b/lib/images/toolbar/h3.png
new file mode 100644
index 000000000..350da88b6
--- /dev/null
+++ b/lib/images/toolbar/h3.png
Binary files differ
diff --git a/lib/images/toolbar/h4.png b/lib/images/toolbar/h4.png
new file mode 100644
index 000000000..bc1b7038f
--- /dev/null
+++ b/lib/images/toolbar/h4.png
Binary files differ
diff --git a/lib/images/toolbar/h5.png b/lib/images/toolbar/h5.png
new file mode 100644
index 000000000..b6c263dfb
--- /dev/null
+++ b/lib/images/toolbar/h5.png
Binary files differ
diff --git a/lib/images/toolbar/hequal.png b/lib/images/toolbar/hequal.png
new file mode 100644
index 000000000..da4e921ff
--- /dev/null
+++ b/lib/images/toolbar/hequal.png
Binary files differ
diff --git a/lib/images/toolbar/hminus.png b/lib/images/toolbar/hminus.png
new file mode 100644
index 000000000..c00f70223
--- /dev/null
+++ b/lib/images/toolbar/hminus.png
Binary files differ
diff --git a/lib/images/toolbar/hplus.png b/lib/images/toolbar/hplus.png
new file mode 100644
index 000000000..6124b5c33
--- /dev/null
+++ b/lib/images/toolbar/hplus.png
Binary files differ
diff --git a/lib/images/toolbar/hr.png b/lib/images/toolbar/hr.png
new file mode 100644
index 000000000..de3a8a55b
--- /dev/null
+++ b/lib/images/toolbar/hr.png
Binary files differ
diff --git a/lib/images/toolbar/image.png b/lib/images/toolbar/image.png
new file mode 100644
index 000000000..70b12fcc2
--- /dev/null
+++ b/lib/images/toolbar/image.png
Binary files differ
diff --git a/lib/images/toolbar/italic.png b/lib/images/toolbar/italic.png
new file mode 100644
index 000000000..d69e66070
--- /dev/null
+++ b/lib/images/toolbar/italic.png
Binary files differ
diff --git a/lib/images/toolbar/link.png b/lib/images/toolbar/link.png
new file mode 100644
index 000000000..01105b0d3
--- /dev/null
+++ b/lib/images/toolbar/link.png
Binary files differ
diff --git a/lib/images/toolbar/linkextern.png b/lib/images/toolbar/linkextern.png
new file mode 100644
index 000000000..acc0c6fc5
--- /dev/null
+++ b/lib/images/toolbar/linkextern.png
Binary files differ
diff --git a/lib/images/toolbar/mono.png b/lib/images/toolbar/mono.png
new file mode 100644
index 000000000..b91ad2e0d
--- /dev/null
+++ b/lib/images/toolbar/mono.png
Binary files differ
diff --git a/lib/images/toolbar/ol.png b/lib/images/toolbar/ol.png
new file mode 100644
index 000000000..186f1fad4
--- /dev/null
+++ b/lib/images/toolbar/ol.png
Binary files differ
diff --git a/lib/images/toolbar/sig.png b/lib/images/toolbar/sig.png
new file mode 100644
index 000000000..72fdad0a0
--- /dev/null
+++ b/lib/images/toolbar/sig.png
Binary files differ
diff --git a/lib/images/toolbar/smiley.png b/lib/images/toolbar/smiley.png
new file mode 100644
index 000000000..85036c1a8
--- /dev/null
+++ b/lib/images/toolbar/smiley.png
Binary files differ
diff --git a/lib/images/toolbar/strike.png b/lib/images/toolbar/strike.png
new file mode 100644
index 000000000..e532d1f07
--- /dev/null
+++ b/lib/images/toolbar/strike.png
Binary files differ
diff --git a/lib/images/toolbar/ul.png b/lib/images/toolbar/ul.png
new file mode 100644
index 000000000..008820722
--- /dev/null
+++ b/lib/images/toolbar/ul.png
Binary files differ
diff --git a/lib/images/toolbar/underline.png b/lib/images/toolbar/underline.png
new file mode 100644
index 000000000..fa271517c
--- /dev/null
+++ b/lib/images/toolbar/underline.png
Binary files differ
diff --git a/lib/images/trash.png b/lib/images/trash.png
new file mode 100644
index 000000000..350c5e1cf
--- /dev/null
+++ b/lib/images/trash.png
Binary files differ
diff --git a/lib/images/up.png b/lib/images/up.png
new file mode 100644
index 000000000..b1eac912d
--- /dev/null
+++ b/lib/images/up.png
Binary files differ
diff --git a/lib/images/wrap.gif b/lib/images/wrap.gif
new file mode 100644
index 000000000..f2253e4a2
--- /dev/null
+++ b/lib/images/wrap.gif
Binary files differ
diff --git a/lib/index.html b/lib/index.html
new file mode 100644
index 000000000..8cb33512e
--- /dev/null
+++ b/lib/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="refresh" content="0; URL=../" />
+<meta name="robots" content="noindex" />
+<title>nothing here...</title>
+</head>
+<body>
+<!-- this is just here to prevent directory browsing -->
+</body>
+</html>
diff --git a/lib/plugins/acl/admin.php b/lib/plugins/acl/admin.php
new file mode 100644
index 000000000..c3461b78b
--- /dev/null
+++ b/lib/plugins/acl/admin.php
@@ -0,0 +1,824 @@
+<?php
+/**
+ * ACL administration functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org> (concepts)
+ * @author Frank Schubert <frank@schokilade.de> (old version)
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_acl extends DokuWiki_Admin_Plugin {
+ var $acl = null;
+ var $ns = null;
+ /**
+ * The currently selected item, associative array with id and type.
+ * Populated from (in this order):
+ * $_REQUEST['current_ns']
+ * $_REQUEST['current_id']
+ * $ns
+ * $ID
+ */
+ var $current_item = null;
+ var $who = '';
+ var $usersgroups = array();
+ var $specials = array();
+
+ /**
+ * return prompt for admin menu
+ */
+ function getMenuText($language) {
+ return $this->getLang('admin_acl');
+ }
+
+ /**
+ * return sort order for position in admin menu
+ */
+ function getMenuSort() {
+ return 1;
+ }
+
+ /**
+ * handle user request
+ *
+ * Initializes internal vars and handles modifications
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function handle() {
+ global $AUTH_ACL;
+ global $ID;
+ global $auth;
+ global $config_cascade;
+
+ // fresh 1:1 copy without replacements
+ $AUTH_ACL = file($config_cascade['acl']['default']);
+
+
+ // namespace given?
+ if($_REQUEST['ns'] == '*'){
+ $this->ns = '*';
+ }else{
+ $this->ns = cleanID($_REQUEST['ns']);
+ }
+
+ if ($_REQUEST['current_ns']) {
+ $this->current_item = array('id' => cleanID($_REQUEST['current_ns']), 'type' => 'd');
+ } elseif ($_REQUEST['current_id']) {
+ $this->current_item = array('id' => cleanID($_REQUEST['current_id']), 'type' => 'f');
+ } elseif ($this->ns) {
+ $this->current_item = array('id' => $this->ns, 'type' => 'd');
+ } else {
+ $this->current_item = array('id' => $ID, 'type' => 'f');
+ }
+
+ // user or group choosen?
+ $who = trim($_REQUEST['acl_w']);
+ if($_REQUEST['acl_t'] == '__g__' && $who){
+ $this->who = '@'.ltrim($auth->cleanGroup($who),'@');
+ }elseif($_REQUEST['acl_t'] == '__u__' && $who){
+ $this->who = ltrim($who,'@');
+ if($this->who != '%USER%'){ #keep wildcard as is
+ $this->who = $auth->cleanUser($this->who);
+ }
+ }elseif($_REQUEST['acl_t'] &&
+ $_REQUEST['acl_t'] != '__u__' &&
+ $_REQUEST['acl_t'] != '__g__'){
+ $this->who = $_REQUEST['acl_t'];
+ }elseif($who){
+ $this->who = $who;
+ }
+
+ // handle modifications
+ if(isset($_REQUEST['cmd']) && checkSecurityToken()){
+
+ // scope for modifications
+ if($this->ns){
+ if($this->ns == '*'){
+ $scope = '*';
+ }else{
+ $scope = $this->ns.':*';
+ }
+ }else{
+ $scope = $ID;
+ }
+
+ if(isset($_REQUEST['cmd']['save']) && $scope && $this->who && isset($_REQUEST['acl'])){
+ // handle additions or single modifications
+ $this->_acl_del($scope, $this->who);
+ $this->_acl_add($scope, $this->who, (int) $_REQUEST['acl']);
+ }elseif(isset($_REQUEST['cmd']['del']) && $scope && $this->who){
+ // handle single deletions
+ $this->_acl_del($scope, $this->who);
+ }elseif(isset($_REQUEST['cmd']['update'])){
+ // handle update of the whole file
+ foreach((array) $_REQUEST['del'] as $where => $names){
+ // remove all rules marked for deletion
+ foreach($names as $who)
+ unset($_REQUEST['acl'][$where][$who]);
+ }
+ // prepare lines
+ $lines = array();
+ // keep header
+ foreach($AUTH_ACL as $line){
+ if($line{0} == '#'){
+ $lines[] = $line;
+ }else{
+ break;
+ }
+ }
+ // re-add all rules
+ foreach((array) $_REQUEST['acl'] as $where => $opt){
+ foreach($opt as $who => $perm){
+ if ($who[0]=='@') {
+ if ($who!='@ALL') {
+ $who = '@'.ltrim($auth->cleanGroup($who),'@');
+ }
+ } elseif ($who != '%USER%'){ #keep wildcard as is
+ $who = $auth->cleanUser($who);
+ }
+ $who = auth_nameencode($who,true);
+ $lines[] = "$where\t$who\t$perm\n";
+ }
+ }
+ // save it
+ io_saveFile($config_cascade['acl']['default'], join('',$lines));
+ }
+
+ // reload ACL config
+ $AUTH_ACL = file($config_cascade['acl']['default']);
+ }
+
+ // initialize ACL array
+ $this->_init_acl_config();
+ }
+
+ /**
+ * ACL Output function
+ *
+ * print a table with all significant permissions for the
+ * current id
+ *
+ * @author Frank Schubert <frank@schokilade.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function html() {
+ global $ID;
+
+ echo '<div id="acl_manager">'.NL;
+ echo '<h1>'.$this->getLang('admin_acl').'</h1>'.NL;
+ echo '<div class="level1">'.NL;
+
+ echo '<div id="acl__tree">'.NL;
+ $this->_html_explorer();
+ echo '</div>'.NL;
+
+ echo '<div id="acl__detail">'.NL;
+ $this->_html_detail();
+ echo '</div>'.NL;
+ echo '</div>'.NL;
+
+ echo '<div class="clearer"></div>';
+ echo '<h2>'.$this->getLang('current').'</h2>'.NL;
+ echo '<div class="level2">'.NL;
+ $this->_html_table();
+ echo '</div>'.NL;
+
+ echo '<div class="footnotes"><div class="fn">'.NL;
+ echo '<sup><a id="fn__1" class="fn_bot" name="fn__1" href="#fnt__1">1)</a></sup>'.NL;
+ echo $this->getLang('p_include');
+ echo '</div></div>';
+
+ echo '</div>'.NL;
+ }
+
+ /**
+ * returns array with set options for building links
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _get_opts($addopts=null){
+ global $ID;
+ $opts = array(
+ 'do'=>'admin',
+ 'page'=>'acl',
+ );
+ if($this->ns) $opts['ns'] = $this->ns;
+ if($this->who) $opts['acl_w'] = $this->who;
+
+ if(is_null($addopts)) return $opts;
+ return array_merge($opts, $addopts);
+ }
+
+ /**
+ * Display a tree menu to select a page or namespace
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _html_explorer(){
+ global $conf;
+ global $ID;
+ global $lang;
+
+ $dir = $conf['datadir'];
+ $ns = $this->ns;
+ if(empty($ns)){
+ $ns = dirname(str_replace(':','/',$ID));
+ if($ns == '.') $ns ='';
+ }elseif($ns == '*'){
+ $ns ='';
+ }
+ $ns = utf8_encodeFN(str_replace(':','/',$ns));
+
+ $data = $this->_get_tree($ns);
+
+ // wrap a list with the root level around the other namespaces
+ array_unshift($data, array( 'level' => 0, 'id' => '*', 'type' => 'd',
+ 'open' =>'true', 'label' => '['.$lang['mediaroot'].']'));
+
+ echo html_buildlist($data,'acl',
+ array($this,'_html_list_acl'),
+ array($this,'_html_li_acl'));
+
+ }
+
+ /**
+ * get a combined list of media and page files
+ *
+ * @param string $folder an already converted filesystem folder of the current namespace
+ * @param string $limit limit the search to this folder
+ */
+ function _get_tree($folder,$limit=''){
+ global $conf;
+
+ // read tree structure from pages and media
+ $data = array();
+ search($data,$conf['datadir'],'search_index',array('ns' => $folder),$limit);
+ $media = array();
+ search($media,$conf['mediadir'],'search_index',array('ns' => $folder, 'nofiles' => true),$limit);
+ $data = array_merge($data,$media);
+ unset($media);
+
+ // combine by sorting and removing duplicates
+ usort($data,array($this,'_tree_sort'));
+ $count = count($data);
+ if($count>0) for($i=1; $i<$count; $i++){
+ if($data[$i-1]['id'] == $data[$i]['id'] && $data[$i-1]['type'] == $data[$i]['type']) unset($data[$i]);
+ }
+ return $data;
+ }
+
+ /**
+ * usort callback
+ *
+ * Sorts the combined trees of media and page files
+ */
+ function _tree_sort($a,$b){
+ // handle the trivial cases first
+ if ($a['id'] == '') return -1;
+ if ($b['id'] == '') return 1;
+ // split up the id into parts
+ $a_ids = explode(':', $a['id']);
+ $b_ids = explode(':', $b['id']);
+ // now loop through the parts
+ while (count($a_ids) && count($b_ids)) {
+ // compare each level from upper to lower
+ // until a non-equal component is found
+ $cur_result = strcmp(array_shift($a_ids), array_shift($b_ids));
+ if ($cur_result) {
+ // if one of the components is the last component and is a file
+ // and the other one is either of a deeper level or a directory,
+ // the file has to come after the deeper level or directory
+ if (empty($a_ids) && $a['type'] == 'f' && (count($b_ids) || $b['type'] == 'd')) return 1;
+ if (empty($b_ids) && $b['type'] == 'f' && (count($a_ids) || $a['type'] == 'd')) return -1;
+ return $cur_result;
+ }
+ }
+ // The two ids seem to be equal. One of them might however refer
+ // to a page, one to a namespace, the namespace needs to be first.
+ if (empty($a_ids) && empty($b_ids)) {
+ if ($a['type'] == $b['type']) return 0;
+ if ($a['type'] == 'f') return 1;
+ return -1;
+ }
+ // Now the empty part is either a page in the parent namespace
+ // that obviously needs to be after the namespace
+ // Or it is the namespace that contains the other part and should be
+ // before that other part.
+ if (empty($a_ids)) return ($a['type'] == 'd') ? -1 : 1;
+ if (empty($b_ids)) return ($b['type'] == 'd') ? 1 : -1;
+ }
+
+ /**
+ * Display the current ACL for selected where/who combination with
+ * selectors and modification form
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _html_detail(){
+ global $conf;
+ global $ID;
+
+ echo '<form action="'.wl().'" method="post" accept-charset="utf-8"><div class="no">'.NL;
+
+ echo '<div id="acl__user">';
+ echo $this->getLang('acl_perms').' ';
+ $inl = $this->_html_select();
+ echo '<input type="text" name="acl_w" class="edit" value="'.(($inl)?'':hsc(ltrim($this->who,'@'))).'" />'.NL;
+ echo '<input type="submit" value="'.$this->getLang('btn_select').'" class="button" />'.NL;
+ echo '</div>'.NL;
+
+ echo '<div id="acl__info">';
+ $this->_html_info();
+ echo '</div>';
+
+ echo '<input type="hidden" name="ns" value="'.hsc($this->ns).'" />'.NL;
+ echo '<input type="hidden" name="id" value="'.hsc($ID).'" />'.NL;
+ echo '<input type="hidden" name="do" value="admin" />'.NL;
+ echo '<input type="hidden" name="page" value="acl" />'.NL;
+ echo '<input type="hidden" name="sectok" value="'.getSecurityToken().'" />'.NL;
+ echo '</div></form>'.NL;
+ }
+
+ /**
+ * Print infos and editor
+ */
+ function _html_info(){
+ global $ID;
+
+ if($this->who){
+ $current = $this->_get_exact_perm();
+
+ // explain current permissions
+ $this->_html_explain($current);
+ // load editor
+ $this->_html_acleditor($current);
+ }else{
+ echo '<p>';
+ if($this->ns){
+ printf($this->getLang('p_choose_ns'),hsc($this->ns));
+ }else{
+ printf($this->getLang('p_choose_id'),hsc($ID));
+ }
+ echo '</p>';
+
+ echo $this->locale_xhtml('help');
+ }
+ }
+
+ /**
+ * Display the ACL editor
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _html_acleditor($current){
+ global $lang;
+
+ echo '<fieldset>';
+ if(is_null($current)){
+ echo '<legend>'.$this->getLang('acl_new').'</legend>';
+ }else{
+ echo '<legend>'.$this->getLang('acl_mod').'</legend>';
+ }
+
+
+ echo $this->_html_checkboxes($current,empty($this->ns),'acl');
+
+ if(is_null($current)){
+ echo '<input type="submit" name="cmd[save]" class="button" value="'.$lang['btn_save'].'" />'.NL;
+ }else{
+ echo '<input type="submit" name="cmd[save]" class="button" value="'.$lang['btn_update'].'" />'.NL;
+ echo '<input type="submit" name="cmd[del]" class="button" value="'.$lang['btn_delete'].'" />'.NL;
+ }
+
+ echo '</fieldset>';
+ }
+
+ /**
+ * Explain the currently set permissions in plain english/$lang
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _html_explain($current){
+ global $ID;
+ global $auth;
+
+ $who = $this->who;
+ $ns = $this->ns;
+
+ // prepare where to check
+ if($ns){
+ if($ns == '*'){
+ $check='*';
+ }else{
+ $check=$ns.':*';
+ }
+ }else{
+ $check = $ID;
+ }
+
+ // prepare who to check
+ if($who{0} == '@'){
+ $user = '';
+ $groups = array(ltrim($who,'@'));
+ }else{
+ $user = $who;
+ $info = $auth->getUserData($user);
+ if($info === false){
+ $groups = array();
+ }else{
+ $groups = $info['grps'];
+ }
+ }
+
+ // check the permissions
+ $perm = auth_aclcheck($check,$user,$groups);
+
+ // build array of named permissions
+ $names = array();
+ if($perm){
+ if($ns){
+ if($perm >= AUTH_DELETE) $names[] = $this->getLang('acl_perm16');
+ if($perm >= AUTH_UPLOAD) $names[] = $this->getLang('acl_perm8');
+ if($perm >= AUTH_CREATE) $names[] = $this->getLang('acl_perm4');
+ }
+ if($perm >= AUTH_EDIT) $names[] = $this->getLang('acl_perm2');
+ if($perm >= AUTH_READ) $names[] = $this->getLang('acl_perm1');
+ $names = array_reverse($names);
+ }else{
+ $names[] = $this->getLang('acl_perm0');
+ }
+
+ // print permission explanation
+ echo '<p>';
+ if($user){
+ if($ns){
+ printf($this->getLang('p_user_ns'),hsc($who),hsc($ns),join(', ',$names));
+ }else{
+ printf($this->getLang('p_user_id'),hsc($who),hsc($ID),join(', ',$names));
+ }
+ }else{
+ if($ns){
+ printf($this->getLang('p_group_ns'),hsc(ltrim($who,'@')),hsc($ns),join(', ',$names));
+ }else{
+ printf($this->getLang('p_group_id'),hsc(ltrim($who,'@')),hsc($ID),join(', ',$names));
+ }
+ }
+ echo '</p>';
+
+ // add note if admin
+ if($perm == AUTH_ADMIN){
+ echo '<p>'.$this->getLang('p_isadmin').'</p>';
+ }elseif(is_null($current)){
+ echo '<p>'.$this->getLang('p_inherited').'</p>';
+ }
+ }
+
+
+ /**
+ * Item formatter for the tree view
+ *
+ * User function for html_buildlist()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _html_list_acl($item){
+ global $ID;
+ $ret = '';
+ // what to display
+ if($item['label']){
+ $base = $item['label'];
+ }else{
+ $base = ':'.$item['id'];
+ $base = substr($base,strrpos($base,':')+1);
+ }
+
+ // highlight?
+ if( ($item['type']== $this->current_item['type'] && $item['id'] == $this->current_item['id']))
+ $cl = ' cur';
+
+ // namespace or page?
+ if($item['type']=='d'){
+ if($item['open']){
+ $img = DOKU_BASE.'lib/images/minus.gif';
+ $alt = '&minus;';
+ }else{
+ $img = DOKU_BASE.'lib/images/plus.gif';
+ $alt = '+';
+ }
+ $ret .= '<img src="'.$img.'" alt="'.$alt.'" />';
+ $ret .= '<a href="'.wl('',$this->_get_opts(array('ns'=>$item['id'],'sectok'=>getSecurityToken()))).'" class="idx_dir'.$cl.'">';
+ $ret .= $base;
+ $ret .= '</a>';
+ }else{
+ $ret .= '<a href="'.wl('',$this->_get_opts(array('id'=>$item['id'],'ns'=>'','sectok'=>getSecurityToken()))).'" class="wikilink1'.$cl.'">';
+ $ret .= noNS($item['id']);
+ $ret .= '</a>';
+ }
+ return $ret;
+ }
+
+
+ function _html_li_acl($item){
+ return '<li class="level' . $item['level'] . ' ' .
+ ($item['open'] ? 'open' : 'closed') . '">';
+ }
+
+
+ /**
+ * Get current ACL settings as multidim array
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _init_acl_config(){
+ global $AUTH_ACL;
+ global $conf;
+ $acl_config=array();
+ $usersgroups = array();
+
+ // get special users and groups
+ $this->specials[] = '@ALL';
+ $this->specials[] = '@'.$conf['defaultgroup'];
+ if($conf['manager'] != '!!not set!!'){
+ $this->specials = array_merge($this->specials,
+ array_map('trim',
+ explode(',',$conf['manager'])));
+ }
+ $this->specials = array_filter($this->specials);
+ $this->specials = array_unique($this->specials);
+ sort($this->specials);
+
+ foreach($AUTH_ACL as $line){
+ $line = trim(preg_replace('/#.*$/','',$line)); //ignore comments
+ if(!$line) continue;
+
+ $acl = preg_split('/\s+/',$line);
+ //0 is pagename, 1 is user, 2 is acl
+
+ $acl[1] = rawurldecode($acl[1]);
+ $acl_config[$acl[0]][$acl[1]] = $acl[2];
+
+ // store non-special users and groups for later selection dialog
+ $ug = $acl[1];
+ if(in_array($ug,$this->specials)) continue;
+ $usersgroups[] = $ug;
+ }
+
+ $usersgroups = array_unique($usersgroups);
+ sort($usersgroups);
+ ksort($acl_config);
+
+ $this->acl = $acl_config;
+ $this->usersgroups = $usersgroups;
+ }
+
+ /**
+ * Display all currently set permissions in a table
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _html_table(){
+ global $lang;
+ global $ID;
+
+ echo '<form action="'.wl().'" method="post" accept-charset="utf-8"><div class="no">'.NL;
+ if($this->ns){
+ echo '<input type="hidden" name="ns" value="'.hsc($this->ns).'" />'.NL;
+ }else{
+ echo '<input type="hidden" name="id" value="'.hsc($ID).'" />'.NL;
+ }
+ echo '<input type="hidden" name="acl_w" value="'.hsc($this->who).'" />'.NL;
+ echo '<input type="hidden" name="do" value="admin" />'.NL;
+ echo '<input type="hidden" name="page" value="acl" />'.NL;
+ echo '<input type="hidden" name="sectok" value="'.getSecurityToken().'" />'.NL;
+ echo '<div class="table">';
+ echo '<table class="inline">';
+ echo '<tr>';
+ echo '<th>'.$this->getLang('where').'</th>';
+ echo '<th>'.$this->getLang('who').'</th>';
+ echo '<th>'.$this->getLang('perm').'<sup><a id="fnt__1" class="fn_top" name="fnt__1" href="#fn__1">1)</a></sup></th>';
+ echo '<th>'.$lang['btn_delete'].'</th>';
+ echo '</tr>';
+ foreach($this->acl as $where => $set){
+ foreach($set as $who => $perm){
+ echo '<tr>';
+ echo '<td>';
+ if(substr($where,-1) == '*'){
+ echo '<span class="aclns">'.hsc($where).'</span>';
+ $ispage = false;
+ }else{
+ echo '<span class="aclpage">'.hsc($where).'</span>';
+ $ispage = true;
+ }
+ echo '</td>';
+
+ echo '<td>';
+ if($who{0} == '@'){
+ echo '<span class="aclgroup">'.hsc($who).'</span>';
+ }else{
+ echo '<span class="acluser">'.hsc($who).'</span>';
+ }
+ echo '</td>';
+
+ echo '<td>';
+ echo $this->_html_checkboxes($perm,$ispage,'acl['.$where.']['.$who.']');
+ echo '</td>';
+
+ echo '<td align="center">';
+ echo '<input type="checkbox" name="del['.hsc($where).'][]" value="'.hsc($who).'" />';
+ echo '</td>';
+ echo '</tr>';
+ }
+ }
+
+ echo '<tr>';
+ echo '<th align="right" colspan="4">';
+ echo '<input type="submit" value="'.$lang['btn_update'].'" name="cmd[update]" class="button" />';
+ echo '</th>';
+ echo '</tr>';
+ echo '</table>';
+ echo '</div>';
+ echo '</div></form>'.NL;
+ }
+
+
+ /**
+ * Returns the permission which were set for exactly the given user/group
+ * and page/namespace. Returns null if no exact match is available
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _get_exact_perm(){
+ global $ID;
+ if($this->ns){
+ if($this->ns == '*'){
+ $check = '*';
+ }else{
+ $check = $this->ns.':*';
+ }
+ }else{
+ $check = $ID;
+ }
+
+ if(isset($this->acl[$check][$this->who])){
+ return $this->acl[$check][$this->who];
+ }else{
+ return null;
+ }
+ }
+
+ /**
+ * adds new acl-entry to conf/acl.auth.php
+ *
+ * @author Frank Schubert <frank@schokilade.de>
+ */
+ function _acl_add($acl_scope, $acl_user, $acl_level){
+ global $config_cascade;
+ $acl_config = file_get_contents($config_cascade['acl']['default']);
+ $acl_user = auth_nameencode($acl_user,true);
+
+ // max level for pagenames is edit
+ if(strpos($acl_scope,'*') === false) {
+ if($acl_level > AUTH_EDIT) $acl_level = AUTH_EDIT;
+ }
+
+
+ $new_acl = "$acl_scope\t$acl_user\t$acl_level\n";
+
+ $new_config = $acl_config.$new_acl;
+
+ return io_saveFile($config_cascade['acl']['default'], $new_config);
+ }
+
+ /**
+ * remove acl-entry from conf/acl.auth.php
+ *
+ * @author Frank Schubert <frank@schokilade.de>
+ */
+ function _acl_del($acl_scope, $acl_user){
+ global $config_cascade;
+ $acl_config = file($config_cascade['acl']['default']);
+ $acl_user = auth_nameencode($acl_user,true);
+
+ $acl_pattern = '^'.preg_quote($acl_scope,'/').'\s+'.$acl_user.'\s+[0-8].*$';
+
+ // save all non!-matching
+ $new_config = preg_grep("/$acl_pattern/", $acl_config, PREG_GREP_INVERT);
+
+ return io_saveFile($config_cascade['acl']['default'], join('',$new_config));
+ }
+
+ /**
+ * print the permission radio boxes
+ *
+ * @author Frank Schubert <frank@schokilade.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _html_checkboxes($setperm,$ispage,$name){
+ global $lang;
+
+ static $label = 0; //number labels
+ $ret = '';
+
+ if($ispage && $setperm > AUTH_EDIT) $perm = AUTH_EDIT;
+
+ foreach(array(AUTH_NONE,AUTH_READ,AUTH_EDIT,AUTH_CREATE,AUTH_UPLOAD,AUTH_DELETE) as $perm){
+ $label += 1;
+
+ //general checkbox attributes
+ $atts = array( 'type' => 'radio',
+ 'id' => 'pbox'.$label,
+ 'name' => $name,
+ 'value' => $perm );
+ //dynamic attributes
+ if(!is_null($setperm) && $setperm == $perm) $atts['checked'] = 'checked';
+ if($ispage && $perm > AUTH_EDIT){
+ $atts['disabled'] = 'disabled';
+ $class = ' class="disabled"';
+ }else{
+ $class = '';
+ }
+
+ //build code
+ $ret .= '<label for="pbox'.$label.'" title="'.$this->getLang('acl_perm'.$perm).'"'.$class.'>';
+ $ret .= '<input '.buildAttributes($atts).' />&nbsp;';
+ $ret .= $this->getLang('acl_perm'.$perm);
+ $ret .= '</label>'.NL;
+ }
+ return $ret;
+ }
+
+ /**
+ * Print a user/group selector (reusing already used users and groups)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _html_select(){
+ global $conf;
+ $inlist = false;
+
+ if($this->who &&
+ !in_array($this->who,$this->usersgroups) &&
+ !in_array($this->who,$this->specials)){
+
+ if($this->who{0} == '@'){
+ $gsel = ' selected="selected"';
+ }else{
+ $usel = ' selected="selected"';
+ }
+ }else{
+ $usel = '';
+ $gsel = '';
+ $inlist = true;
+ }
+
+
+ echo '<select name="acl_t" class="edit">'.NL;
+ echo ' <option value="__g__" class="aclgroup"'.$gsel.'>'.$this->getLang('acl_group').':</option>'.NL;
+ echo ' <option value="__u__" class="acluser"'.$usel.'>'.$this->getLang('acl_user').':</option>'.NL;
+ if (!empty($this->specials)) {
+ echo ' <optgroup label="&nbsp;">'.NL;
+ foreach($this->specials as $ug){
+ if($ug == $this->who){
+ $sel = ' selected="selected"';
+ $inlist = true;
+ }else{
+ $sel = '';
+ }
+
+ if($ug{0} == '@'){
+ echo ' <option value="'.hsc($ug).'" class="aclgroup"'.$sel.'>'.hsc($ug).'</option>'.NL;
+ }else{
+ echo ' <option value="'.hsc($ug).'" class="acluser"'.$sel.'>'.hsc($ug).'</option>'.NL;
+ }
+ }
+ echo ' </optgroup>'.NL;
+ }
+ if (!empty($this->usersgroups)) {
+ echo ' <optgroup label="&nbsp;">'.NL;
+ foreach($this->usersgroups as $ug){
+ if($ug == $this->who){
+ $sel = ' selected="selected"';
+ $inlist = true;
+ }else{
+ $sel = '';
+ }
+
+ if($ug{0} == '@'){
+ echo ' <option value="'.hsc($ug).'" class="aclgroup"'.$sel.'>'.hsc($ug).'</option>'.NL;
+ }else{
+ echo ' <option value="'.hsc($ug).'" class="acluser"'.$sel.'>'.hsc($ug).'</option>'.NL;
+ }
+ }
+ echo ' </optgroup>'.NL;
+ }
+ echo '</select>'.NL;
+ return $inlist;
+ }
+}
diff --git a/lib/plugins/acl/ajax.php b/lib/plugins/acl/ajax.php
new file mode 100644
index 000000000..71a2eb03a
--- /dev/null
+++ b/lib/plugins/acl/ajax.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * AJAX call handler for ACL plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+//fix for Opera XMLHttpRequests
+if(!count($_POST) && !empty($HTTP_RAW_POST_DATA)){
+ parse_str($HTTP_RAW_POST_DATA, $_POST);
+}
+
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../../');
+require_once(DOKU_INC.'inc/init.php');
+//close session
+session_write_close();
+
+if(!auth_isadmin()) die('for admins only');
+if(!checkSecurityToken()) die('CRSF Attack');
+
+$ID = getID();
+
+$acl = plugin_load('admin','acl');
+$acl->handle();
+
+$ajax = $_REQUEST['ajax'];
+header('Content-Type: text/html; charset=utf-8');
+
+if($ajax == 'info'){
+ $acl->_html_info();
+}elseif($ajax == 'tree'){
+ global $conf;
+ global $ID;
+
+ $dir = $conf['datadir'];
+ $ns = $_REQUEST['ns'];
+ if($ns == '*'){
+ $ns ='';
+ }
+ $ns = cleanID($ns);
+ $lvl = count(explode(':',$ns));
+ $ns = utf8_encodeFN(str_replace(':','/',$ns));
+
+ $data = $acl->_get_tree($ns,$ns);
+
+ foreach(array_keys($data) as $item){
+ $data[$item]['level'] = $lvl+1;
+ }
+ echo html_buildlist($data, 'acl', array($acl, '_html_list_acl'),
+ array($acl, '_html_li_acl'));
+}
+
diff --git a/lib/plugins/acl/lang/af/lang.php b/lib/plugins/acl/lang/af/lang.php
new file mode 100644
index 000000000..04d9b0acf
--- /dev/null
+++ b/lib/plugins/acl/lang/af/lang.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Afrikaans language file
+ *
+ */
+$lang['page'] = 'Bladsy';
+$lang['acl_perm0'] = 'Niks';
+$lang['acl_perm1'] = 'Lees';
+$lang['acl_perm2'] = 'Verander';
+$lang['acl_perm4'] = 'Maak';
diff --git a/lib/plugins/acl/lang/ar/help.txt b/lib/plugins/acl/lang/ar/help.txt
new file mode 100644
index 000000000..70f5cf645
--- /dev/null
+++ b/lib/plugins/acl/lang/ar/help.txt
@@ -0,0 +1,11 @@
+=== مساعدة سريعة: ===
+
+على هذه الصفحة يمكنك إضافة أو إزالة الصلاحيات الخاصة بالنطاقات و الصفحات في ويكيتك.
+
+الشريط الأيسر يظهر كل النطاقات و الصفحات المتاحة.
+
+النموذج في الأسفل يمكنك من رؤية و تعديل الصلاحيات لمستخدم محدد أو مجموعة .
+
+في الجدول في الأسفل تجد قواعد التحكم بالوصول معروضة. يمكنك استخدامها لحذف أو تغيير عدة قواعد بسرعة.
+
+قراءة [[doku>acl|المستندات الرسمية عن ACL]] قد يساعدك على الفهم الكامل لطريقة عمل التحكم بالوصول في دوكو ويكي.
diff --git a/lib/plugins/acl/lang/ar/lang.php b/lib/plugins/acl/lang/ar/lang.php
new file mode 100644
index 000000000..7c05b721c
--- /dev/null
+++ b/lib/plugins/acl/lang/ar/lang.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Arabic language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Mostafa Hussein <mostafa@gmail.com>
+ * @author Yaman Hokan <always.smile.yh@hotmail.com>
+ * @author Usama Akkad <uahello@gmail.com>
+ * @author uahello@gmail.com
+ */
+$lang['admin_acl'] = 'إدارة قوائم التحكم بالدخول';
+$lang['acl_group'] = 'مجموعة';
+$lang['acl_user'] = 'مستخدم';
+$lang['acl_perms'] = 'ترخيص لـ';
+$lang['page'] = 'صفحة';
+$lang['namespace'] = 'فضاء التسمية';
+$lang['btn_select'] = 'اختيار';
+$lang['p_user_id'] = 'المستخدم<b class="acluser">%s</b> عنده حاليا الصلاحيات التالية على الصفحة<b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'المستخدم <b class="acluser">%s</b> عنده حاليا الصلاحيات التالية في النطاق<b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'أعضاء مجموعة<b class="aclgroup">%s</b> عندهم حاليا الصلاحيات التالية على الصفحة page <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'أعضاء مجموعة <b class="aclgroup">%s</b> عندهم حاليا الصلاحيات التالية في النطاق <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'رجاء <b>مستخدما أو مجموعة</b> في النموذج أعلاه لعرض أو تحرير اعداد الصلاحيات للصفحة<b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'رجاء Please <b>أدخل مستخدما أو مجموعة</b> في النموذج أعلاه لعرض أو تحرير اعداد الصلاحيات للنطاق<b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'لاحظ: هذه الصلاحيات لم تنشأ إراديا بل وُرثت من مجموعات أخرى أو نطاقات أعلى.';
+$lang['p_isadmin'] = 'لاحظ: المجموعة أو المستخدم المحدد عندهم دائما صلاحيات كاملة بسبب ضبطهم كمستخدمين متفوقين.';
+$lang['p_include'] = 'الصلاحيات الاعلى تتضمن الأخفض. صلاحيات الإنشاء ، والرفع، والحذف تطبق فقط على النطاقات، وليس على الصفحات.';
+$lang['current'] = 'قواعد ACL الحالية';
+$lang['where'] = 'الصفحة/النطاق';
+$lang['who'] = 'اسم المستخدم / المجموعة';
+$lang['perm'] = 'التصاريح';
+$lang['acl_perm0'] = 'لا يوجد';
+$lang['acl_perm1'] = 'قراءة';
+$lang['acl_perm2'] = 'تحرير';
+$lang['acl_perm4'] = 'إنشاء';
+$lang['acl_perm8'] = 'تحميل';
+$lang['acl_perm16'] = 'مسح';
+$lang['acl_new'] = 'أضف أضافة جديدة';
+$lang['acl_mod'] = 'عدل المدخلة';
diff --git a/lib/plugins/acl/lang/bg/help.txt b/lib/plugins/acl/lang/bg/help.txt
new file mode 100644
index 000000000..2de453420
--- /dev/null
+++ b/lib/plugins/acl/lang/bg/help.txt
@@ -0,0 +1,11 @@
+=== Помощ ===
+
+От тук можете да добавяте и премахвате права за именни пространства и страници във вашето Wiki.
+
+Левият панел показва всички налични именни пространства и страници.
+
+Формата отгоре ви позволява да преглеждате и променяте правата на избран потребител или група.
+
+В таблицата отдолу са показани всички актуални правила за контрол на достъпа. Можете да я ползвате за бързо изтриване или промяна на множество правила.
+
+За да разберете как работи контрола на достъпа в DokuWiki трябва да прочетете [[doku>acl|документацията относно ACL]]. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/bg/lang.php b/lib/plugins/acl/lang/bg/lang.php
new file mode 100644
index 000000000..e260be918
--- /dev/null
+++ b/lib/plugins/acl/lang/bg/lang.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * bulgarian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Nikolay Vladimirov <nikolay@vladimiroff.com>
+ * @author Viktor Usunov <usun0v@mail.bg>
+ * @author Kiril <neohidra@gmail.com>
+ */
+$lang['admin_acl'] = 'Управление на списъците за достъп';
+$lang['acl_group'] = 'Група';
+$lang['acl_user'] = 'Потребител';
+$lang['acl_perms'] = 'Права за';
+$lang['page'] = 'Страница';
+$lang['namespace'] = 'Именно пространство';
+$lang['btn_select'] = 'Избери';
+$lang['p_user_id'] = 'Потребителят <b class="acluser">%s</b> в момента има следните права за страницата <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Потребителят <b class="acluser">%s</b> в момента има следните права за именното пространство <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Членовете на групата <b class="aclgroup">%s</b> в момента имат следните права за страницата <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Членовете на групата <b class="aclgroup">%s</b> в момента имат следните права за именното пространство <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Моля, <b>въведете потребител или група</b> в полето отгоре, за да видите или промените правата за страницата <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Моля, <b>въведете потребител или група</b> в полето отгоре, за да видите или промените правата за именното пространство <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Бележка: Тези разрешения не са зададени директно, а са наследени от други групи или именни пространства.';
+$lang['p_isadmin'] = 'Бележка: Избраната група или потребител има всички права, защото е определен за супер потребител.';
+$lang['p_include'] = 'Висши права включват по-нисшите такива. Правата за създаване, качване и изтриване са приложими само за именни пространства, но не за страници.';
+$lang['current'] = 'Текущи ACL права';
+$lang['where'] = 'Страница/Именно пространство';
+$lang['who'] = 'Потребител/Група';
+$lang['perm'] = 'Права';
+$lang['acl_perm0'] = 'Никакви';
+$lang['acl_perm1'] = 'Четене';
+$lang['acl_perm2'] = 'Редактиране';
+$lang['acl_perm4'] = 'Създаване';
+$lang['acl_perm8'] = 'Качване';
+$lang['acl_perm16'] = 'Изтриване';
+$lang['acl_new'] = 'Добавяне на право';
+$lang['acl_mod'] = 'Промяна на записа';
diff --git a/lib/plugins/acl/lang/ca-valencia/help.txt b/lib/plugins/acl/lang/ca-valencia/help.txt
new file mode 100644
index 000000000..87450d2fa
--- /dev/null
+++ b/lib/plugins/acl/lang/ca-valencia/help.txt
@@ -0,0 +1,15 @@
+=== Ajuda ràpida: ===
+
+En esta pàgina pot afegir i llevar permissos per a espais de noms i
+pàgines del wiki.
+
+El panel esquerre mostra tots els espais de noms i pàgines disponibles.
+
+El formulari de dalt permet vore i modificar els permissos de l'usuari
+o grup seleccionat.
+
+En la taula de baix es mostren totes les regles d'accés actuals. Pot
+usar-la per a canviar o borrar ràpidament vàries regles.
+
+Llegint la [[doku>acl|documentació oficial sobre ACL]] podrà
+comprendre millor com funciona el control d'accés en DokuWiki.
diff --git a/lib/plugins/acl/lang/ca-valencia/lang.php b/lib/plugins/acl/lang/ca-valencia/lang.php
new file mode 100644
index 000000000..ef0ae92eb
--- /dev/null
+++ b/lib/plugins/acl/lang/ca-valencia/lang.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * valencian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Bernat Arlandis i Mañó <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@llenguaitecnologia.com>
+ */
+$lang['admin_acl'] = 'Gestor de les llistes de control d\'accés';
+$lang['acl_group'] = 'Grup';
+$lang['acl_user'] = 'Usuari';
+$lang['acl_perms'] = 'Permissos per a';
+$lang['page'] = 'Pàgina';
+$lang['namespace'] = 'Espai de noms';
+$lang['btn_select'] = 'Seleccionar';
+$lang['p_user_id'] = 'L\'usuari <b class="acluser">%s</b> té actualment els següents permissos en la pàgina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'L\'usuari <b class="acluser">%s</b> té actualment els següents permissos en l\'espai de noms <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Els membres del grup <b class="aclgroup">%s</b> tenen actualment els següents permissos en la pàgina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Els membres del grup <b class="aclgroup">%s</b> tenen actualment els següents permissos en l\'espai de noms <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Per favor, <b>introduïxca un usuari o grup</b> en el formulari de dalt per a vore o editar els per a la pàgina <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Per favor, <b>introduïxca un usuari o grup</b> en el formulari de dalt per a vore o editar els permissos per a l\'espai de noms <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Nota: estos permissos no s\'han indicat explícitament sino que s\'hereten d\'atres grups o d\'espais de noms antecessors.';
+$lang['p_isadmin'] = 'Nota: el grup o usuari seleccionat té sempre tots els permissos perque està configurat com a super-usuari.';
+$lang['p_include'] = 'Els permissos més alts inclouen als més baixos. Els permissos per a crear, enviar i borrar només valen per a espais de noms, pàgines no.';
+$lang['current'] = 'Regles ACL actuals';
+$lang['where'] = 'Pàgina/espai de noms';
+$lang['who'] = 'Usuari/grup';
+$lang['perm'] = 'Permissos';
+$lang['acl_perm0'] = 'Cap';
+$lang['acl_perm1'] = 'Llegir';
+$lang['acl_perm2'] = 'Editar';
+$lang['acl_perm4'] = 'Crear';
+$lang['acl_perm8'] = 'Pujar';
+$lang['acl_perm16'] = 'Borrar';
+$lang['acl_new'] = 'Afegir entrada nova';
+$lang['acl_mod'] = 'Modificar entrada';
diff --git a/lib/plugins/acl/lang/ca/help.txt b/lib/plugins/acl/lang/ca/help.txt
new file mode 100644
index 000000000..d9bcc126d
--- /dev/null
+++ b/lib/plugins/acl/lang/ca/help.txt
@@ -0,0 +1,11 @@
+=== Ajuda ràpida ===
+
+En aquesta pàgina podeu afegir i treure permisos per a espais i pàgines del vostre wiki.
+
+La subfinestra de l'esquerra mostra tots els espais i pàgines disponibles.
+
+El formulari de dalt us permet veure i modificar els permisos de l'usuari o grup que seleccioneu.
+
+En la taula de baix es mostren totes les regles de control d'accés que hagin estat definides. Podeu utilitzar aquesta taula per suprimir o modificar ràpidament totes les regles que vulgueu.
+
+Llegir la [[doku>acl|documentació oficial sobre ACL]] us pot ajudar a entendre del tot com funciona el control d'accés en DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/ca/lang.php b/lib/plugins/acl/lang/ca/lang.php
new file mode 100644
index 000000000..10f656062
--- /dev/null
+++ b/lib/plugins/acl/lang/ca/lang.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * catalan language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Carles Bellver <carles.bellver@cent.uji.es>
+ * @author Carles Bellver <carles.bellver@gmail.com>
+ * @author carles.bellver@gmail.com
+ * @author carles.bellver@cent.uji.es
+ */
+$lang['admin_acl'] = 'Gestió de la Llista de Control d\'Accés';
+$lang['acl_group'] = 'Grup';
+$lang['acl_user'] = 'Usuari';
+$lang['acl_perms'] = 'Permisos per a';
+$lang['page'] = 'Pàgina';
+$lang['namespace'] = 'Espai';
+$lang['btn_select'] = 'Selecciona';
+$lang['p_user_id'] = 'L\'usuari <b class="acluser">%s</b> té a hores d\'ara els permisos següents en la pàgina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'L\'usuari <b class="acluser">%s</b> té a hores d\'ara els permisos següents en l\'espai <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Els membres del grup <b class="aclgroup">%s</b> tenen a hores d\'ara els permisos següents en la pàgina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Els membres del grup <b class="aclgroup">%s</b> tenen a hores d\'ara els permisos següents en l\'espai <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = '<b>Introduïu un usuari o grup</b> en el formulari de dalt per veure o editar els seus permisos en la pàgina <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = '<b>Introduïu un usuari o grup</b> en el formulari de dalt per veure o editar els seus permisos en l\'espai <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Nota: aquests permisos no s\'han definit explícitament, sinó que són heretats d\'altres grups o d\'espais d\'ordre superior.';
+$lang['p_isadmin'] = 'Nota: l\'usuari o grup seleccionat té sempre tots els permisos perquè ha estat configurat com a superusuari.';
+$lang['p_include'] = 'Els permisos més alts inclouen tots els permisos inferiors. Els permisos per a crear, penjar i suprimir només s\'apliquen als espais, no a pàgines.';
+$lang['current'] = 'Regles ACL actuals';
+$lang['where'] = 'Pàgina/espai';
+$lang['who'] = 'Usuari/grup';
+$lang['perm'] = 'Permisos';
+$lang['acl_perm0'] = 'Cap';
+$lang['acl_perm1'] = 'Lectura';
+$lang['acl_perm2'] = 'Edició';
+$lang['acl_perm4'] = 'Creació';
+$lang['acl_perm8'] = 'Penjar fitxers';
+$lang['acl_perm16'] = 'Suprimir';
+$lang['acl_new'] = 'Afegeix nova entrada';
+$lang['acl_mod'] = 'Modifica entrada';
diff --git a/lib/plugins/acl/lang/cs/help.txt b/lib/plugins/acl/lang/cs/help.txt
new file mode 100644
index 000000000..1dbc88ad0
--- /dev/null
+++ b/lib/plugins/acl/lang/cs/help.txt
@@ -0,0 +1,11 @@
+=== Nápověda: ===
+
+Na této stránce můžete přidávat a odebírat oprávnění na jmenné prostory a stránky Vaší wiki.
+
+Levý panel zobrazuje všechny dostupné jmenné prostory a stránky.
+
+Formulář výše umožňuje vidět a modifikovat oprávnění vybraného uživatele nebo skupiny.
+
+V tabulce uvedené níže jsou zobrazeny všechny aktuální pravidla pro řízení přístupu (oprávnění). Zde můžete rychle odebírat a měnit více položek (oprávnění) najednou.
+
+Pro detailnější nápovědu si přečtěte stránku [[doku>acl|oficiální dokumentaci ACL]], která Vám může pomoci plně pochopit princip, jak řízení přístupu na DokuWiki funguje.
diff --git a/lib/plugins/acl/lang/cs/lang.php b/lib/plugins/acl/lang/cs/lang.php
new file mode 100644
index 000000000..cc1d97023
--- /dev/null
+++ b/lib/plugins/acl/lang/cs/lang.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Czech language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Bohumir Zamecnik <bohumir@zamecnik.org>
+ * @author Zbynek Krivka <zbynek.krivka@seznam.cz>
+ * @author tomas@valenta.cz
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @author Lefty <lefty@multihost.cz>
+ * @author Vojta Beran <xmamut@email.cz>
+ * @author zbynek.krivka@seznam.cz
+ */
+$lang['admin_acl'] = 'Správa přístupových práv';
+$lang['acl_group'] = 'Skupina';
+$lang['acl_user'] = 'Uživatel';
+$lang['acl_perms'] = 'Práva pro';
+$lang['page'] = 'Stránka';
+$lang['namespace'] = 'Jmenný prostor';
+$lang['btn_select'] = 'Vybrat';
+$lang['p_user_id'] = 'Uživatel <b class="acluser">%s</b> má nyní na stránku <b class="aclpage">%s</b> následující oprávnění: <i>%s</i>.';
+$lang['p_user_ns'] = 'Uživatel <b class="acluser">%s</b> má nyní na jmenný prostor <b class="aclns">%s</b> následující oprávnění: <i>%s</i>.';
+$lang['p_group_id'] = 'Členové skupiny <b class="aclgroup">%s</b> mají nyní na stránku <b class="aclpage">%s</b> následující oprávnění: <i>%s</i>.';
+$lang['p_group_ns'] = 'Členové skupiny <b class="aclgroup">%s</b> mají nyní na jmenný prostor <b class="aclns">%s</b> následující oprávnění: <i>%s</i>.';
+$lang['p_choose_id'] = 'Prosím, <b>vložte uživatele nebo skupinu</b> ve formě uvedené výše, abyste mohli prohlížet a editovat množinu oprávnění pro stránku <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Prosím, <b>vložte uživatele nebo skupinu</b> ve formě uvedené výše, abyste mohli prohlížet a editovat množinu oprávnění pro jmenný prostor <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Poznámka: Tato oprávnění nebyla nastavena explicitně, ale jsou zděděna z jiné skupiny nebo z nadřazeného jmenného prostoru.';
+$lang['p_isadmin'] = 'Poznámka: Vybraná skupina nebo uživatel má vždy plná oprávnění, protože je nastaven jako správce (superuser).';
+$lang['p_include'] = 'Vyšší oprávnění zahrnují nižší oprávnění. Vytvořit, Nahrát a Smazat se vztahují jen k jmenným prostorů, nikoliv ke stránkám.';
+$lang['current'] = 'Aktuální ACL pravidla';
+$lang['where'] = 'Stránka/Jmenný prostor';
+$lang['who'] = 'Uživatel/Skupina';
+$lang['perm'] = 'Oprávnění';
+$lang['acl_perm0'] = 'Žádné';
+$lang['acl_perm1'] = 'Čtení';
+$lang['acl_perm2'] = 'Úpravy';
+$lang['acl_perm4'] = 'Vytvoření';
+$lang['acl_perm8'] = 'Upload';
+$lang['acl_perm16'] = 'Mazání';
+$lang['acl_new'] = 'Přidat novou položku';
+$lang['acl_mod'] = 'Editovat položku';
diff --git a/lib/plugins/acl/lang/da/help.txt b/lib/plugins/acl/lang/da/help.txt
new file mode 100644
index 000000000..c8eedfc48
--- /dev/null
+++ b/lib/plugins/acl/lang/da/help.txt
@@ -0,0 +1,11 @@
+=== Vejledning ===
+
+På denne side kan du tilføje og fjerne tilladelser for navnerum og sider i din wiki.
+
+Panelet i venstre side viser alle tilgængelige navnerum og sider.
+
+I kassen for oven giver dig mulighed for at se og ændre tilladelser for en bestemt bruger eller gruppe.
+
+Nedenstående skema viser dig alle de satte regler for adgangskontrol. Du kan bruge den til hurtigt at slette eller ændre nogle af dem.
+
+Ved at læse [[doku>acl|den officielle vejledning til ACL]] kan du opnå yderligere hjælp til at blive sat helt ind i, hvordan adgangskontrol virker i DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/da/lang.php b/lib/plugins/acl/lang/da/lang.php
new file mode 100644
index 000000000..f82098dee
--- /dev/null
+++ b/lib/plugins/acl/lang/da/lang.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Danish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author koeppe <koeppe@kazur.dk>
+ * @author Jon Bendtsen <bendtsen@diku.dk>
+ * @author Lars Næsbye Christensen <larsnaesbye@stud.ku.dk>
+ * @author Kalle Sommer Nielsen <kalle@php.net>
+ * @author Esben Laursen <hyber@hyber.dk>
+ * @author Harith <haj@berlingske.dk>
+ * @author Daniel Ejsing-Duun <dokuwiki@zilvador.dk>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author rasmus@kinnerup.com
+ * @author Michael Pedersen subben@gmail.com
+ */
+$lang['admin_acl'] = 'Rettighedsadministration';
+$lang['acl_group'] = 'Gruppe';
+$lang['acl_user'] = 'Bruger';
+$lang['acl_perms'] = 'Rettigheder for';
+$lang['page'] = 'Dokument';
+$lang['namespace'] = 'Navnerum';
+$lang['btn_select'] = 'Vælg';
+$lang['p_user_id'] = 'Bruger <b class="acluser">%s</b> har følgende adgang på siden <b class="aclpage">%s</b>: <i>%s</i>';
+$lang['p_user_ns'] = 'Bruger <b class="acluser">%s</b> har foreløbig følgende tilladelse i navnerummet <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Medlemmerne af gruppen <b class="aclgroup">%s</b> har foreløbigt de følgende tilladelser på siden <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Medlemmerne af gruppen <b class="aclgroup">%s</b> har foreløbigt de følgende tilladelser i navnerummet <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Venligst <b>udfyld en bruger eller gruppe</b> i ovennævnte formular for at se eller redigere tilladelserne for denne side<b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Venligst <b>udfyld en bruger eller gruppe</b> i ovennævnte formular for at se eller redigere tilladelserne for navnerummet <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Bemærk: Disse tilladelser var ikke lagt entydigt ind, men var arvet fra andre grupper eller højere navnerum.';
+$lang['p_isadmin'] = 'Bemærk: Den valgte gruppe eller bruger har altid fuld adgang, fordi den er sat til at være en supergruppe eller -bruger';
+$lang['p_include'] = 'Højere tilladelse inkluderer også lavere. Tilladelser til at oprette, lægge filer op og slette gælder kun for navnerum, ikke sider.';
+$lang['current'] = 'Aktuelle ACL-regler';
+$lang['where'] = 'Side/navnerum';
+$lang['who'] = 'Bruger/gruppe';
+$lang['perm'] = 'Rettigheder';
+$lang['acl_perm0'] = 'Ingen';
+$lang['acl_perm1'] = 'Læs';
+$lang['acl_perm2'] = 'Skriv';
+$lang['acl_perm4'] = 'Opret';
+$lang['acl_perm8'] = 'Overføre';
+$lang['acl_perm16'] = 'Slet';
+$lang['acl_new'] = 'Tilføj ny post';
+$lang['acl_mod'] = 'Ændre post';
diff --git a/lib/plugins/acl/lang/de-informal/help.txt b/lib/plugins/acl/lang/de-informal/help.txt
new file mode 100644
index 000000000..d7930f8df
--- /dev/null
+++ b/lib/plugins/acl/lang/de-informal/help.txt
@@ -0,0 +1,11 @@
+=== Schnellhilfe ===
+
+Auf dieser Seite kannst Du Rechte für Namensräume und Seiten in deinem Wiki hinzufügen oder entfernen.
+
+Der linke Bereich zeigt alle Namensräume und Seiten.
+
+Das obere Formular zeigt die die Rechte der ausgewählten Gruppe bzw. Benutzers.
+
+In der Tabelle unten werden alle momentan gesetzten Zugriffsregeln gezeigt. Hier kannst Du schnell mehrere Regeln löschen oder ändern.
+
+Das Lesen von [[doku>acl|official documentation on ACL]] kann Dir helfen zu verstehen, wie die Zugriffskontrole in DokuWiki funktioniert.
diff --git a/lib/plugins/acl/lang/de-informal/lang.php b/lib/plugins/acl/lang/de-informal/lang.php
new file mode 100644
index 000000000..3f4b08c2a
--- /dev/null
+++ b/lib/plugins/acl/lang/de-informal/lang.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * German (informal) language file
+ *
+ * @author Alexander Fischer <tbanus@os-forge.net>
+ * @author Juergen Schwarzer <jschwarzer@freenet.de>
+ * @author Marcel Metz <marcel_metz@gmx.de>
+ * @author Matthias Schulte <post@lupo49.de>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['admin_acl'] = 'Zugriffskontrollsystem Management';
+$lang['acl_group'] = 'Gruppe';
+$lang['acl_user'] = 'Benutzer';
+$lang['acl_perms'] = 'Rechte für';
+$lang['page'] = 'Seite';
+$lang['namespace'] = 'Namensraum';
+$lang['btn_select'] = 'Auswählen';
+$lang['p_user_id'] = 'Benutzer <b class="acluser">%s</b> hat im Moment folgende Rechte auf der Seite <b class="aclpage">%s</b>: <i>%s</i>';
+$lang['p_user_ns'] = 'Benutzer <b class="acluser">%s</b> hat momentan die folgenden Rechte im Namensraum <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Die Gruppenmitglieder <b class="aclgroup">%s</b> haben momentan die folgenden Rechte auf der Seite <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Die Mitglieder der Gruppe <b class="aclgroup">%s</b> haben gerade Zugriff in folgenden Namensräumen <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Bitte <b>gib einen Nutzer oder eine Gruppe</b> in das Formular ein, um die Berechtigungen der Seite <b class="aclpage">%s</b> anzusehen oder zu bearbeiten.';
+$lang['p_choose_ns'] = 'Bitte <b>gib einen Nutzer oder eine Gruppe</b> in das Formular ein, um die Berechtigungen des Namenraumes <b class="aclpage">%s</b> anzusehen oder zu bearbeiten.';
+$lang['p_inherited'] = 'Hinweis: Diese Rechte wurden nicht explizit gesetzt, sondern von anderen Gruppen oder übergeordneten Namensräumen geerbt.';
+$lang['p_isadmin'] = 'Hinweis: Die gewählte Gruppe oder der Benutzer haben immer die vollen Rechte, weil sie als Superuser konfiguriert sind.';
+$lang['p_include'] = 'Höhere Rechte schließen kleinere mit ein. Hochlade- und Löschrechte sind nur für Namensräume, nicht für Seiten.';
+$lang['current'] = 'Momentane Zugriffsregeln';
+$lang['where'] = 'Seite/Namensraum';
+$lang['who'] = 'Benutzer/Gruppe';
+$lang['perm'] = 'Rechte';
+$lang['acl_perm0'] = 'Keine';
+$lang['acl_perm1'] = 'Lesen';
+$lang['acl_perm2'] = 'Bearbeiten';
+$lang['acl_perm4'] = 'Erstellen';
+$lang['acl_perm8'] = 'Hochladen';
+$lang['acl_perm16'] = 'Löschen';
+$lang['acl_new'] = 'Neuen Eintrag zufügen';
+$lang['acl_mod'] = 'Eintrag modifizieren';
diff --git a/lib/plugins/acl/lang/de/help.txt b/lib/plugins/acl/lang/de/help.txt
new file mode 100644
index 000000000..783ae22e7
--- /dev/null
+++ b/lib/plugins/acl/lang/de/help.txt
@@ -0,0 +1,11 @@
+=== Kurzhilfe ===
+
+Auf dieser Seite können sie Zugriffsberechtigungen für Seiten und Namensräume festlegen und ändern.
+
+Die Liste links zeigt alle verfügbaren Namensräume und Seiten.
+
+Das Formular oben erlaubt Anzeige, Ändern und Hinzufügen von Zugriffsregeln für einen ausgewählten Nutzer oder eine Gruppe.
+
+In der Tabelle unten werden alle bestehenden Regeln aufgeführt und können dort modifiziert oder gelöscht werden.
+
+Für ein tiefergehendes Verständnis wie Zugriffsbeschränkungen in DokuWiki funktionieren, sollten Sie die [[doku>acl|offizielle Dokumentation]] lesen. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/de/lang.php b/lib/plugins/acl/lang/de/lang.php
new file mode 100644
index 000000000..eb23636c4
--- /dev/null
+++ b/lib/plugins/acl/lang/de/lang.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * german language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Christof <gagi@fin.de>
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Esther Brunner <esther@kaffeehaus.ch>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Dirk Einecke <dirk@dirkeinecke.de>
+ * @author Blitzi94@gmx.de
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Niels Lange <niels@boldencursief.nl>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Paul Lachewsky <kaeptn.haddock@gmail.com>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['admin_acl'] = 'Zugangsverwaltung';
+$lang['acl_group'] = 'Gruppe';
+$lang['acl_user'] = 'Benutzer';
+$lang['acl_perms'] = 'Berechtigungen für';
+$lang['page'] = 'Seite';
+$lang['namespace'] = 'Namensraum';
+$lang['btn_select'] = 'Auswählen';
+$lang['p_user_id'] = 'Nutzer <b class="acluser">%s</b> hat momentan folgende Berechtigungen für die Seite <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Nutzer <b class="acluser">%s</b> hat momentan folgende Berechtigungen im Namensraum <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Mitglieder der Gruppe <b class="aclgroup">%s</b> haben momentan folgende Berechtigungen für die Seite <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Mitglieder der Gruppe <b class="aclgroup">%s</b> haben momentan folgende Berechtigungen für den Namensraum <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Bitte geben Sie in obigem Formular eine <b>einen Nutzer oder eine Gruppe</b> an, um die Berechtigungen für die Seite <b class="aclpage">%s</b> zu sehen oder zu ändern.';
+$lang['p_choose_ns'] = 'Bitte geben Sie in obigem Formular eine <b>einen Nutzer oder eine Gruppe</b> an, um die Berechtigungen für den Namensraum <b class="aclns">%s</b> zu sehen oder zu ändern.';
+$lang['p_inherited'] = 'Hinweis: Diese Berechtigungen wurden nicht explizit gesetzt, sondern von anderen Gruppen oder höher liegenden Namensräumen geerbt.';
+$lang['p_isadmin'] = 'Hinweis: Die ausgewählte Gruppe oder Nutzer haben immer alle Berechtigungen das sie als Superuser konfiguriert wurden.';
+$lang['p_include'] = 'Höhere Berechtigungen schließen niedrigere mit ein. Anlegen, Hochladen und Entfernen gilt nur für Namensräume, nicht für einzelne Seiten';
+$lang['current'] = 'Momentane Zugriffsregeln';
+$lang['where'] = 'Seite/Namensraum';
+$lang['who'] = 'Nutzer/Gruppe';
+$lang['perm'] = 'Berechtigungen';
+$lang['acl_perm0'] = 'Keine';
+$lang['acl_perm1'] = 'Lesen';
+$lang['acl_perm2'] = 'Bearbeiten';
+$lang['acl_perm4'] = 'Anlegen';
+$lang['acl_perm8'] = 'Hochladen';
+$lang['acl_perm16'] = 'Entfernen';
+$lang['acl_new'] = 'Eintrag hinzufügen';
+$lang['acl_mod'] = 'Eintrag bearbeiten';
diff --git a/lib/plugins/acl/lang/el/help.txt b/lib/plugins/acl/lang/el/help.txt
new file mode 100644
index 000000000..ea2f816c0
--- /dev/null
+++ b/lib/plugins/acl/lang/el/help.txt
@@ -0,0 +1,10 @@
+=== Γρήγορη Βοήθεια: ===
+
+Στη σελίδα αυτή μπορείτε να προσθέσετε και αφαιρέσετε δικαιώματα πρόσβασης για φακέλους και σελίδες στο wiki σας.
+
+Το αριστερό πλαίσιο δείχνει όλους τους διαθέσιμους φακέλους και αρχεία.
+
+Η παραπάνω φόρμα επιτρέπει να δείτε και να τροποποιήσετε τα διακαιώματα μίας επιλεγμένης ομάδας χρηστών ή ενός χρήστη.
+
+Στον παρακάτω πίνακα εμφανίζονται όλοι οι τρέχοντες κανόνες παραχώρησης δικαιωμάτων πρόσβασης. Μπορείτε να τον χρησιμοποιήσετε ώστε να σβήσετε ή να τροποποιήσετε γρήγορα πολλαπλούς κανόνες.
+Διαβάζοντας την [[doku>acl|επίσημη τεκμηρίωση για τις Λίστες Δικαιωμάτων Πρόσβασης - ACL]] ίσως σας βοηθήσει να καταλάβετε πλήρως το πως αυτές εφαρμόζονται στην DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/el/lang.php b/lib/plugins/acl/lang/el/lang.php
new file mode 100644
index 000000000..e1cd26755
--- /dev/null
+++ b/lib/plugins/acl/lang/el/lang.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Greek language file
+ *
+ * Based on DokuWiki Version rc2007-05-24 english language file
+ * Original english language file contents included for reference
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author Thanos Massias <tm@thriasio.gr>
+ * @author Αθανάσιος Νταής <homunculus@wana.gr>
+ * @author Konstantinos Koryllos <koryllos@gmail.com>
+ * @author George Petsagourakis <petsagouris@gmail.com>
+ * @author Petros Vidalis <pvidalis@gmail.com>
+ */
+$lang['admin_acl'] = 'Διαχείριση Δικαιωμάτων Πρόσβασης';
+$lang['acl_group'] = 'Ομάδα';
+$lang['acl_user'] = 'Χρήστης';
+$lang['acl_perms'] = 'Δικαιώματα για';
+$lang['page'] = 'Σελίδα';
+$lang['namespace'] = 'Φάκελος';
+$lang['btn_select'] = 'Επιλογή';
+$lang['p_user_id'] = 'Ο χρήστης <b class="acluser">%s</b> έχει τα ακόλουθα δικαιώματα πρόσβασης στην σελίδα <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Ο χρήστης <b class="acluser">%s</b> έχει τα ακόλουθα δικαιώματα πρόσβασης στον φάκελο <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Τα μέλη της ομάδας <b class="aclgroup">%s</b> έχουν τα ακόλουθα δικαιώματα πρόσβασης στην σελίδα <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Τα μέλη της ομάδας <b class="aclgroup">%s</b> έχουν τα ακόλουθα δικαιώματα πρόσβασης στον φάκελο <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Παρακαλώ <b>δώστε ένα όνομα χρήστη ή ομάδας χρηστών</b> στην παραπάνω μορφή για να δείτε τα αντίστοιχα δικαιώματα πρόσβασης για την σελίδα <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Παρακαλώ <b>δώστε ένα όνομα χρήστη ή ομάδας χρηστών</b> στην παραπάνω μορφή για να δείτε τα αντίστοιχα δικαιώματα πρόσβασης για τον φάκελο <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Σημείωση: Αυτά τα διακαιώματα χρήσης δεν ορίστηκαν άμεσα αλλά κληρονομήθηκαν από άλλες ομάδες χρηστών ή φακέλους σε υψηλότερο επίπεδο.';
+$lang['p_isadmin'] = 'Σημείωση: Η επιλεγμένη ομάδα χρηστών ή χρήστης έχει πάντα πλήρη διακαιώματα πρόσβασης διότι είναι δηλωμένος σαν υπερχρήστης (superuser).';
+$lang['p_include'] = 'Τα υψηλότερα δικαιώματα πρόσβασης περιλαμβάνουν τα χαμηλότερα. Τα δικαιώματα για Δημιουργία, Φόρτωση και Διαγραφή αφορούν μόνο φακέλους και όχι σελίδες. ';
+$lang['current'] = 'Τρέχοντες κανόνες Λίστας Δικαιωμάτων Πρόσβασης - ACL';
+$lang['where'] = 'Σελίδα/Φάκελος';
+$lang['who'] = 'Χρήστης/Ομάδα χρηστών';
+$lang['perm'] = 'Δικαιώματα πρόσβασης';
+$lang['acl_perm0'] = 'Κανένα';
+$lang['acl_perm1'] = 'Ανάγνωση';
+$lang['acl_perm2'] = 'Τροποποίηση';
+$lang['acl_perm4'] = 'Δημιουργία';
+$lang['acl_perm8'] = 'Φόρτωση';
+$lang['acl_perm16'] = 'Διαγραφή';
+$lang['acl_new'] = 'Προσθήκη νέας εγγραφής';
+$lang['acl_mod'] = 'Τροποποίηση εγγραφής';
diff --git a/lib/plugins/acl/lang/en/help.txt b/lib/plugins/acl/lang/en/help.txt
new file mode 100644
index 000000000..2b80cc4c7
--- /dev/null
+++ b/lib/plugins/acl/lang/en/help.txt
@@ -0,0 +1,12 @@
+=== Quick Help: ===
+
+On this page you can add and remove permissions for namespaces and pages in your wiki.
+
+The left pane displays all available namespaces and pages.
+
+The form above allows you to see and modify the permissions of a selected user or group.
+
+In the table below all currently set access control rules are shown. You can use it to quickly delete or change multiple rules.
+
+Reading the [[doku>acl|official documentation on ACL]] might help you to fully understand how access control works in DokuWiki.
+
diff --git a/lib/plugins/acl/lang/en/lang.php b/lib/plugins/acl/lang/en/lang.php
new file mode 100644
index 000000000..779614d32
--- /dev/null
+++ b/lib/plugins/acl/lang/en/lang.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * english language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+
+$lang['admin_acl'] = 'Access Control List Management';
+$lang['acl_group'] = 'Group';
+$lang['acl_user'] = 'User';
+$lang['acl_perms'] = 'Permissions for';
+$lang['page'] = 'Page';
+$lang['namespace'] = 'Namespace';
+
+$lang['btn_select'] = 'Select';
+
+$lang['p_user_id'] = 'User <b class="acluser">%s</b> currently has the following permissions on page <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'User <b class="acluser">%s</b> currently has the following permissions in namespace <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Members of group <b class="aclgroup">%s</b> currently have the following permissions on page <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Members of group <b class="aclgroup">%s</b> currently have the following permissions in namespace <b class="aclns">%s</b>: <i>%s</i>.';
+
+$lang['p_choose_id'] = 'Please <b>enter a user or group</b> in the form above to view or edit the permissions set for the page <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Please <b>enter a user or group</b> in the form above to view or edit the permissions set for the namespace <b class="aclns">%s</b>.';
+
+
+$lang['p_inherited'] = 'Note: Those permissions were not set explicitly but were inherited from other groups or higher namespaces.';
+$lang['p_isadmin'] = 'Note: The selected group or user has always full permissions because it is configured as superuser.';
+$lang['p_include'] = 'Higher permissions include lower ones. Create, Upload and Delete permissions only apply to namespaces, not pages.';
+
+$lang['current'] = 'Current ACL Rules';
+$lang['where'] = 'Page/Namespace';
+$lang['who'] = 'User/Group';
+$lang['perm'] = 'Permissions';
+
+$lang['acl_perm0'] = 'None';
+$lang['acl_perm1'] = 'Read';
+$lang['acl_perm2'] = 'Edit';
+$lang['acl_perm4'] = 'Create';
+$lang['acl_perm8'] = 'Upload';
+$lang['acl_perm16'] = 'Delete';
+$lang['acl_new'] = 'Add new Entry';
+$lang['acl_mod'] = 'Modify Entry';
+//Setup VIM: ex: et ts=2 :
diff --git a/lib/plugins/acl/lang/eo/help.txt b/lib/plugins/acl/lang/eo/help.txt
new file mode 100644
index 000000000..cc3f63e5a
--- /dev/null
+++ b/lib/plugins/acl/lang/eo/help.txt
@@ -0,0 +1,11 @@
+=== Helpeto: ===
+
+En tiu ĉi paĝo vi povas aldoni kaj forigi rajtojn por nomspacoj kaj paĝoj en via vikio.
+
+La maldekstra panelo montras ĉiujn disponeblajn nomspacojn kaj paĝojn.
+
+La suba agordilo permesas al vi rigardi kaj modifi la rajtojn de elektita uzanto aŭ grupo.
+
+En la suba tabelo ĉiuj aktuale difinitaj alirkontrolaj reguloj estas montritaj. Vi povas uzi ĝin por rapide forigi aŭ ŝanĝi multoblajn regulojn.
+
+Legado de la [[doku&gt;acl|oficiala dokumentaro pri ACL]] povus helpi vin bone kompreni kiel alirkontrolo funkcias en DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/eo/lang.php b/lib/plugins/acl/lang/eo/lang.php
new file mode 100644
index 000000000..72ce576ee
--- /dev/null
+++ b/lib/plugins/acl/lang/eo/lang.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Esperantolanguage file
+ *
+ * @author Felipe Castro <fefcas@uol.com.br>
+ * @author Felipo Kastro <fefcas@gmail.com>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Erik Pedersen <erik pedersen@shaw.ca>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert BOGENSCHNEIDER <robog@gmx.de>
+ * @author Robert BOGENSCHNEIDER <bogi@UEA.org>
+ */
+$lang['admin_acl'] = 'Administrado de Alirkontrola Listo (ACL)';
+$lang['acl_group'] = 'Grupo';
+$lang['acl_user'] = 'Uzanto';
+$lang['acl_perms'] = 'Rajtoj por';
+$lang['page'] = 'Paĝo';
+$lang['namespace'] = 'Nomspaco';
+$lang['btn_select'] = 'Elekti';
+$lang['p_user_id'] = 'Uzanto &lt;b class=&quot;acluser&quot;&gt;%s&lt;/b&gt; aktuale havas la jenajn rajtojn en la paĝo &lt;b class=&quot;aclpage&quot;&gt;%s&lt;/b&gt;: &lt;i&gt;%s&lt;/i&gt;.';
+$lang['p_user_ns'] = 'Uzanto &lt;b class=&quot;acluser&quot;&gt;%s&lt;/b&gt; aktuale havas la jenajn rajtojn en la nomspaco &lt;b class=&quot;aclns&quot;&gt;%s&lt;/b&gt;: &lt;i&gt;%s&lt;/i&gt;.';
+$lang['p_group_id'] = 'Anoj de la grupo &lt;b class=&quot;aclgroup&quot;&gt;%s&lt;/b&gt; aktuale havas la jenajn rajtojn en la paĝo &lt;b class=&quot;aclpage&quot;&gt;%s&lt;/b&gt;: &lt;i&gt;%s&lt;/i&gt;.';
+$lang['p_group_ns'] = 'Anoj de la grupo &lt;b class=&quot;aclgroup&quot;&gt;%s&lt;/b&gt; aktuale havas la jenajn rajtojn en la nomspaco &lt;b class=&quot;aclns&quot;&gt;%s&lt;/b&gt;: &lt;i&gt;%s&lt;/i&gt;.';
+$lang['p_choose_id'] = 'Bonvolu &lt;b&gt;enmeti uzanton aŭ grupon&lt;/b&gt; en la suba agordilo por rigardi aŭ redakti la aron da rajtoj por la paĝo &lt;b class=&quot;aclpage&quot;&gt;%s&lt;/b&gt;.';
+$lang['p_choose_ns'] = 'Bonvolu &lt;b&gt;enmeti uzanton aŭ grupon&lt;/b&gt; en la suba agordilo por rigardi aŭ redakti la aron da rajtoj por la nomspaco &lt;b class=&quot;aclns&quot;&gt;%s&lt;/b&gt;.';
+$lang['p_inherited'] = 'Rimarko: tiuj rajtoj ne estis rekte difinitaj, sed ili estis hereditaj el aliaj pli superaj grupoj aŭ nomspacoj.';
+$lang['p_isadmin'] = 'Rimarko: la elektita grupo aŭ uzanto ĉiam havas plenan rajtaron ĉar ĝi estas difinita kiel superuzanto.';
+$lang['p_include'] = 'Plialtaj permesoj inkluzivas malpli altajn. La permesoj por Krei, Alŝuti kaj Forigi nur aplikeblas al nomspacoj, ne al paĝoj.';
+$lang['current'] = 'Aktuala regularo ACL';
+$lang['where'] = 'Paĝo/Nomspaco';
+$lang['who'] = 'Uzanto/Grupo';
+$lang['perm'] = 'Rajtoj';
+$lang['acl_perm0'] = 'Nenio';
+$lang['acl_perm1'] = 'Legi';
+$lang['acl_perm2'] = 'Redakti';
+$lang['acl_perm4'] = 'Krei';
+$lang['acl_perm8'] = 'Alŝuti';
+$lang['acl_perm16'] = 'Forigi';
+$lang['acl_new'] = 'Aldoni novan Enmetaĵon';
+$lang['acl_mod'] = 'Modifi Enmetaĵon';
diff --git a/lib/plugins/acl/lang/es/help.txt b/lib/plugins/acl/lang/es/help.txt
new file mode 100644
index 000000000..c683477a8
--- /dev/null
+++ b/lib/plugins/acl/lang/es/help.txt
@@ -0,0 +1,11 @@
+=== Ayuda rápida: ===
+
+En esta página puede agregar o retirar permisos para los espacios de nombres y páginas en su wiki.
+
+El panel de la izquierda muiestra todos los espacios de nombres y páginas
+
+El formulario inferior permite ver y modificar los permisos del usuario o grupo elegido.
+
+En la tabla anterior se muestran todas las reglas de control de acceso vigentes Puede usarla para borrar o cambiar varias reglas rápidamente.
+
+Consultar el [[doku>acl|official documentation on ACL]] puede ayudarle a entender completamente como el control de acceso trabaja en DokuWiki.
diff --git a/lib/plugins/acl/lang/es/lang.php b/lib/plugins/acl/lang/es/lang.php
new file mode 100644
index 000000000..ee50a7530
--- /dev/null
+++ b/lib/plugins/acl/lang/es/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Spanish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Miguel Pagano <miguel.pagano@gmail.com>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ * @author Gabriel Castillo <gch@pumas.ii.unam.mx>
+ * @author oliver@samera.com.py
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Manuel Meco <manuel.meco@gmail.com>
+ * @author VictorCastelan <victorcastelan@gmail.com>
+ * @author Jordan Mero hack.jord@gmail.com
+ * @author Felipe Martinez <metalmartinez@gmail.com>
+ * @author Javier Aranda <internet@javierav.com>
+ * @author Zerial <fernando@zerial.org>
+ * @author Marvin Ortega <maty1206@maryanlinux.com>
+ * @author Daniel Castro Alvarado <dancas2@gmail.com>
+ * @author Fernando J. Gómez <fjgomez@gmail.com>
+ * @author Victor Castelan <victorcastelan@gmail.com>
+ * @author Mauro Javier Giamberardino <mgiamberardino@gmail.com>
+ * @author emezeta <emezeta@infoprimo.com>
+ * @author Oscar Ciudad <oscar@jacho.net>
+ * @author Ruben Figols <ruben.figols@gmail.com>
+ */
+$lang['admin_acl'] = 'Administración de lista de control de acceso';
+$lang['acl_group'] = 'Grupo';
+$lang['acl_user'] = 'Usuario';
+$lang['acl_perms'] = 'Permiso para';
+$lang['page'] = 'Página';
+$lang['namespace'] = 'Espacio de nombres';
+$lang['btn_select'] = 'Seleccionar';
+$lang['p_user_id'] = 'El usuario <b class="acluser">%s</b> tiene los siguientes permisos sobre la página <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'El usuario <b class="acluser">%s</b> tiene los siguientes permisos sobre el espacio de nombres <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Los miembros del grupo <b class="aclgroup">%s</b> tienen actualmente los siguientes permisos sobre la página <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Los miembros del grupo <b class="aclgroup">%s</b> tienen actualmente los siguientes permisos sobre el espacio de nombres <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Por favor <b>proporcione un usuario o grupo</b>en el formulario arriba mostrado para ver o editar los permisos asignados sobre la página<b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Por favor <b>proporcione un usuario o grupo</b>en el formulario arriba mostrado para ver o editar los permisos asignados sobre el espacio de nombres <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Nota: Esos permisos no fueron establecidos explícitamente sino que fueron heredados desde otros grupos o espacios de nombres superiores';
+$lang['p_isadmin'] = 'Nota: El grupo o usuario seleccionado simepre tiene permisos totales debido a que se encuentra configurado como superusuario.';
+$lang['p_include'] = 'Los permisos superiores incluyen a los inferiores. Los permisos Crear, Cargar y Eliminar sólo se aplican a los espacios de nombres, no a las páginas.';
+$lang['current'] = 'Reglas ACL vigentes';
+$lang['where'] = 'Página/Espacio de nombres';
+$lang['who'] = 'Usuario/Grupo';
+$lang['perm'] = 'Permisos';
+$lang['acl_perm0'] = 'ninguno';
+$lang['acl_perm1'] = 'Leer';
+$lang['acl_perm2'] = 'Editar';
+$lang['acl_perm4'] = 'Crear';
+$lang['acl_perm8'] = 'Subir un fichero';
+$lang['acl_perm16'] = 'Borrar';
+$lang['acl_new'] = 'Agregar una nueva entrada';
+$lang['acl_mod'] = 'Modificar una entrada';
diff --git a/lib/plugins/acl/lang/et/lang.php b/lib/plugins/acl/lang/et/lang.php
new file mode 100644
index 000000000..bc4c73a16
--- /dev/null
+++ b/lib/plugins/acl/lang/et/lang.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Estonian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Oliver S6ro <seem.iges@mail.ee>
+ * @author Aari Juhanson <aari@vmg.vil.ee>
+ * @author Kaiko Kaur <kaiko@kultuur.edu.ee>
+ * @author kristian.kankainen@kuu.la
+ * @author Rivo Zängov <eraser@eraser.ee>
+ */
+$lang['admin_acl'] = 'Ligipääsukontrolli nimekirja haldamine';
+$lang['acl_group'] = 'Grupp';
+$lang['acl_user'] = 'Kasutaja';
+$lang['acl_perms'] = 'Lubatud';
+$lang['page'] = 'leht';
+$lang['namespace'] = 'alajaotus';
+$lang['btn_select'] = 'Vali';
+$lang['who'] = 'Kasutaja/Grupp';
+$lang['perm'] = 'Õigused';
+$lang['acl_perm0'] = 'Pole';
+$lang['acl_perm1'] = 'Lugemine';
+$lang['acl_perm2'] = 'Toimetamine';
+$lang['acl_perm4'] = 'Tekitamine';
+$lang['acl_perm8'] = 'Üles laadimine';
+$lang['acl_perm16'] = 'Kustuta';
+$lang['acl_new'] = 'Uue kirje lisamine';
+$lang['acl_mod'] = 'Muuda sissekannet';
diff --git a/lib/plugins/acl/lang/eu/help.txt b/lib/plugins/acl/lang/eu/help.txt
new file mode 100644
index 000000000..9e6070a10
--- /dev/null
+++ b/lib/plugins/acl/lang/eu/help.txt
@@ -0,0 +1,11 @@
+=== Laguntza Bizkorra: ===
+
+Orri honetan wiki-ko orri eta izen-espazioen baimenak gehitu eta kendu ahal ditzakezu.
+
+Ezkerreko panelak eskuragarri dauden orri eta izen-espazioak erakusten ditu.
+
+Goiko formularioak aukeratutako erabiltzaile edo taldearen baimenak ikusi eta aldatzea ahalbidetzen dizu.
+
+Beheko taulan une honetan ezarritako atzipen kontrol arauak daude. Hainbat arau bizkor ezabatu edo aldatzeko erabili dezakezu.
+
+[[doku>acl|Atzipen Kontrol Listen inguruko dokumentazio ofiziala]] irakurtzeak atzipen kontrolak DokuWiki-n nola funtzionatzen duen ulertzen lagundu zaitzaike.
diff --git a/lib/plugins/acl/lang/eu/lang.php b/lib/plugins/acl/lang/eu/lang.php
new file mode 100644
index 000000000..99e70ad00
--- /dev/null
+++ b/lib/plugins/acl/lang/eu/lang.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Basque language file
+ *
+ * @author Inko Illarramendi <inko.i.a@gmail.com>
+ */
+$lang['admin_acl'] = 'Atzipen Kontrol Listaren Kudeaketa';
+$lang['acl_group'] = 'Taldea';
+$lang['acl_user'] = 'Erabiltzailea';
+$lang['acl_perms'] = 'Baimenak honetarako:';
+$lang['page'] = 'Orria';
+$lang['namespace'] = 'Izen-espazioa';
+$lang['btn_select'] = 'Aukeratu';
+$lang['p_user_id'] = '<b class="acluser">%s</b> erabiltzaileak une honetan honako baimenak ditu <b class="aclpage">%s</b> orrian: <i>%s</i>.';
+$lang['p_user_ns'] = '<b class="acluser">%s</b> erabiltzaileak une honetan honako baimenak ditu <b class="aclns">%s</b> izen-espazioan: <i>%s</i>.';
+$lang['p_group_id'] = '<b class="aclgroup">%s</b> taldeko kideek une honetan honako baimenak dituzte <b class="aclpage">%s</b> orrian: <i>%s</i>.';
+$lang['p_group_ns'] = '<b class="aclgroup">%s</b> taldeko kideek une honetan honako baimenak dituzte <b class="aclns">%s</b> izen-espazioan: <i>%s</i>.';
+$lang['p_choose_id'] = 'Mesedez <b>sartu erabiltzaile edo taldea</b> goiko formularioan <b class="aclpage">%s</b> orrian ezarritako baimenak ikusi edo aldatzeko.';
+$lang['p_choose_ns'] = 'Mesedez <b>sartu erabiltzaile edo taldea</b> goiko formularioan <b class="aclns">%s</b> izen-espazioan ezarritako baimenak ikusi edo aldatzeko.';
+$lang['p_inherited'] = 'Oharra: Baimen horiek ez dira esplizituki jarriak, beste talde batzuetatik edo goragoko izen-espazioetatik heredatuak baizik.';
+$lang['p_isadmin'] = 'Oharra: Aukeratutako talde edo erabiltzaileak beti daika baimen osoa, supererabiltzaile gisa konfiguratuta baitago.';
+$lang['p_include'] = 'Baimen handiagoek baimen txikiagoak barneratzen dituzte. Sortu, Igo eta Ezabatu baimenak izen-espazioei soilik aplikatzen zaizkie, ez orriei.';
+$lang['current'] = 'Uneko AKL Arauak';
+$lang['where'] = 'Orria/Izen-espazioa';
+$lang['who'] = 'Erabiltzailea/Taldea';
+$lang['perm'] = 'Baimenak';
+$lang['acl_perm0'] = 'Inork';
+$lang['acl_perm1'] = 'Irakurri';
+$lang['acl_perm2'] = 'Editatu';
+$lang['acl_perm4'] = 'Sortu';
+$lang['acl_perm8'] = 'Igo';
+$lang['acl_perm16'] = 'Ezabatu';
+$lang['acl_new'] = 'Sarrera berri bat gehitu';
+$lang['acl_mod'] = 'Aldatu Sarrera';
diff --git a/lib/plugins/acl/lang/fa/help.txt b/lib/plugins/acl/lang/fa/help.txt
new file mode 100644
index 000000000..1ec797faf
--- /dev/null
+++ b/lib/plugins/acl/lang/fa/help.txt
@@ -0,0 +1,11 @@
+=== راهنما: ===
+
+در این صفحه شما می‌توانید دسترسی صفحات و فضای‌نام‌ها را مدیریت کنید.
+
+در قسمت سمت راست، لیست تمام صفحات و فضای‌نام‌ها را مشاهده می‌کنید.
+
+در فرم بالا می‌توانید دسترسی‌های کاربران و گروه‌های مختلف را مشاهده و ویرایش کنید.
+
+در جدول زیر، تمامی قوانین مدیریتی را مشاهده می‌کنید. شما می‌توانید آن‌ها را حذف یا تعدادی از آن‌ها رو تغییر دهید.
+
+ممکن است خواندن [[doku>acl|مطلب رسمی در مورد مدیریت دسترسی‌ها]] شما را در درک بهتر این قسمت DokuWiki یاری کند. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/fa/lang.php b/lib/plugins/acl/lang/fa/lang.php
new file mode 100644
index 000000000..ed576c271
--- /dev/null
+++ b/lib/plugins/acl/lang/fa/lang.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Persian language file
+ *
+ * @author behrad eslamifar <behrad_es@yahoo.com)
+ * @author Mohsen Firoozmandan <info@mambolearn.com>
+ * @author omidmr@gmail.com
+ * @author Omid Mottaghi <omidmr@gmail.com>
+ * @author Mohammad Reza Shoaei <shoaei@gmail.com>
+ */
+$lang['admin_acl'] = 'مدیریت کنترل دسترسی‌ها';
+$lang['acl_group'] = 'گروه';
+$lang['acl_user'] = 'کاربر';
+$lang['acl_perms'] = 'مجوز برای';
+$lang['page'] = 'صفحه';
+$lang['namespace'] = 'فضای‌نام';
+$lang['btn_select'] = 'انتخاب';
+$lang['p_user_id'] = 'کاربر <b class="acluser">%s</b> دسترسی‌های زیر را برای صفحه‌ی <b class="aclpage">%s</b> دارد: <i>%s</i>.';
+$lang['p_user_ns'] = 'کاربر <b class="acluser">%s</b> دسترسی‌های زیر را برای فضای‌نام <b class="aclpage">%s</b> دارد: <i>%s</i>.';
+$lang['p_group_id'] = 'اعضای گروه <b class="aclgroup">%s</b> دسترسی‌های زیر را برای صفحه‌ی <b class="aclpage">%s</b> دارند: <i>%s</i>.';
+$lang['p_group_ns'] = 'اعضای گروه <b class="aclgroup">%s</b> دسترسی‌های زیر را برای فضای‌نام <b class="aclpage">%s</b> دارند: <i>%s</i>.';
+$lang['p_choose_id'] = 'خواهشمندیم <b>نام یک کاربر یا گروه</b> را در فرم بالا وارد کنید تا دسترسی‌های آن را برای صفحه‌ی <b class="aclpage">%s</b> ببینید و ویرایش کنید.';
+$lang['p_choose_ns'] = 'خواهشمندیم <b>نام یک کاربر یا گروه</b> را در فرم بالا وارد کنید تا دسترسی‌های آن را برای فضای‌نام <b class="aclpage">%s</b> ببینید و ویرایش کنید.';
+$lang['p_inherited'] = 'توجه: دسترسی‌ها مستقیمن مقداردهی نشده است، بلکه از گروه‌های بالا یا فضای‌نام گرفته شده است.';
+$lang['p_isadmin'] = 'توجه: کاربر یا گروه انتخاب شده همیشه با تمام دسترسی می‌باشد، زیرا به عنوان «superuser» انتخاب شده است.';
+$lang['p_include'] = 'دسترسی‌های بالا، دسترسی‌های پایین را شامل می‌شود. ایجاد، ارسال و حذف فقط به فضای‌نام الحاق می‌شود.';
+$lang['current'] = 'قوانین دسترسی فعلی';
+$lang['where'] = 'صفحه/فضای‌نام';
+$lang['who'] = 'کاربر/گروه';
+$lang['perm'] = 'دسترسی‌ها';
+$lang['acl_perm0'] = 'هیچ‌کدام';
+$lang['acl_perm1'] = 'خواندن';
+$lang['acl_perm2'] = 'ویزایش';
+$lang['acl_perm4'] = 'ایجاد';
+$lang['acl_perm8'] = 'ارسال';
+$lang['acl_perm16'] = 'حذف';
+$lang['acl_new'] = 'اضافه کردن ورودی جدید';
+$lang['acl_mod'] = 'ویرایش ورودی';
diff --git a/lib/plugins/acl/lang/fi/help.txt b/lib/plugins/acl/lang/fi/help.txt
new file mode 100644
index 000000000..d821f2d89
--- /dev/null
+++ b/lib/plugins/acl/lang/fi/help.txt
@@ -0,0 +1,11 @@
+=== Pika-apu: ===
+
+Tällä sivulla voit lisätä tai poistaa oikeuksia wikisi nimiavaruuksiin tai sivuihin.
+
+Vasen osa näyttää kaikki tarjolla olevat nimiavaruudet ja sivut.
+
+Yllä olevan kaavakkeen avulla voit katsoa ja muokata oikeuksia valitulle käyttäjälle ja ryhmälle.
+
+Alla olevassa taulukossa on näkyvissä päällä olevat pääsyoikeudet. Voit käyttää sitä muokataksesi tai poistaaksesi useita oikeuksia.
+
+[[doku>acl|Virallisen käyttöoikeus (ACL) dokumentaation]] lukeminen voi helpottaa sinua täysin ymmärtämään mitän käyttöoikeudet toimivat DokuWikissä.
diff --git a/lib/plugins/acl/lang/fi/lang.php b/lib/plugins/acl/lang/fi/lang.php
new file mode 100644
index 000000000..4f145e0f6
--- /dev/null
+++ b/lib/plugins/acl/lang/fi/lang.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Finnish language file
+ *
+ * @author otto@valjakko.net
+ * @author Otto Vainio <otto@valjakko.net>
+ * @author Teemu Mattila <ghcsystems@gmail.com>
+ * @author Sami Olmari <sami@olmari.fi>
+ */
+$lang['admin_acl'] = 'Käyttöoikeudet (ACL)';
+$lang['acl_group'] = 'Ryhmä';
+$lang['acl_user'] = 'Käyttäjä';
+$lang['acl_perms'] = 'Oikeudet';
+$lang['page'] = 'Sivu';
+$lang['namespace'] = 'Nimiavaruus';
+$lang['btn_select'] = 'Valitse';
+$lang['p_user_id'] = 'Käyttäjällä <b class="acluser">%s</b> on tällä hetkellä seuraavat oikeudet sivulla <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Käyttäjällä <b class="acluser">%s</b> on tällä hetkellä seuraavat oikeudet nimiavaruudessa <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Ryhmän <b class="aclgroup">%s</b> jäsenillä on tällä hetkellä seuraavat oikeudet sivulla <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Ryhmän <b class="aclgroup">%s</b> jäsenillä on tällä hetkellä seuraavat oikeudet nimiavaruudessa <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Ole hyvä ja <b>syötä ryhmän nimi</b> yllä olevaan kaavakkeeseen katsoaksesi tai muokataksesi oikeuksia sivulle <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Ole hyvä ja <b>syötä ryhmän nimi</b> yllä olevaan kaavakkeeseen katsoaksesi tai muokataksesi oikeuksia nimiavaruuteen <b class="aclpage">%s</b>.';
+$lang['p_inherited'] = 'Huomaa: Oikeuksia ei ole erikseen asetettu, vaan ne on peritty toiselta ryhmältä tai ylemmältä nimiavaruudelta.';
+$lang['p_isadmin'] = 'Huomaa: Valitulla ryhmällä tai käyttäjällä on aina täydet oikeudet, koska se on määritelty pääkäyttäjäksi (Superuser)';
+$lang['p_include'] = 'Korkeammat oikeudet sisältävät matalammat. Luonti-, Lähetys- ja Poisto-oikeudet vaikuttavat vain nimiavaruuksiin, ei sivuihin.';
+$lang['current'] = 'Tämänhetkiset käyttöoikeudet (ACL)';
+$lang['where'] = 'Sivu/Nimiavaruus';
+$lang['who'] = 'Käyttäjä/Ryhmä';
+$lang['perm'] = 'Oikeudet';
+$lang['acl_perm0'] = 'Ei mitään';
+$lang['acl_perm1'] = 'Luku';
+$lang['acl_perm2'] = 'Muokkaus';
+$lang['acl_perm4'] = 'Luonti';
+$lang['acl_perm8'] = 'Lähetys';
+$lang['acl_perm16'] = 'Poisto';
+$lang['acl_new'] = 'Lisää uusi';
+$lang['acl_mod'] = 'Muokkaa';
diff --git a/lib/plugins/acl/lang/fr/help.txt b/lib/plugins/acl/lang/fr/help.txt
new file mode 100644
index 000000000..158ec92ed
--- /dev/null
+++ b/lib/plugins/acl/lang/fr/help.txt
@@ -0,0 +1,9 @@
+=== Aide rapide ===
+
+Cette page vous permet d'ajouter ou de supprimer des permissions pour les catégories et les pages de votre wiki. Le panneau de gauche liste toutes les catégories et les pages disponibles.
+
+Le formulaire ci-dessus permet d'afficher et de modifier les permissions d'un utilisateur ou d'un groupe sélectionné.
+
+Dans le tableau ci-dessous, toutes les listes de contrôle d'accès actuelles sont affichées. Vous pouvez l'utiliser pour supprimer ou modifier rapidement plusieurs ACL.
+
+La lecture de [[doku>fr:acl|la documentation officielle des ACL]] pourra vous permettre de bien comprendre le fonctionnement du contrôle d'accès dans DokuWiki.
diff --git a/lib/plugins/acl/lang/fr/lang.php b/lib/plugins/acl/lang/fr/lang.php
new file mode 100644
index 000000000..a33a52bf0
--- /dev/null
+++ b/lib/plugins/acl/lang/fr/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * french language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Sébastien Bauer <sebastien.bauer@advalvas.be>
+ * @author Antoine Fixary <antoine.fixary@freesbee.fr>
+ * @author cumulus <pta-n56@myamail.com>
+ * @author Gwenn Gueguen <contact@demisel.net>
+ * @author Guy Brand <gb@unistra.fr>
+ * @author Fabien Chabreuil <fabien@integralpersonality.com>
+ * @author Stéphane Chamberland <stephane.chamberland@ec.gc.ca>
+ * @author Maurice A. LeBlanc <leblancma@cooptel.qc.ca>
+ * @author stephane.gully@gmail.com
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author olivier duperray <duperray.olivier@laposte.net>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author Philippe Bajoit <philippe.bajoit@gmail.com>
+ * @author Florian Gaub <floriang@floriang.net>
+ * @author Samuel Dorsaz samuel.dorsaz@novelion.net
+ * @author Johan Guilbaud <guilbaud.johan@gmail.com>
+ * @author schplurtz@laposte.net
+ * @author skimpax@gmail.com
+ */
+$lang['admin_acl'] = 'Gestion de la liste des contrôles d\'accès (ACL)';
+$lang['acl_group'] = 'Groupe';
+$lang['acl_user'] = 'Utilisateur';
+$lang['acl_perms'] = 'Permission pour';
+$lang['page'] = 'Page';
+$lang['namespace'] = 'Catégorie';
+$lang['btn_select'] = 'Sélectionner';
+$lang['p_user_id'] = 'Permissions actuelles de l\'utilisateur <strong class="acluser">%s</strong> sur la page <strong class="aclpage">%s</strong>: <em>%s</em>.';
+$lang['p_user_ns'] = 'Permissions actuelles de l\'utilisateur <strong class="acluser">%s</strong> sur la catégorie <strong class="aclns">%s</strong>: <em>%s</em>.';
+$lang['p_group_id'] = 'Permissions actuelles des membres du groupe <strong class="aclgroup">%s</strong> sur la page <strong class="aclpage">%s</strong>: <em>%s</em>.';
+$lang['p_group_ns'] = 'Permissions actuelles des membres du groupe <strong class="aclgroup">%s</strong> sur la catégorie <strong class="aclns">%s</strong>: <em>%s</em>.';
+$lang['p_choose_id'] = 'Saisissez un nom <strong>d\'utilisateur ou de groupe</strong> dans le formulaire ci-dessus pour afficher ou éditer les permissions relatives à la page <strong class="aclpage">%s</strong>.';
+$lang['p_choose_ns'] = 'Saisissez un nom <strong>d\'utilisateur ou de groupe</strong> dans le formulaire ci-dessous pour afficher ou éditer les permissions relatives à la catégorie <strong class="aclns">%s</strong>.';
+$lang['p_inherited'] = 'Note : Ces permissions n\'ont pas été explicitement fixées mais sont héritées d\'autres groupes ou catégories supérieures.';
+$lang['p_isadmin'] = 'Note : Le groupe ou l\'utilisateur sélectionné dispose de toutes les permissions car il est paramétré en tant que superutilisateur.';
+$lang['p_include'] = 'Les permissions les plus élevées induisent les plus faibles. Création, Télécharger et Effacer ne s\'appliquent qu\'aux catégories, pas aux pages.';
+$lang['current'] = 'ACL actuelles';
+$lang['where'] = 'Page/Catégorie';
+$lang['who'] = 'Utilisateur/Groupe';
+$lang['perm'] = 'Permissions';
+$lang['acl_perm0'] = 'Aucune';
+$lang['acl_perm1'] = 'Lecture';
+$lang['acl_perm2'] = 'Écriture';
+$lang['acl_perm4'] = 'Création';
+$lang['acl_perm8'] = 'Téléverser';
+$lang['acl_perm16'] = 'Effacer';
+$lang['acl_new'] = 'Ajouter une nouvelle entrée';
+$lang['acl_mod'] = 'Modifier l\'entrée';
diff --git a/lib/plugins/acl/lang/gl/help.txt b/lib/plugins/acl/lang/gl/help.txt
new file mode 100644
index 000000000..593dcef07
--- /dev/null
+++ b/lib/plugins/acl/lang/gl/help.txt
@@ -0,0 +1,11 @@
+=== Axuda Rápida: ===
+
+Nesta páxina podes engadir e eliminar permisos para os nomes de espazo e as páxinas do teu wiki.
+
+O panel da esquerda amosa todos os nomes de espazo e páxinas dispoñíbeis.
+
+O formulario de enriba permíteche ver e modificares os permisos do usuario ou grupo seleccionado.
+
+Na táboa de embaixo amósanse todas as regras de control de accesos estabelecidas. Podes empregala para mudares ou eliminares varias regras dun xeito rápido.
+
+A lectura da [[doku>acl|documentación oficial da ACL]] pode servirche de axuda para comprenderes como funciona o control de accesos no Dokuwiki.
diff --git a/lib/plugins/acl/lang/gl/lang.php b/lib/plugins/acl/lang/gl/lang.php
new file mode 100644
index 000000000..db57598e6
--- /dev/null
+++ b/lib/plugins/acl/lang/gl/lang.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Galicianlanguage file
+ *
+ * @author Medúlio <medulio@ciberirmandade.org>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ */
+$lang['admin_acl'] = 'Xestión da Lista de Control de Acceso (ACL)';
+$lang['acl_group'] = 'Grupo';
+$lang['acl_user'] = 'Usuario';
+$lang['acl_perms'] = 'Permisos para';
+$lang['page'] = 'Páxina';
+$lang['namespace'] = 'Nome de espazo';
+$lang['btn_select'] = 'Escolle';
+$lang['p_user_id'] = 'O usuario <b class="acluser">%s</b> dispón actualmente dos seguintes permisos na páxina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'O usuario <b class="acluser">%s</b> dispón actualmente dos seguintes permisos no nome de espazo <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Os membros do grupo <b class="aclgroup">%s</b> dispoñen actualmente dos seguintes permisos na páxina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Os membros do grupo <b class="aclgroup">%s</b> cdispoñen actualmente dos seguintes permisos no nome de espazo <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Por favor, <b>insire un usuario ou grupo</b> no formulario de enriba para ver ou editar os permisos establecidos para a páxina <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Por favor <b>insire un usuario ou grupo</b> no formulario de enriba para ver ou editar os permisos establecidos no nome de espazo <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Nota: Estes permisos non foron establecidos explicitamente senón que foron herdadas de outros grupos ou nomes de espazo meirandes.';
+$lang['p_isadmin'] = 'Nota: O grupo ou usuario seleccionado terá sempre permisos completos por estar configurado como super-usuario.';
+$lang['p_include'] = 'Os permisos meirandes inclúen os menores. Os permisos de Creación, Subida e Eliminado só se aplican aos nomes de espazo, non ás páxinas.';
+$lang['current'] = 'Regras ACL Actuais';
+$lang['where'] = 'Páxina/Nome de Espazo';
+$lang['who'] = 'Usuario/Grupo';
+$lang['perm'] = 'Permisos';
+$lang['acl_perm0'] = 'Ningún';
+$lang['acl_perm1'] = 'Ler';
+$lang['acl_perm2'] = 'Editar';
+$lang['acl_perm4'] = 'Crear';
+$lang['acl_perm8'] = 'Subir arquivos';
+$lang['acl_perm16'] = 'Eliminar';
+$lang['acl_new'] = 'Engadir nova Entrada';
+$lang['acl_mod'] = 'Modificar Entrada';
diff --git a/lib/plugins/acl/lang/he/help.txt b/lib/plugins/acl/lang/he/help.txt
new file mode 100644
index 000000000..33f2933b9
--- /dev/null
+++ b/lib/plugins/acl/lang/he/help.txt
@@ -0,0 +1,11 @@
+=== עזרה חפוזה: ===
+
+בדף זה ניתן להוסיף ולהסיר הרשאות למרחבי שמות ולדפים בויקי שלך.
+
+הצד השמאלי מציג את כל מרבי השמות והדפים הזמינים.
+
+הטופס מעלה מאפשר לך לראות ולשנות את ההרשאות של משתמש או קבוצה נבחרים.
+
+בטבלה מטה מוצגים כל כללי בקרת הגישה הנוכחיים. ניתן להשתמש בה כדי למחוק או לשנות מספר כללים במהירות.
+
+קריאת [[doku>acl|התיעוד הרשמי ל-ACL ACL]] יכולה לעזור לך להבין באופן מלא כיצד בקרת הגישה עובדת בדוקוויקי.
diff --git a/lib/plugins/acl/lang/he/lang.php b/lib/plugins/acl/lang/he/lang.php
new file mode 100644
index 000000000..91025f4b8
--- /dev/null
+++ b/lib/plugins/acl/lang/he/lang.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * hebrew language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author DoK <kamberd@yahoo.com>
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ * @author Moshe Kaplan <mokplan@gmail.com>
+ * @author Yaron Yogev <yaronyogev@gmail.com>
+ * @author Yaron Shahrabani <sh.yaron@gmail.com>
+ */
+$lang['admin_acl'] = 'ניהול רשימת בקרת גישות';
+$lang['acl_group'] = 'קבוצה';
+$lang['acl_user'] = 'משתמש';
+$lang['acl_perms'] = 'הרשאות עבור';
+$lang['page'] = 'דף';
+$lang['namespace'] = 'מרחב שמות';
+$lang['p_user_id'] = 'למשתמש <b class="acluser">%s</b> יש כרגע את ההרשאות הבאות בדף <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'למשתמש <b class="acluser">%s</b> יש כרגע את ההרשאות הבאות במרחב השם <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'לחברי קבוצת <b class="aclgroup">%s</b> יש כרגע את ההרשאות הבאות בדף <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'לחברי קבוצת <b class="aclgroup">%s</b> יש כרגע את ההרשאות הבאות במרחב השם <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'נא <b>להזין משתמש או קבוצה</b> בטופס מעלה כדי לצפות או לערוך את ההרשאות המוגדרות עבור הדף <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'נא <b>להזין משתמש או קבוצה</b> בטופס מעלה כדי לצפות או לערוך את ההרשאות המוגדרות עבור מרחב השם <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'לתשומת לבך: הרשאות אלו לא הוגדרו באופן מפורש אלא נורשו מקבוצות אחרות או ממרחב שמות גבוה יותר.';
+$lang['p_isadmin'] = 'לתשומת לבך: לקבוצה או המשתמש שנבחרו יש תמיד הרשאות מלאות בגלל הגדרתם כמשתמש-על.';
+$lang['current'] = 'חוקי ה-ACL הנוכחיים';
+$lang['where'] = 'דף/מרחב שם';
+$lang['who'] = 'משתמש/קבוצה';
+$lang['perm'] = 'הרשאות';
+$lang['acl_perm0'] = 'ללא';
+$lang['acl_perm1'] = 'קריאה';
+$lang['acl_perm2'] = 'עריכה';
+$lang['acl_perm4'] = 'יצירה';
+$lang['acl_perm8'] = 'העלאה';
+$lang['acl_perm16'] = 'מחיקה';
+$lang['acl_new'] = 'הוספת רשומה חדשה';
+$lang['acl_mod'] = 'שינויי מובאה';
diff --git a/lib/plugins/acl/lang/hi/lang.php b/lib/plugins/acl/lang/hi/lang.php
new file mode 100644
index 000000000..d6f78ffd6
--- /dev/null
+++ b/lib/plugins/acl/lang/hi/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Hindi language file
+ *
+ * @author Abhinav Tyagi <abhinavtyagi11@gmail.com>
+ * @author yndesai@gmail.com
+ */
diff --git a/lib/plugins/acl/lang/hr/help.txt b/lib/plugins/acl/lang/hr/help.txt
new file mode 100644
index 000000000..4e7cfc3c2
--- /dev/null
+++ b/lib/plugins/acl/lang/hr/help.txt
@@ -0,0 +1,11 @@
+=== Brza Pomoć: ===
+
+Na ovoj stranici možeš dodavati i brisati dozvole za imenske prostore i stranice u svom wiki-u.
+
+Lijevi prozor prikazuje sve dostupne imenske prostore i stranice.
+
+Forma iznad ti omogućuje pregled i mijenjanje dozvola odabranom korisniku ili grupi.
+
+U tablici ispod prikazana su sva trenutno postavljena pravila kontrole pristupa. Koristite je za višestruko brisanje ili mijenjanje pravila.
+
+Čitanje [[doku>acl|službena dokumentacija o ACL]] može vam pomoći potpuno razumijeti kako kontrola pristupa radi u DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/hr/lang.php b/lib/plugins/acl/lang/hr/lang.php
new file mode 100644
index 000000000..8c21f1b0b
--- /dev/null
+++ b/lib/plugins/acl/lang/hr/lang.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Croatian language file
+ *
+ * @author Branko Rihtman <theney@gmail.com>
+ * @author Dražen Odobašić <dodobasic@gmail.com>
+ * @author Dejan Igrec dejan.igrec@gmail.com
+ */
+$lang['admin_acl'] = 'Upravljanje listom kontrole pristupa';
+$lang['acl_group'] = 'Grupa';
+$lang['acl_user'] = 'Korisnik';
+$lang['acl_perms'] = 'Dozvole za';
+$lang['page'] = 'Stranica';
+$lang['namespace'] = 'Imenski prostor';
+$lang['btn_select'] = 'Odaberi';
+$lang['p_user_id'] = 'Korisnik <b class="acluser">%s</b> trenutno ima sljedeće dozvole na stranici <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Korisnik <b class="acluser">%s</b> trenutno ima sljedeće dozvole u imenskom prostoru <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Članovi grupe <b class="aclgroup">%s</b> trenutno imaju sljedeće dozvole na stranici <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Članovi grupe <b class="aclgroup">%s</b> trenutno imaju sljedeće dozvole u imenskom prostoru <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Molim <b>unesti korisnika ili grupu</b> u gornju formu za pregled ili uređivanje dozvola postavljenih za stranicu <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Molim <b>unesti korisnika ili grupu</b> u gornju formu za pregled ili uređivanje dozvola postavljenih za imenski prostor <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Napomena: Ove dozvole nisu postavljene eksplicitno već su naslijeđene od drugih grupa ili nadređenih imenskih prostora.';
+$lang['p_isadmin'] = 'Napomena: Odabrana grupa ili korisnik uvijek ima sve dozvole jer je postavljen kao superuser.';
+$lang['p_include'] = 'Više dozvole uključuju sve niže. Dozvole Kreiraj, Učitaj i Briši se primjenjuju samo na imenske prostore, ne stranice.';
+$lang['current'] = 'Trenutna ACL Pravila';
+$lang['where'] = 'Stranica/Imenski prostor';
+$lang['who'] = 'Korisnik/Grupa';
+$lang['perm'] = 'Dozvole';
+$lang['acl_perm0'] = 'Ništa';
+$lang['acl_perm1'] = 'Čitaj';
+$lang['acl_perm2'] = 'Uredi';
+$lang['acl_perm4'] = 'Kreiraj';
+$lang['acl_perm8'] = 'Učitaj';
+$lang['acl_perm16'] = 'Briši';
+$lang['acl_new'] = 'Dodaj novi Zapis';
+$lang['acl_mod'] = 'Promijeni Zapis';
diff --git a/lib/plugins/acl/lang/hu/help.txt b/lib/plugins/acl/lang/hu/help.txt
new file mode 100644
index 000000000..57f16a39c
--- /dev/null
+++ b/lib/plugins/acl/lang/hu/help.txt
@@ -0,0 +1,12 @@
+=== Hozzáférési lista (ACL) kezelő ===
+
+Ezen az oldalon jogokat oszthat és vehet el a wiki oldalakhoz és névterekhez.
+
+A bal oldalon látható az összes névtér és oldal.
+
+A felső form segít a kiválasztott felhasználó vagy csoport jogosultságainak megtekintésében vagy változtatásában.
+
+Az alsó táblázat mutatja az összes jelenleg érvényes hozzáférési szabályt. Ennek segítségével gyorsan törölhetők vagy megváltoztathatók a szabályok.
+
+A [[doku>acl|hivatalos ACL dokumentáció]] segíthet a DokuWiki hozzáférés-kezelés működésének megértésében.
+
diff --git a/lib/plugins/acl/lang/hu/lang.php b/lib/plugins/acl/lang/hu/lang.php
new file mode 100644
index 000000000..255d838b6
--- /dev/null
+++ b/lib/plugins/acl/lang/hu/lang.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Hungarian language file
+ *
+ * @author Sandor TIHANYI <stihanyi+dw@gmail.com>
+ * @author Siaynoq Mage <siaynoqmage@gmail.com>
+ * @author schilling.janos@gmail.com
+ * @author Szabó Dávid <szabo.david@gyumolcstarhely.hu>
+ * @author Sándor TIHANYI <stihanyi+dw@gmail.com>
+ * @author David Szabo <szabo.david@gyumolcstarhely.hu>
+ */
+$lang['admin_acl'] = 'Hozzáférési lista (ACL) kezelő';
+$lang['acl_group'] = 'Csoport:';
+$lang['acl_user'] = 'Felhasználó:';
+$lang['acl_perms'] = 'Jogosultság ehhez:';
+$lang['page'] = 'oldal';
+$lang['namespace'] = 'névtér';
+$lang['btn_select'] = 'Kiválaszt';
+$lang['p_user_id'] = 'A(z) <b class="acluser">%s</b> felhasználónak jelenleg a következő jogosultsága van ezen az oldalon: <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'A(z) <b class="acluser">%s</b> felhasználónak jelenleg a következő jogosultsága van ebben a névtérben: <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'A(z) <b class="aclgroup">%s</b> csoport tagjainak jelenleg a következő jogosultsága van ezen az oldalon: <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'A(z) <b class="aclgroup">%s</b> csoport tagjainak jelenleg a következő jogosultsága van ebben a névtérben: <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'A felső formon <b>adjon meg egy felhasználót vagy csoportot</b>, akinek a(z) <b class="aclpage">%s</b> oldalhoz beállított jogosultságait megtekinteni vagy változtatni szeretné.';
+$lang['p_choose_ns'] = 'A felső formon <b>adjon meg egy felhasználót vagy csoportot</b>, akinek a(z) <b class="aclns">%s</b> névtérhez beállított jogosultságait megtekinteni vagy változtatni szeretné.';
+$lang['p_inherited'] = 'Megjegyzés: ezek a jogok nem itt lettek explicit beállítva, hanem öröklődtek egyéb csoportokból vagy felsőbb névterekből.';
+$lang['p_isadmin'] = 'Megjegyzés: a kiválasztott csoportnak vagy felhasználónak mindig teljes jogosultsága lesz, mert Wiki-gazdának van beállítva.';
+$lang['p_include'] = 'A magasabb jogok tartalmazzák az alacsonyabbakat. A Létrehozás, Feltöltés és Törlés jogosultságok csak névterekre alkalmazhatók, az egyes oldalakra nem.';
+$lang['current'] = 'Jelenlegi hozzáférési szabályok';
+$lang['where'] = 'Oldal/névtér';
+$lang['who'] = 'Felhasználó/Csoport';
+$lang['perm'] = 'Jogosultságok';
+$lang['acl_perm0'] = 'Semmi';
+$lang['acl_perm1'] = 'Olvasás';
+$lang['acl_perm2'] = 'Szerkesztés';
+$lang['acl_perm4'] = 'Létrehozás';
+$lang['acl_perm8'] = 'Feltöltés';
+$lang['acl_perm16'] = 'Törlés';
+$lang['acl_new'] = 'Új bejegyzés hozzáadása';
+$lang['acl_mod'] = 'Bejegyzés módosítása';
diff --git a/lib/plugins/acl/lang/ia/help.txt b/lib/plugins/acl/lang/ia/help.txt
new file mode 100644
index 000000000..59f5764eb
--- /dev/null
+++ b/lib/plugins/acl/lang/ia/help.txt
@@ -0,0 +1,11 @@
+=== Adjuta rapide: ===
+
+In iste pagina tu pote adder e remover permissiones pro spatios de nomines e paginas in tu wiki.
+
+Le columna sinistre presenta tote le spatios de nomines e paginas disponibile.
+
+Le formulario hic supra permitte vider e modificar le permissiones de un usator o gruppo seligite.
+
+In le tabella hic infra se monstra tote le regulas de controlo de accesso actualmente configurate. Tu pote usar lo pro rapidemente deler o modificar plure regulas.
+
+Es recommendate leger le [[doku>acl|documentation official super ACL]] pro comprender completemente como le controlo de accesso functiona in DokuWiki.
diff --git a/lib/plugins/acl/lang/ia/lang.php b/lib/plugins/acl/lang/ia/lang.php
new file mode 100644
index 000000000..f7d076539
--- /dev/null
+++ b/lib/plugins/acl/lang/ia/lang.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Interlingua language file
+ *
+ * @author robocap <robocap1@gmail.com>
+ * @author Martijn Dekker <martijn@inlv.org>
+ */
+$lang['admin_acl'] = 'Gestion de listas de controlo de accesso';
+$lang['acl_group'] = 'Gruppo';
+$lang['acl_user'] = 'Usator';
+$lang['acl_perms'] = 'Permissiones pro';
+$lang['page'] = 'Pagina';
+$lang['namespace'] = 'Spatio de nomines';
+$lang['btn_select'] = 'Seliger';
+$lang['p_user_id'] = 'Le usator <b class="acluser">%s</b> ha actualmente le sequente permissiones in le pagina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Le usator <b class="acluser">%s</b> ha actualmente le sequente permissiones in le spatio de nomines <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Le membros del gruppo <b class="aclgroup">%s</b> a actualmente le sequente permissiones in le pagina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Le membros del gruppo <b class="aclgroup">%s</b> ha actualmente le sequente permissiones in le spatio de nomines <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Per favor <b>entra un usator o gruppo</b> in le formulario hic supra pro vider o modificar le permissiones configurate pro le pagina <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Per favor <b>entra un usator o gruppo</b> in le formulario hic supra pro vider o modificar le permissiones configurate pro le spatio de nomines <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Nota ben: Iste permissiones non ha essite configurate explicitemente ma ha essite hereditate de altere gruppos o de spatios de nomines superior.';
+$lang['p_isadmin'] = 'Nota ben: Le gruppo o usator seligite ha sempre permissiones integral proque es configurate como superusator.';
+$lang['p_include'] = 'Le permissiones superior include les inferior. Le permissiones de Crear, Incargar e Deler es solmente applicabile a spatios de nomines, non a paginas.';
+$lang['current'] = 'Regulas ACL actual';
+$lang['where'] = 'Pagina/Spatio de nomines';
+$lang['who'] = 'Usator/Gruppo';
+$lang['perm'] = 'Permissiones';
+$lang['acl_perm0'] = 'Nulle';
+$lang['acl_perm1'] = 'Leger';
+$lang['acl_perm2'] = 'Modificar';
+$lang['acl_perm4'] = 'Crear';
+$lang['acl_perm8'] = 'Incargar';
+$lang['acl_perm16'] = 'Deler';
+$lang['acl_new'] = 'Adder nove entrata';
+$lang['acl_mod'] = 'Modificar entrata';
diff --git a/lib/plugins/acl/lang/id-ni/lang.php b/lib/plugins/acl/lang/id-ni/lang.php
new file mode 100644
index 000000000..d367340b7
--- /dev/null
+++ b/lib/plugins/acl/lang/id-ni/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * idni language file
+ *
+ * @author Harefa <fidelis@harefa.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/acl/lang/id/lang.php b/lib/plugins/acl/lang/id/lang.php
new file mode 100644
index 000000000..650637635
--- /dev/null
+++ b/lib/plugins/acl/lang/id/lang.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Indonesian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author mubaidillah <mubaidillah@gmail.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
+$lang['admin_acl'] = 'Manajemen Daftar Pengendali Akses';
+$lang['acl_group'] = 'Grup';
+$lang['acl_user'] = 'User';
+$lang['acl_perms'] = 'Ijin untuk';
+$lang['page'] = 'Halaman';
+$lang['namespace'] = 'Namespace';
+$lang['btn_select'] = 'Pilih';
+$lang['acl_perm1'] = 'Baca';
+$lang['acl_perm2'] = 'Ubah';
+$lang['acl_perm4'] = 'Buat';
+$lang['acl_perm8'] = 'Upload';
+$lang['acl_perm16'] = 'Hapus';
+$lang['acl_new'] = 'Tambah Entry baru';
diff --git a/lib/plugins/acl/lang/is/lang.php b/lib/plugins/acl/lang/is/lang.php
new file mode 100644
index 000000000..b45faa80a
--- /dev/null
+++ b/lib/plugins/acl/lang/is/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Icelandic language file
+ *
+ * @author Hrannar Baldursson <hrannar.baldursson@gmail.com>
+ * @author Ólafur Gunnlaugsson <oli@audiotools.com>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ */
+$lang['acl_group'] = 'Hópur';
+$lang['acl_user'] = 'Notandi';
+$lang['page'] = 'Síða';
+$lang['namespace'] = 'Nafnrými';
+$lang['btn_select'] = 'Veldu';
+$lang['where'] = 'Síða/Nafnrými';
+$lang['acl_perm16'] = 'Eyða';
diff --git a/lib/plugins/acl/lang/it/help.txt b/lib/plugins/acl/lang/it/help.txt
new file mode 100644
index 000000000..8bf68e8e7
--- /dev/null
+++ b/lib/plugins/acl/lang/it/help.txt
@@ -0,0 +1,11 @@
+=== Breve Aiuto: ===
+
+In questa pagina puoi aggiungere e rimuovere permessi per categorie e pagine del tuo wiki.
+
+Il pannello di sinistra mostra tutte le categorie e le pagine disponibili.
+
+Il campo sopra ti permette di vedere e modificare i permessi di un utente o gruppo selezionato.
+
+Nella tabella sotto, sono riportate tutte le regole di controllo degli accessi attualmente impostate. Puoi utilizzarla per eliminare o cambiare al volo varie regole.
+
+Leggere la [[doku>acl|documentazione ufficale delle ACL]] può aiutarti a capire pienamente come funziona il controllo degli accessi in DokuWiki.
diff --git a/lib/plugins/acl/lang/it/lang.php b/lib/plugins/acl/lang/it/lang.php
new file mode 100644
index 000000000..f789b979f
--- /dev/null
+++ b/lib/plugins/acl/lang/it/lang.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Italian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Giorgio Vecchiocattivi <giorgio@vecchio.it>
+ * @author Roberto Bolli <http://www.rbnet.it/>
+ * @author Pietro Battiston toobaz@email.it
+ * @author Diego Pierotto ita.translations@tiscali.it
+ * @author ita.translations@tiscali.it
+ * @author Lorenzo Breda <lbreda@gmail.com>
+ * @author snarchio@alice.it
+ * @author robocap <robocap1@gmail.com>
+ * @author Osman Tekin osman.tekin93@hotmail.it
+ * @author Jacopo Corbetta <jacopo.corbetta@gmail.com>
+ */
+$lang['admin_acl'] = 'Gestione Lista Controllo Accessi (ACL)';
+$lang['acl_group'] = 'Gruppo';
+$lang['acl_user'] = 'Utente';
+$lang['acl_perms'] = 'Permessi per';
+$lang['page'] = 'Pagina';
+$lang['namespace'] = 'Categoria';
+$lang['btn_select'] = 'Seleziona';
+$lang['p_user_id'] = 'L\'utente <b class="acluser">%s</b> attualmente ha i seguenti permessi sulla pagina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'L\'utente <b class="acluser">%s</b> attualmente ha i seguenti permessi per la categoria <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'I membri del gruppo<b class="aclgroup">%s</b> attualmente hanno i seguenti permessi sulla pagina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'I membri del gruppo<b class="aclgroup">%s</b> attualmente hanno i seguenti permessi per la categoria <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = '<b>Inserisci un utente o gruppo</b> nel campo sopra per modificare i permessi impostati per la pagina <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = '<b>Inserisci un utente o un gruppo</b> nel campo sopra per modificare i permessi impostati per la categoria <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Nota: questi permessi non sono stati esplicitamente impostati, ma sono stati ereditati da altri gruppi o da categorie superiori.';
+$lang['p_isadmin'] = 'Nota: il gruppo o utente selezionato ha sempre tutti i permessi perché è configurato come amministratore.';
+$lang['p_include'] = 'I permessi più elevati includono i permessi inferiori. I permessi Crea, Carica ed Elimina si applicano soltanto alle categorie e non alle pagine.';
+$lang['current'] = 'Regole ACL attuali';
+$lang['where'] = 'Pagina/Categoria';
+$lang['who'] = 'Utente/Gruppo';
+$lang['perm'] = 'Permessi';
+$lang['acl_perm0'] = 'Nessuno';
+$lang['acl_perm1'] = 'Lettura';
+$lang['acl_perm2'] = 'Modifica';
+$lang['acl_perm4'] = 'Crea';
+$lang['acl_perm8'] = 'Carica';
+$lang['acl_perm16'] = 'Elimina';
+$lang['acl_new'] = 'Aggiungi nuovo valore';
+$lang['acl_mod'] = 'Modifica valore';
diff --git a/lib/plugins/acl/lang/ja/help.txt b/lib/plugins/acl/lang/ja/help.txt
new file mode 100644
index 000000000..f7867f8e2
--- /dev/null
+++ b/lib/plugins/acl/lang/ja/help.txt
@@ -0,0 +1,11 @@
+=== クイックヘルプ: ===
+
+このページでは、Wiki内の名前空間とページに対する権限を追加・削除することができます。
+
+左側のボックスには存在する名前空間とページが表示されています。
+
+上記のフォームを使って、選択したユーザーもしくはグループの権限を閲覧・変更することができます。
+
+以下のテープルには、現在設定されているアクセスコントロールのルールが表示されています。このテーブルを使って、複数のルールを素早く変更・削除することが可能です。
+
+DokuWikiのアクセスコントロールについては、[[doku>acl|official documentation on ACL]] をお読み下さい。 \ No newline at end of file
diff --git a/lib/plugins/acl/lang/ja/lang.php b/lib/plugins/acl/lang/ja/lang.php
new file mode 100644
index 000000000..831fd2d5c
--- /dev/null
+++ b/lib/plugins/acl/lang/ja/lang.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * japanese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Davilin(Yuji Takenaka) <webmaster@davilin.com>
+ * @author Yuji Takenaka <webmaster@davilin.com>
+ * @author Ikuo Obataya <i.obataya@gmail.com>
+ * @author Daniel Dupriest <kououken@gmail.com>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ */
+$lang['admin_acl'] = 'アクセスコントロール管理';
+$lang['acl_group'] = 'グループ';
+$lang['acl_user'] = 'ユーザー';
+$lang['acl_perms'] = '権限を追加';
+$lang['page'] = '文書';
+$lang['namespace'] = '名前空間';
+$lang['btn_select'] = '選択';
+$lang['p_user_id'] = 'ユーザー <b class="acluser">%s</b> は、ページ <b class="aclpage">%s</b> に対して次の権限を持っています: <i>%s</i>';
+$lang['p_user_ns'] = 'ユーザー <b class="acluser">%s</b> は、名前空間 <b class="aclns">%s</b> に対して次の権限を持っています: <i>%s</i>';
+$lang['p_group_id'] = 'グループ <b class="aclgroup">%s</b> のメンバーは、ページ <b class="aclpage">%s</b> に対して次の権限を持っています: <i>%s</i>';
+$lang['p_group_ns'] = 'グループ <b class="aclgroup">%s</b> のメンバーは、名前空間 <b class="aclns">%s</b> に対して次の権限を持っています: <i>%s</i>';
+$lang['p_choose_id'] = 'ページ <b class="aclpage">%s</b> にセットされた権限を閲覧・編集するためには、上記のフォームに<b>ユーザー名もしくはグループ名を入力して下さい</b>。';
+$lang['p_choose_ns'] = '名前空間 <b class="aclns">%s</b> にセットされた権限を閲覧・編集するためには、上記のフォームに<b>ユーザー名もしくはグループ名を入力して下さい</b>。';
+$lang['p_inherited'] = '注意:これらの権限は明示されていませんが、他のグループもしくは上位の名前空間の権限を継承します。';
+$lang['p_isadmin'] = '注意:選択したグループもしくはユーザーはスーパーユーザーであるため、全ての権限があります。';
+$lang['p_include'] = '高次の権限は、それより低次の権限を含みます。作成・アップロード・削除の権限は、ページではなく名前空間のみに適用されます。';
+$lang['current'] = '現在のACLルール';
+$lang['where'] = 'ページ/名前空間';
+$lang['who'] = 'ユーザー/グループ';
+$lang['perm'] = '権限';
+$lang['acl_perm0'] = '無し';
+$lang['acl_perm1'] = '読取';
+$lang['acl_perm2'] = '編集';
+$lang['acl_perm4'] = '作成';
+$lang['acl_perm8'] = 'アップロード';
+$lang['acl_perm16'] = '削除';
+$lang['acl_new'] = '新規エントリ';
+$lang['acl_mod'] = 'エントリの編集';
diff --git a/lib/plugins/acl/lang/kk/lang.php b/lib/plugins/acl/lang/kk/lang.php
new file mode 100644
index 000000000..dde5b9577
--- /dev/null
+++ b/lib/plugins/acl/lang/kk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * kazakh language file
+ *
+ * @author Nurgozha Kaliaskarov astana08@gmail.com
+ */
diff --git a/lib/plugins/acl/lang/ko/help.txt b/lib/plugins/acl/lang/ko/help.txt
new file mode 100644
index 000000000..516198ee5
--- /dev/null
+++ b/lib/plugins/acl/lang/ko/help.txt
@@ -0,0 +1,11 @@
+=== 도움말: ===
+
+현재 페이지에서 위키 네임스페이스와 페이지에 대한 접근 권한을 추가하거나 삭제할 수 있습니다.
+
+왼쪽 영역을 선택가능한 네임스페이스들과 페이지 목록을 보여줍니다.
+
+위쪽 입력 양식에서 선택된 사용자와 그룹의 접근 권한을 보거나 변경할 수 있습니다.
+
+아래 테이블에서 현재 설정된 모든 접근 제어 규칙들을 볼 수 있으며, 즉시 여러 규칙들을 삭제하거나 변경할 수 있습니다.
+
+DokuWiki에서 접근 제어가 어떻게 동작되는지 알려면 [[doku>acl|official documentation on ACL]] 읽기 바랍니다. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/ko/lang.php b/lib/plugins/acl/lang/ko/lang.php
new file mode 100644
index 000000000..6f4e991cb
--- /dev/null
+++ b/lib/plugins/acl/lang/ko/lang.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * korean language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author jk Lee
+ * @author dongnak@gmail.com
+ * @author Song Younghwan <purluno@gmail.com>
+ * @author SONG Younghwan <purluno@gmail.com>
+ * @author Seung-Chul Yoo <dryoo@live.com>
+ */
+$lang['admin_acl'] = '접근 제어 목록 관리';
+$lang['acl_group'] = '그룹';
+$lang['acl_user'] = '사용자';
+$lang['acl_perms'] = '권한';
+$lang['page'] = '페이지';
+$lang['namespace'] = '네임스페이스';
+$lang['btn_select'] = '선택';
+$lang['p_user_id'] = '사용자 <b class="acluser">%s</b>는 현재 <b class="aclpage">%s</b>: <i>%s</i> 페이지 접근이 가능합니다.';
+$lang['p_user_ns'] = '사용자 <b class="acluser">%s</b>는 현재 <b class="aclns">%s</b>: <i>%s</i> 네임스페이스 접근이 가능합니다.';
+$lang['p_group_id'] = '그룹 <b class="aclgroup">%s</b> 사용자는 현재 <b class="aclpage">%s</b>: <i>%s</i> 페이지 접근이 가능합니다.';
+$lang['p_group_ns'] = '그룹 <b class="aclgroup">%s</b> 사용자는 현재 <b class="aclns">%s</b>: <i>%s</i> 네임스페이스 접근이 가능합니다.';
+$lang['p_choose_id'] = '<b class="aclpage">%s</b> 페이지 접근 권한을 보거나 변경하려면 <b>사용자</b>나 <b>그룹</b>을 위 양식에 입력하기 바랍니다.';
+$lang['p_choose_ns'] = '<b class="aclns">%s</b> 네임스페이스 접근 권한을 보거나 변경하려면 <b>사용자</b>나 <b>그룹</b>을 위 양식에 입력하기 바랍니다.';
+$lang['p_inherited'] = '주의: 권한이 명시적으로 설정되지 않았으므로 다른 그룹들이나 상위 네임스페이스로 부터 가져왔습니다.';
+$lang['p_isadmin'] = '주의: 슈퍼유저로 설정되어 있으므로 선택된 그룹이나 사용자는 언제나 모든 접근 권한을 가집니다.';
+$lang['p_include'] = '더 높은 접근권한은 하위를 포함합니다. 페이지가 아닌 네임스페이스에는 생성, 업로드, 삭제 권한만 적용됩니다.';
+$lang['current'] = '현 ACL 규칙';
+$lang['where'] = '페이지/네임스페이스';
+$lang['who'] = '사용자/그룹';
+$lang['perm'] = '접근 권한';
+$lang['acl_perm0'] = '없음';
+$lang['acl_perm1'] = '읽기';
+$lang['acl_perm2'] = '수정';
+$lang['acl_perm4'] = '생성';
+$lang['acl_perm8'] = '업로드';
+$lang['acl_perm16'] = '삭제';
+$lang['acl_new'] = '새 항목 추가';
+$lang['acl_mod'] = '선택 항목 변경';
diff --git a/lib/plugins/acl/lang/la/help.txt b/lib/plugins/acl/lang/la/help.txt
new file mode 100644
index 000000000..553884c30
--- /dev/null
+++ b/lib/plugins/acl/lang/la/help.txt
@@ -0,0 +1,11 @@
+=== Auxilium: ===
+
+Hic facultates generum paginarumque addere delereue potes.
+
+Tabella sinistra omnes paginas generaque ostendit.
+
+His campis mutare facultates electorum Sodalium Gregumque potes.
+
+In tabula omnes administrationis leges ostensae sunt. Delere quoque uel mutare plures leges potes.
+
+Si [[doku>acl|official documentation on ACL]] legas, maius auxilium in Vicem mutando habes. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/la/lang.php b/lib/plugins/acl/lang/la/lang.php
new file mode 100644
index 000000000..941de1f79
--- /dev/null
+++ b/lib/plugins/acl/lang/la/lang.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Latin language file
+ *
+ * @author Massimiliano Vassalli <vassalli.max@gmail.com>
+ */
+$lang['admin_acl'] = 'Administratio Indicis Custodiae Aditus';
+$lang['acl_group'] = 'Grex';
+$lang['acl_user'] = 'Sodalis';
+$lang['acl_perms'] = 'Facultas:';
+$lang['page'] = 'Pagina';
+$lang['namespace'] = 'Genus';
+$lang['btn_select'] = 'eligere';
+$lang['p_user_id'] = 'Sodalis <b class="acluser">%s</b> nunc has facultates paginae "<b class="aclpage">%s</b> habes: <i>%s</i>.';
+$lang['p_user_ns'] = 'Sodalis <b class="acluser">%s</b> nunc has facultates generis "<b class="aclns">%s</b> habes: <i>%s</i>.';
+$lang['p_group_id'] = 'Socius\a gregis <b class="aclgroup">%s</b> nunc has facultates paginae "<b class="aclpage">%s</b> habes: <i>%s</i>.';
+$lang['p_group_ns'] = 'Socius\a gregis <b class="aclgroup">%s</b> nunc has facultates generis "<b class="aclns">%s</b> habes: <i>%s</i>.';
+$lang['p_choose_id'] = '<b>Sodalis grexue</b> in campo insere ut facultates paginae <b class="aclpage">%s</b> uideas.';
+$lang['p_choose_ns'] = '<b>Sodalis grexue</b> in campo insere ut facultates generis <b class="aclns">%s</b> uideas.';
+$lang['p_inherited'] = 'Caue: hae facultates et huic rei et aliis gregibus uel generibus legitimae sunt.';
+$lang['p_isadmin'] = 'Caue: electi greges semper plenum ius habent, eo quod ut magister\stra elegitur.';
+$lang['p_include'] = 'Maiores facultates minores includunt. Creandi, onerandi uel delendi facultates solum generibus, non paginis sunt.';
+$lang['current'] = 'Communes ICA leges';
+$lang['where'] = 'Pagina/Genus';
+$lang['who'] = 'Sodalis/Grex';
+$lang['perm'] = 'Facultates';
+$lang['acl_perm0'] = 'Nihil';
+$lang['acl_perm1'] = 'Legere';
+$lang['acl_perm2'] = 'Recensere';
+$lang['acl_perm4'] = 'Creare';
+$lang['acl_perm8'] = 'Onerare';
+$lang['acl_perm16'] = 'Delere';
+$lang['acl_new'] = 'Nouom addere';
+$lang['acl_mod'] = 'Nouom recensere';
diff --git a/lib/plugins/acl/lang/lb/help.txt b/lib/plugins/acl/lang/lb/help.txt
new file mode 100644
index 000000000..e36ed373f
--- /dev/null
+++ b/lib/plugins/acl/lang/lb/help.txt
@@ -0,0 +1,11 @@
+=== Séier Hëllef: ===
+
+Op dëser Säit kanns de Rechter fir Namespacen a Säiten an dengem Wiki setzen.
+
+Op der lénkser Säit hues de all d'Namespacen a Säiten.
+
+Am Formulär hei uewendriwwer kanns de d'Rechter vun dem ausgewielte Benotzer oder Grupp änneren
+
+An der Tabell hei ënnendrënner kanns de all d'Reegele gesinn déi de Moment gesat sinn. Du kanns se huelen fir Reegelen ze änneren oder ze läschen.
+
+Déi [[doku>acl|offiziell Dokumentatioun iwwert ACL]] hëlleft der besser ze verstoen wéi déi Reegelen am Dokuwiki funktionéieren.
diff --git a/lib/plugins/acl/lang/lb/lang.php b/lib/plugins/acl/lang/lb/lang.php
new file mode 100644
index 000000000..59acdf7a8
--- /dev/null
+++ b/lib/plugins/acl/lang/lb/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * lb language file
+ *
+ * @author joel@schintgen.net
+ */
diff --git a/lib/plugins/acl/lang/lt/lang.php b/lib/plugins/acl/lang/lt/lang.php
new file mode 100644
index 000000000..f11944746
--- /dev/null
+++ b/lib/plugins/acl/lang/lt/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * lithuanian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Linas Valiukas <shirshegsm@gmail.com>
+ * @author audrius.klevas@gmail.com
+ * @author Arunas Vaitekunas <aras@fan.lt>
+ */
+$lang['admin_acl'] = 'Priėjimo Kontrolės Sąrašų valdymas';
+$lang['acl_group'] = 'Grupė';
+$lang['acl_user'] = 'Vartotojas';
+$lang['acl_perms'] = 'Leidimai';
+$lang['page'] = 'Puslapis';
+$lang['namespace'] = 'Pavadinimas';
+$lang['btn_select'] = 'Rinktis';
+$lang['acl_perm1'] = 'Skaityti';
+$lang['acl_perm2'] = 'Redaguoti';
+$lang['acl_perm4'] = 'Sukurti';
+$lang['acl_perm8'] = 'Atsiųsti';
+$lang['acl_perm16'] = 'Ištrinti';
+$lang['acl_new'] = 'Pridėti naują įrašą';
diff --git a/lib/plugins/acl/lang/lv/help.txt b/lib/plugins/acl/lang/lv/help.txt
new file mode 100644
index 000000000..f570d798c
--- /dev/null
+++ b/lib/plugins/acl/lang/lv/help.txt
@@ -0,0 +1,11 @@
+=== Īsa palīdzība ===
+
+Šajā lapā var uzdot un noņemt tiesības uz lapām un nodaļām.
+
+Kreisajā pusē parādītas visas pieejamās nodaļas un lapas.
+
+Formā augšpusē var redzēt un grozīt norādītā lietotāja vai grupas tiesības .
+
+Apakšā tabulā parādīts visu tiesību saraksts. To var lietot, lai ātri mainītu vairākus pieejas tiesību noteikumus.
+
+[[doku>acl|Officiālajos piekļuves tiesību noteikumu dokumentos]] var atrast izvērstu informāciju, kā darbojas DokuWiki sistēmas piekļuves tiesību kontrole.
diff --git a/lib/plugins/acl/lang/lv/lang.php b/lib/plugins/acl/lang/lv/lang.php
new file mode 100644
index 000000000..f478b32c6
--- /dev/null
+++ b/lib/plugins/acl/lang/lv/lang.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * latvian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['admin_acl'] = 'Piekļuves tiesību vadība';
+$lang['acl_group'] = 'Grupa';
+$lang['acl_user'] = 'Lietotājs';
+$lang['acl_perms'] = 'Tiesības';
+$lang['page'] = 'Lapa';
+$lang['namespace'] = 'Nodaļa';
+$lang['btn_select'] = 'Izvēlēties';
+$lang['p_user_id'] = 'Lietotājam <b class="acluser">%s</b> ir tiesības <i>%s</i> lapu <b class="aclpage">%s</b> .';
+$lang['p_user_ns'] = 'Lietotājam <b class="acluser">%s</b> nodaļā <b class="aclns">%s</b> ir tiesības <i>%s</i>.';
+$lang['p_group_id'] = 'Grupas <b class="aclgroup">%s</b> biedriem ir tiesības <i>%s</i> lapu <b class="aclpage">%s</b>.';
+$lang['p_group_ns'] = 'Grupas <b class="aclgroup">%s</b> biedriem ir tiesības <i>%s</i> nodaļu <b class="aclns">%s</b>: .';
+$lang['p_choose_id'] = 'Lūdzu <b>ieraksti lietotāju vai grupu</b> augstāk norādītajā laukā, lai skatītu vai labotu tiesības lapai <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Lūdzu <b>ieraksti lietotāju vai grupu</b> augstāk norādītajā laukā, lai skatītu vai labotu tiesības nodaļai <b class="aclpage">%s</b>.';
+$lang['p_inherited'] = 'Ievēro: Šīs tiesības nav tieši uzdotas, bet mantotas no citām grupām vai augstākām nodaļām. ';
+$lang['p_isadmin'] = 'Ievēro: Norādītajai grupai vai lietotājam vienmēr ir visas tiesības, jo tas konfigurēts kā <i>superuser</i>.';
+$lang['p_include'] = 'Augstāka atļauja iekļauj arī zemākās tiesības. Izveidošanas, augšupielādēšanas un dzēšanas tiesības attiecas tikai uz nodaļām, nevis lapām.';
+$lang['current'] = 'Patreizējo tiesību saraksts (ACL)';
+$lang['where'] = 'Lapa/nodaļa';
+$lang['who'] = 'Lietotājs/grupa';
+$lang['perm'] = 'Tiesības';
+$lang['acl_perm0'] = 'nekādas';
+$lang['acl_perm1'] = 'lasīt';
+$lang['acl_perm2'] = 'labot';
+$lang['acl_perm4'] = 'izveidot';
+$lang['acl_perm8'] = 'augšupielādēt';
+$lang['acl_perm16'] = 'dzēst';
+$lang['acl_new'] = 'pievienot jaunu šķirkli';
+$lang['acl_mod'] = 'labot šķirkli';
diff --git a/lib/plugins/acl/lang/mk/lang.php b/lib/plugins/acl/lang/mk/lang.php
new file mode 100644
index 000000000..d576c3d1d
--- /dev/null
+++ b/lib/plugins/acl/lang/mk/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Macedonian language file
+ *
+ * @author Dimitar Talevski <dimi3.14@gmail.com>
+ */
+$lang['acl_group'] = 'Група';
+$lang['acl_user'] = 'Корисник';
+$lang['acl_perms'] = 'Пермисии за';
+$lang['page'] = 'Страница';
+$lang['btn_select'] = 'Избери';
+$lang['current'] = 'Моментални ACL правила';
+$lang['who'] = 'Корисник/група';
+$lang['perm'] = 'Пермисии';
+$lang['acl_perm0'] = 'Ништо';
+$lang['acl_perm1'] = 'Читај';
+$lang['acl_perm2'] = 'Уреди';
+$lang['acl_perm4'] = 'Креирај';
+$lang['acl_perm8'] = 'Качи';
+$lang['acl_perm16'] = 'Избриши';
+$lang['acl_new'] = 'Додај нов запис';
+$lang['acl_mod'] = 'Измени запис';
diff --git a/lib/plugins/acl/lang/mr/help.txt b/lib/plugins/acl/lang/mr/help.txt
new file mode 100644
index 000000000..e8aa13b52
--- /dev/null
+++ b/lib/plugins/acl/lang/mr/help.txt
@@ -0,0 +1,12 @@
+=== त्वरित मदत ===
+
+या पानावर तुमची तुमच्या विकी मधील पाने किंवा नेमस्पेस वरील परवानग्या बदलू शकता.
+
+डाविकडील मार्जिन मधे सर्व उपलब्ध पाने आणि नेमस्पेस दाखवले आहेत.
+
+वरील फॉर्म वापरून तुमची निवडलेल्या सदस्य किंवा गटाच्या परवानग्या बदलू शकता.
+
+खालील टेबल मधे सध्या सेट असलेले नियम दिलेले आहेत.
+हे टेबल वापरून तुम्ही चटकन हे नियम बदलू शकता.
+
+[[doku>acl| ACL वरील अधिकृत माहितीसंग्रह ]] वाचून तुम्हाला डॉक्युविकिमधे परवानगीची व्यवस्था कशी काम करते ते नीट समजेल. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/mr/lang.php b/lib/plugins/acl/lang/mr/lang.php
new file mode 100644
index 000000000..978df758a
--- /dev/null
+++ b/lib/plugins/acl/lang/mr/lang.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Marathi language file
+ *
+ * @author ghatothkach@hotmail.com
+ * @author Padmanabh Kulkarni <kulkarnipadmanabh@gmail.com>
+ * @author Padmanabh Kulkarni<kulkarnipadmanabh@gmail.com>
+ * @author shantanoo@gmail.com
+ */
+$lang['admin_acl'] = 'Access Control List व्यवस्थापन';
+$lang['acl_group'] = 'गट';
+$lang['acl_user'] = 'सदस्य';
+$lang['acl_perms'] = 'परवानगी \'च्या साठी';
+$lang['page'] = 'पान';
+$lang['namespace'] = 'नेमस्पेस';
+$lang['btn_select'] = 'निवडा';
+$lang['p_user_id'] = '<b class="acluser">%s</b> ह्या सदस्याला सध्या <b class="aclpage">%s</b> या पानावर पुढील परवानग्या आहेत : <i>%s</i>.';
+$lang['p_user_ns'] = '<b class="acluser">%s</b> या सदस्याला सध्या <b class="aclns">%s</b> या नेमस्पेसवर पुढील परवानग्या आहेत : <i>%s</i>.';
+$lang['p_group_id'] = '<b class="aclgroup">%s</b> या गटाच्या सदस्याना सध्या <b class="aclpage">%s</b> या पानावर पुढील परवानग्या आहेत : <i>%s</i>.';
+$lang['p_group_ns'] = '<b class="aclgroup">%s</b> या गटाच्या सदस्याना सध्या <b class="aclns">%s</b> या नेमस्पेसवर पुढील परवानग्या आहेत : <i>%s</i>.';
+$lang['p_choose_id'] = 'वरील फॉर्म मधे एखाद्या <b>सदस्य किंवा गटाचे </b> नाव टाकुन <b class="aclpage">%s</b> या पानासाठी त्यांच्या परवानग्या पाहू/बदलू शकता.';
+$lang['p_choose_ns'] = 'वरील फॉर्म मधे एखाद्या <b>सदस्य किंवा गटाचे </b> नाव टाकुन <b class="aclns">%s</b> या नेमस्पेससाठी त्यांच्या परवानग्या पाहू/बदलू शकता.';
+$lang['p_inherited'] = 'टीप : ह्या परवानग्या प्रत्यक्ष सेट केल्या नसून त्या इतर गट किंवा अधिक उच्च नेमस्पेस कडून वारसाहक्काने :) आल्या आहेत.';
+$lang['p_isadmin'] = 'टीप : निवडलेल्या सदस्य किंवा गटाला कायम सर्व परवानग्या असतात कारण तो सुपर सदस्य म्हणुन सेट केला आहे.';
+$lang['p_include'] = 'उच्च परवानग्यांमधे त्याखालिल परवानग्या अध्याहृत असतात. क्रिएट, अपलोड आणि डिलीट परवानग्या फ़क्त नामसमुहावर (नेमस्पेस) लागू असतात, पानांवर नाही.';
+$lang['current'] = 'सद्य ACL नियम';
+$lang['where'] = 'पान/नेमस्पेस';
+$lang['who'] = 'सदस्य/गट';
+$lang['perm'] = 'परवानग्या';
+$lang['acl_perm0'] = 'काही नाही.';
+$lang['acl_perm1'] = 'वाचन';
+$lang['acl_perm2'] = 'संपादन';
+$lang['acl_perm4'] = 'निर्माण';
+$lang['acl_perm8'] = 'अपलोड';
+$lang['acl_perm16'] = 'डिलीट';
+$lang['acl_new'] = 'नवीन एंट्री करा';
+$lang['acl_mod'] = 'एंट्री बदला';
diff --git a/lib/plugins/acl/lang/ms/lang.php b/lib/plugins/acl/lang/ms/lang.php
new file mode 100644
index 000000000..77ad2a1c1
--- /dev/null
+++ b/lib/plugins/acl/lang/ms/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Malay language file
+ *
+ * @author Markos
+ */
diff --git a/lib/plugins/acl/lang/ne/lang.php b/lib/plugins/acl/lang/ne/lang.php
new file mode 100644
index 000000000..6a29a9fa8
--- /dev/null
+++ b/lib/plugins/acl/lang/ne/lang.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Nepali language file
+ *
+ * @author Saroj Kumar Dhakal <lotusnagarkot@gmail.com>
+ * @author SarojKumar Dhakal <lotusnagarkot@yahoo.com>
+ * @author Saroj Dhakal<lotusnagarkot@yahoo.com>
+ */
+$lang['admin_acl'] = 'एक्सेस कन्ट्रोल लिस्ट व्यवस्थापन';
+$lang['acl_group'] = 'समूह';
+$lang['acl_user'] = 'प्रोगकर्ता';
+$lang['acl_perms'] = 'को लागि अनुमति';
+$lang['page'] = 'पृष्ठ';
+$lang['namespace'] = 'नेमस्पेस';
+$lang['btn_select'] = 'छान्नुहोस्';
+$lang['current'] = 'हालैको ACL नियमहरु ';
+$lang['where'] = 'पृष्ठ / नेमस्पेस';
+$lang['who'] = 'प्रयोगकर्ता / समूह ';
+$lang['perm'] = 'अनुमति';
+$lang['acl_perm0'] = 'कुनै पनि होइन';
+$lang['acl_perm1'] = 'पठन गर्नुहोस्';
+$lang['acl_perm2'] = 'सम्पादन गर्नुहोस्';
+$lang['acl_perm4'] = 'निर्माण गर्नुहोस्';
+$lang['acl_perm8'] = 'अपलोड गर्नुहोस्';
+$lang['acl_perm16'] = 'मेटाउनुहोस्';
+$lang['acl_new'] = 'नयाँ प्रविष्ठि गर्नुहोस्';
+$lang['acl_mod'] = 'प्रविष्ठि सच्याउनुहोस्';
diff --git a/lib/plugins/acl/lang/nl/help.txt b/lib/plugins/acl/lang/nl/help.txt
new file mode 100644
index 000000000..255f21ba0
--- /dev/null
+++ b/lib/plugins/acl/lang/nl/help.txt
@@ -0,0 +1,11 @@
+=== Snelle hulp: ===
+
+Op deze pagina kun je bevoegdheden toevoegen en verwijderen voor namespaces en pagina's in je wiki.
+
+Het linkerpaneel geeft alle beschikbare namespaces en pagina's weer.
+
+In het formulier hierboven kun je bevoegdheden zien en aanpassen voor een selecteerde gebruiker of groep.
+
+In de tabel hieronder worden alle momenteel ingestelde toegangsregels weergegeven. Je kunt hier snel regels wijzigen of verwijderen.
+
+Lees de [[doku>acl|documentatie over ACLs]] om de mogelijkheden volledig te begrijpen.
diff --git a/lib/plugins/acl/lang/nl/lang.php b/lib/plugins/acl/lang/nl/lang.php
new file mode 100644
index 000000000..cb0765505
--- /dev/null
+++ b/lib/plugins/acl/lang/nl/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * dutch language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author François Kooman <fkooman.tuxed.net>
+ * @author Jack van Klaren <dokuwiki@afentoe.xs4all.nl>
+ * @author Riny Heijdendael <riny@heijdendael.nl>
+ * @author Koen Huybrechts <huybkoen@gmail.com>
+ * @author Wouter Schoot <wouter@schoot.org>
+ * @author John de Graaff <john@de-graaff.net>
+ * @author Niels Schoot <niels.schoot@quintiq.com>
+ * @author Dion Nicolaas <dion@nicolaas.net>
+ * @author Danny Rotsaert <danny.rotsaert@edpnet.be>
+ * @author Marijn Hofstra hofstra.m@gmail.com
+ * @author Matthias Carchon webmaster@c-mattic.be
+ * @author Marijn Hofstra <hofstra.m@gmail.com>
+ * @author Timon Van Overveldt <timonvo@gmail.com>
+ * @author Jeroen
+ * @author Ricardo Guijt <ricardoguijt@gmail.com>
+ */
+$lang['admin_acl'] = 'Toegangsrechten';
+$lang['acl_group'] = 'Groep';
+$lang['acl_user'] = 'Gebruiker';
+$lang['acl_perms'] = 'Permissies voor';
+$lang['page'] = 'Pagina';
+$lang['namespace'] = 'Namespace';
+$lang['btn_select'] = 'Selecteer';
+$lang['p_user_id'] = 'Gebruiker <b class="acluser">%s</b> heeft momenteel de volgende bevoegdheden op pagina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Gebruiker <b class="acluser">%s</b> heeft momenteel de volgende bevoegdheden op namespace <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Leden van groep <b class="aclgroup">%s</b> hebben momenteel de volgende bevoegdheden op pagina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Leden van groep <b class="aclgroup">%s</b>hebben momenteel de volgende bevoegdheden op namespace <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Vul een <b>gebruiker of groep</b> in in het bovenstaande formulier om de bevoegdheden te bekijken of te bewerken voor de pagina <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Vul een <b>gebruiker of groep</b> in in het bovenstaande formulier om de bevoegdheden te bekijken of te bewerken voor de namespace <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Let op: Deze permissies zijn niet expliciet ingesteld maar overerfd van andere groepen of hogere namespaces.';
+$lang['p_isadmin'] = 'Let op: De geselecteerde groep of gebruiker heeft altijd volledige toegangsrechten omdat hij als superuser geconfigureerd is.';
+$lang['p_include'] = 'Hogere permissies bevatten ook de lagere. Aanmaken, uploaden en verwijderen gelden alleen voor namespaces, niet voor pagina\'s.';
+$lang['current'] = 'Huidige ACL regels';
+$lang['where'] = 'Pagina/namespace';
+$lang['who'] = 'Gebruiker/Groep';
+$lang['perm'] = 'Bevoegdheden';
+$lang['acl_perm0'] = 'Geen';
+$lang['acl_perm1'] = 'Lezen';
+$lang['acl_perm2'] = 'Bewerken';
+$lang['acl_perm4'] = 'Aanmaken';
+$lang['acl_perm8'] = 'Uploaden';
+$lang['acl_perm16'] = 'Verwijderen';
+$lang['acl_new'] = 'Nieuwe regel toevoegen';
+$lang['acl_mod'] = 'Regel aanpassen';
diff --git a/lib/plugins/acl/lang/no/help.txt b/lib/plugins/acl/lang/no/help.txt
new file mode 100644
index 000000000..c3d3688a9
--- /dev/null
+++ b/lib/plugins/acl/lang/no/help.txt
@@ -0,0 +1,11 @@
+=== Hurtighjelp: ===
+
+På denne siden kan du legge til og fjerne tillatelser for navnerom og sider i din wiki.
+
+Venstre panel viser alle tilgjengelige navnerom og sider.
+
+Skjemaet over tillater deg å se og modifisere tillatelser for en valgt bruker eller gruppe.
+
+I tabellen nedenfor vises alle nærværende satte adgangskontroll-regler. Du kan bruke den til raskt å slette eller endre mange regler i slengen.
+
+Å lese [[doku>acl|den offisielle dokumentasjonen for ACL]] kan hjelpe deg å fullt ut forstå hvordan adgangskontroll fungerer i DokuWiki.
diff --git a/lib/plugins/acl/lang/no/lang.php b/lib/plugins/acl/lang/no/lang.php
new file mode 100644
index 000000000..09d71937a
--- /dev/null
+++ b/lib/plugins/acl/lang/no/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Norwegian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Reidar Mosvold <Reidar.Mosvold@hit.no>
+ * @author Jorge Barrera Grandon <jorge@digitalwolves.org>
+ * @author Thomas Nygreen <nygreen@gmail.com>
+ * @author Arild Burud <arildb@met.no>
+ * @author Torkill Bruland <torkar-b@online.no>
+ * @author Rune M. Andersen <rune.andersen@gmail.com>
+ * @author Jakob Vad Nielsen (me@jakobnielsen.net)
+ * @author Kjell Tore Næsgaard <kjell.t.nasgaard@ntnu.no>
+ * @author Knut Staring <knutst@gmail.com>
+ * @author Lisa Ditlefsen <lisa@vervesearch.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author Rune Rasmussen syntaxerror.no@gmail.com
+ * @author Jon Bøe <jonmagneboe@hotmail.com>
+ * @author Egil Hansen <egil@rosetta.no>
+ */
+$lang['admin_acl'] = 'Administrasjon av lister for adgangskontroll (ACL)';
+$lang['acl_group'] = 'Gruppe';
+$lang['acl_user'] = 'Bruker';
+$lang['acl_perms'] = 'Rettigheter for';
+$lang['page'] = 'Side';
+$lang['namespace'] = 'Navnerom';
+$lang['btn_select'] = 'Velg';
+$lang['p_user_id'] = 'Bruker <b class="acluser">%s</b> har for tiden følgende tillatelser i for siden <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Bruker <b class="acluser">%s</b> har for tiden følgende tillatelser i navnerom <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Medlemmer av gruppe <b class="aclgroup">%s</b> har for tiden følgende tillatelser i for siden <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Medlemmer av gruppe <b class="aclgroup">%s</b> har for tiden følgende tillatelser i navnerom <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = '<b>Før inn en bruker eller gruppe</b> i skjemaet over for å vise eller redigere tillatelser satt for siden <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = '<b>Før inn en bruker eller gruppe</b> i skjemaet over for å vise eller redigere tillatelser satt for navnerommet <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Merk: Disse tillatelser ble ikke eksplisitt satt, men ble arvet fra andre grupper eller høyere navnerom.';
+$lang['p_isadmin'] = 'Merk: Den valgte gruppen eller bruker har altid fulle tillatelser fordi vedkommende er konfigurert som superbruker.';
+$lang['p_include'] = 'Høyere tillgangsrettigheter inkluderer lavere. Rettigheter for å opprette, laste opp og slette gjelder bare for navnerom, ikke enkeltsider.';
+$lang['current'] = 'Gjeldende ACL-regler';
+$lang['where'] = 'Side/Navnerom';
+$lang['who'] = 'Bruker/Gruppe';
+$lang['perm'] = 'Rettigheter';
+$lang['acl_perm0'] = 'Ingen';
+$lang['acl_perm1'] = 'Lese';
+$lang['acl_perm2'] = 'Redigere';
+$lang['acl_perm4'] = 'Opprette';
+$lang['acl_perm8'] = 'Laste opp';
+$lang['acl_perm16'] = 'Slette';
+$lang['acl_new'] = 'Legg til ny oppføring';
+$lang['acl_mod'] = 'Endre oppføring';
diff --git a/lib/plugins/acl/lang/pl/help.txt b/lib/plugins/acl/lang/pl/help.txt
new file mode 100644
index 000000000..331fd2a7a
--- /dev/null
+++ b/lib/plugins/acl/lang/pl/help.txt
@@ -0,0 +1,11 @@
+=== Pomoc ===
+
+Na tej stronie możesz zmienić uprawnienia do stron i katalogów w wiki.
+
+Lewy panel pokazuje wszystkie dostępne katalogi i strony.
+
+Formularz powyżej pozwala wyświetlać uprawnienia wybranego użytkownika oraz grupy.
+
+W tabeli poniżej znajdują się wszystkie aktywne reguły dotyczące uprawnień.
+
+Więcej informacji na temat uprawnień w DokuWiki możesz znaleźć w [[doku>acl|oficjalnej dokumentacji uprawnień]].
diff --git a/lib/plugins/acl/lang/pl/lang.php b/lib/plugins/acl/lang/pl/lang.php
new file mode 100644
index 000000000..1b10b5232
--- /dev/null
+++ b/lib/plugins/acl/lang/pl/lang.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * polish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Grzegorz Żur <grzegorz.zur@gmail.com>
+ * @author Mariusz Kujawski <marinespl@gmail.com>
+ * @author Maciej Kurczewski <pipijajko@gmail.com>
+ * @author Sławomir Boczek <slawkens@gmail.com>
+ * @author sleshek@wp.pl
+ * @author Leszek Stachowski <shazarre@gmail.com>
+ * @author maros <dobrimaros@yahoo.pl>
+ * @author Grzegorz Widła <dzesdzes@gmail.com>
+ * @author Łukasz Chmaj <teachmeter@gmail.com>
+ * @author Begina Felicysym <begina.felicysym@wp.eu>
+ */
+$lang['admin_acl'] = 'Zarządzanie uprawnieniami';
+$lang['acl_group'] = 'Grupa';
+$lang['acl_user'] = 'Użytkownik';
+$lang['acl_perms'] = 'Uprawnienia użytkownika';
+$lang['page'] = 'Strona';
+$lang['namespace'] = 'Katalog';
+$lang['btn_select'] = 'Wybierz';
+$lang['p_user_id'] = 'Użytkownik <b class="acluser">%s</b> posiada następujące uprawnienia do strony <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Użytkownik <b class="acluser">%s</b> posiada następujące uprawnienia do katalogów <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Członkowie grupy <b class="aclgroup">%s</b> posiadają następujące uprawnienia do strony <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Członkowie grupy <b class="aclgroup">%s</b> posiadają następujące uprawnienia do katalogu <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Podaj <b>nazwę użytkownika lub grupy</b> w powyższym formularzu, by wyświetlić lub zmienić uprawnienia do strony <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Podaj <b>nazwę użytkownika lub grupy</b> w powyższym formularzu, by wyświetlić lub zmienić uprawnienia do katalogu <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Uwaga: Uprawnienia nie zostały nadane wprost ale są dziedziczone z grupy lub katalogu.';
+$lang['p_isadmin'] = 'Uwaga: Wybrana grupa lub użytkownika zawsze dysponuje pełnymi uprawnieniami ponieważ posiada uprawnienia administratora.';
+$lang['p_include'] = 'Szersze uprawnienia zawierają węższe. Tworzenie, przesyłanie plików oraz usuwanie mają znaczenie tylko dla katalogów, nie dla stron.';
+$lang['current'] = 'Aktywne reguły zarządzania uprawnieniami';
+$lang['where'] = 'Strona/Katalog';
+$lang['who'] = 'Użytkownik/Grupa';
+$lang['perm'] = 'Uprawnienie';
+$lang['acl_perm0'] = 'Żadne';
+$lang['acl_perm1'] = 'Czytanie';
+$lang['acl_perm2'] = 'Zmiana';
+$lang['acl_perm4'] = 'Tworzenie';
+$lang['acl_perm8'] = 'Przesyłanie plików';
+$lang['acl_perm16'] = 'Usuwanie';
+$lang['acl_new'] = 'Dodaj nowy wpis';
+$lang['acl_mod'] = 'Zmień wpis';
diff --git a/lib/plugins/acl/lang/pt-br/help.txt b/lib/plugins/acl/lang/pt-br/help.txt
new file mode 100644
index 000000000..b2a49a90d
--- /dev/null
+++ b/lib/plugins/acl/lang/pt-br/help.txt
@@ -0,0 +1,11 @@
+=== Ajuda rápida: ===
+
+Nessa página você pode adicionar e remover permissões para espaços de nomes e páginas do seu wiki.
+
+O painel à esquerda mostra todos os espaços de nomes e páginas disponíveis.
+
+O formulário acima permite a visualização e modificação das permissões de um determinado usuário ou grupo.
+
+Na tabela abaixo são exibidas todas as regras de controle de acesso definidas. Você pode usá-la para excluir ou mudar rapidamente várias regras.
+
+A leitura da [[doku>acl|documentação oficial sobre ACL]] pode ajudar a compreender melhor como o controle de acessos funciona no DokuWiki.
diff --git a/lib/plugins/acl/lang/pt-br/lang.php b/lib/plugins/acl/lang/pt-br/lang.php
new file mode 100644
index 000000000..a0c997600
--- /dev/null
+++ b/lib/plugins/acl/lang/pt-br/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Brazilian Portuguese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Luis Fernando Enciso <lfenciso@certto.com.br>
+ * @author Alauton/Loug
+ * @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Lucien Raven <lucienraven@yahoo.com.br>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Flávio Veras <flaviove@gmail.com>
+ * @author Jeferson Propheta <jeferson.propheta@gmail.com>
+ * @author jair.henrique@gmail.com
+ * @author Luis Dantas <luis@dantas.com>
+ * @author Frederico Guimarães <frederico@teia.bio.br>
+ * @author Jair Henrique <jair.henrique@gmail.com>
+ * @author Luis Dantas <luisdantas@gmail.com>
+ * @author Sergio Motta sergio@cisne.com.br
+ * @author Isaias Masiero Filho <masiero@masiero.org>
+ * @author Balaco Baco <balacobaco@imap.cc>
+ */
+$lang['admin_acl'] = 'Administração da Lista de Controles de Acesso';
+$lang['acl_group'] = 'Grupo';
+$lang['acl_user'] = 'Usuário';
+$lang['acl_perms'] = 'Permissões para';
+$lang['page'] = 'Página';
+$lang['namespace'] = 'Espaço de nomes';
+$lang['btn_select'] = 'Selecionar';
+$lang['p_user_id'] = 'O usuário <b class="acluser">%s</b> possui as seguintes permissões na página <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'O usuário <b class="acluser">%s</b> possui as seguintes permissões no espaço de nomes <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Os membros do grupo <b class="aclgroup">%s</b> possuem as seguintes permissões na página <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Os membros do grupo <b class="aclgroup">%s</b> possuem as seguintes permissões no espaço de nomes <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Por favor <b>digite um usuário ou grupo</b> no formulário acima para ver ou editar as permissões para a página <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Por favor <b>digite um usuário ou grupo</b> no formulário acima para ver ou editar as permissões para o espaço de nomes <b class="aclpage">%s</b>.';
+$lang['p_inherited'] = 'Nota: Essas permissões não foram definidas explicitamente, mas sim herdadas de outros grupos ou espaço de nomes superiores.';
+$lang['p_isadmin'] = 'Nota: O grupo ou usuário selecionado sempre tem permissões completas, porque ele está configurado como superusuário.';
+$lang['p_include'] = 'As permissões superiores incluem as inferiores. Permissões para Criar, Enviar e Apagar aplicam-se apenas aos espaços de nomes e não às páginas.';
+$lang['current'] = 'Regras atuais da ACL';
+$lang['where'] = 'Página/Espaço de nomes';
+$lang['who'] = 'Usuário/Grupo';
+$lang['perm'] = 'Permissões';
+$lang['acl_perm0'] = 'Nenhuma';
+$lang['acl_perm1'] = 'Ler';
+$lang['acl_perm2'] = 'Editar';
+$lang['acl_perm4'] = 'Criar';
+$lang['acl_perm8'] = 'Enviar';
+$lang['acl_perm16'] = 'Excluir';
+$lang['acl_new'] = 'Adicionar nova entrada';
+$lang['acl_mod'] = 'Modificar a entrada';
diff --git a/lib/plugins/acl/lang/pt/help.txt b/lib/plugins/acl/lang/pt/help.txt
new file mode 100644
index 000000000..cf4619deb
--- /dev/null
+++ b/lib/plugins/acl/lang/pt/help.txt
@@ -0,0 +1,9 @@
+=== Auxílio Rápido ===
+
+Nesta página podes adicionar e remover permissões para espaço de nomes e páginas no seu wiki.
+
+O painel esquerdo exibe todos os espaço de nomes e páginas. O formulario acima permite a visualização e modificar as permissões de um selecionado utilizador ou grupo.
+
+Na tabela inferior são exibidas todas as actuais regras de controle de acesso. Podes utilisá-la para excluir ou mudar rapidamente várias regras ao mesmo tempo.
+
+A leitura da [[doku>acl|documentação oficial acerca ACL]] pode ajudar a compreender melhor como o controle de acessos funciona no DokuWiki.
diff --git a/lib/plugins/acl/lang/pt/lang.php b/lib/plugins/acl/lang/pt/lang.php
new file mode 100644
index 000000000..d90bab624
--- /dev/null
+++ b/lib/plugins/acl/lang/pt/lang.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author José Carlos Monteiro <jose.c.monteiro@netcabo.pt>
+ * @author José Monteiro <Jose.Monteiro@DoWeDo-IT.com>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Fil <fil@meteopt.com>
+ * @author André Neves <drakferion@gmail.com>
+ * @author José Campos zecarlosdecampos@gmail.com
+ */
+$lang['admin_acl'] = 'Gestão de ACLs';
+$lang['acl_group'] = 'Grupo';
+$lang['acl_user'] = 'Utilizador';
+$lang['acl_perms'] = 'Permissão para';
+$lang['page'] = 'Documento';
+$lang['namespace'] = 'Namespace';
+$lang['btn_select'] = 'Selecionar';
+$lang['p_user_id'] = 'O utilizador <b class="acluser">%s</b> tem as seguintes permissões na página <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'O utilizador <b class="acluser">%s</b> tem as seguintes permissões no espaço de nomes <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Os membros do grupo <b class="aclgroup">%s</b> têm as seguintes permissões na página <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Os membros do grupo <b class="aclgroup">%s</b> têm as seguintes permissões no espaço de nomes <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Por favor <b>digite um utilizador ou grupo</b> no formulário acima para ver ou editar as permissões para a página <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Por favor <b>digite um utilizador ou grupo</b> no formulário acima para ver ou editar as permissões para o espaço de nomes <b class="aclpage">%s</b>.';
+$lang['p_inherited'] = 'Nota: Essas permissões não foram definidas explicitamente, mas sim herdadas de outros grupos ou espaço de nomes superiores.';
+$lang['p_isadmin'] = 'Nota: O grupo ou utilizador seleccionado tem sempre permissões completas, porque ele está configurado como superutilizador.';
+$lang['p_include'] = 'As permissões superiores incluem as inferiores. Permissões para Criar, Enviar e Apagar aplicam-se apenas aos espaços de nomes e não às páginas.';
+$lang['current'] = 'Regras Actuais ACL';
+$lang['where'] = 'Página/Espaço de Nomes';
+$lang['who'] = 'Utilizador/Grupo';
+$lang['perm'] = 'Permissões';
+$lang['acl_perm0'] = 'Nenhum';
+$lang['acl_perm1'] = 'Ler';
+$lang['acl_perm2'] = 'Editar';
+$lang['acl_perm4'] = 'Criar';
+$lang['acl_perm8'] = 'Carregar';
+$lang['acl_perm16'] = 'Remover';
+$lang['acl_new'] = 'Adicionar nova entrada';
+$lang['acl_mod'] = 'Modificar Entrada';
diff --git a/lib/plugins/acl/lang/ro/help.txt b/lib/plugins/acl/lang/ro/help.txt
new file mode 100644
index 000000000..3f762613c
--- /dev/null
+++ b/lib/plugins/acl/lang/ro/help.txt
@@ -0,0 +1,11 @@
+=== Quick Help: ===
+
+Pe această pagină puteţi adăuga şi elimina autorizaţiile pentru spaţiile de nume şi paginile din wiki.
+
+Panoul din stânga afişează toate spaţiile de nume şi paginile disponibile.
+
+Formularul de sus vă permite să vedeţi şi să modificaţi autorizaţiile unui anume utilizator sau grup.
+
+In tabelul de jos sunt arătate toate regulile de control a accesului setate. Îl puteţi folosi pentru a şterge sau modifica rapid mai multe reguli.
+
+Consultarea [[doku>acl|official documentation on ACL]] vă poate ajuta să înţelegeţi deplin cum funcţionează controlul accesului în DocuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/ro/lang.php b/lib/plugins/acl/lang/ro/lang.php
new file mode 100644
index 000000000..6d63ad024
--- /dev/null
+++ b/lib/plugins/acl/lang/ro/lang.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Romanian language file
+ *
+ * @author Sergiu Baltariu <s_baltariu@yahoo.com>
+ * @author s_baltariu@yahoo.com
+ * @author Emanuel-Emeric Andrasi <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrași <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andraşi <em.andrasi@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrasi <em.andrasi@mandrivausers.ro>
+ * @author Marius OLAR <olarmariusalex@gmail.com>
+ * @author Emanuel-Emeric Andrași <em.andrasi@mandrivausers.ro>
+ */
+$lang['admin_acl'] = 'Managementul Listei de Control a Accesului';
+$lang['acl_group'] = 'Grup';
+$lang['acl_user'] = 'Utilizator';
+$lang['acl_perms'] = 'Autorizare pentru';
+$lang['page'] = 'Pagina';
+$lang['namespace'] = 'Spaţiu de nume';
+$lang['btn_select'] = 'Selectează';
+$lang['p_user_id'] = 'Utilizatorul <b class="acluser">%s</b> are următoarele autorizaţii pe pagină <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Utilizatorul <b class="acluser">%s</b> are următoarele autorizaţii pe spaţiul de nume <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Membrii grupului <b class="aclgroup">%s</b> au următoarele autorizaţii pe pagină <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Membrii grupului <b class="aclgroup">%s</b> au următoarele autorizaţii pe spaţiul de nume <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = '<b>Introduceţi un utilizator sau un grup</b> în formularul de mai sus pentru a vizualiza sau edita autorizaţiile paginii <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = '<b>Introduceţi un utilizator sau un grup</b> în formularul de mai sus pentru a vizualiza sau edita autorizaţiile spaţiului de nume <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Notă: Aceste autorizaţii nu au fost setate explicit ci au fost moştenite de la alte grupuri sau spaţii de nume superioare ierarhic.';
+$lang['p_isadmin'] = 'Notă: Grupul sau utilizatorul selectat are intotdeauna toate autorizatiile întrucât este configurat ca superutilizator.';
+$lang['p_include'] = 'Permisiunile superioare le includ pe cele inferioare. Permisiunile de Creare, Upload şi Ştergere se aplică doar numelor de spaţiu, nu paginilor.';
+$lang['current'] = 'Reguli ACL actuale';
+$lang['where'] = 'Pagină/Spaţiu de nume';
+$lang['who'] = 'Utilizator/Grup';
+$lang['perm'] = 'Autorizaţii';
+$lang['acl_perm0'] = 'Nici una';
+$lang['acl_perm1'] = 'Citire';
+$lang['acl_perm2'] = 'Editare';
+$lang['acl_perm4'] = 'Creare';
+$lang['acl_perm8'] = 'Încărcare';
+$lang['acl_perm16'] = 'Ştergere';
+$lang['acl_new'] = 'Adaugă intrare nouă';
+$lang['acl_mod'] = 'Modifică intrare';
diff --git a/lib/plugins/acl/lang/ru/help.txt b/lib/plugins/acl/lang/ru/help.txt
new file mode 100644
index 000000000..7807105a8
--- /dev/null
+++ b/lib/plugins/acl/lang/ru/help.txt
@@ -0,0 +1,7 @@
+=== Краткая справка ===
+
+На этой странице вы можете добавить или удалить права доступа к пространствам имён и страницам своей вики.\\
+На панели слева отображены доступные пространства имён и страницы.\\
+Форма выше позволяет вам просмотреть и изменить права доступа для выбранного пользователя или группы.\\
+Текущие права доступа отображены в таблице ниже. Вы можете использовать её для быстрого удаления или изменения правил.\\
+Прочтение [[doku>acl|официальной документации по ACL]] может помочь вам в полном понимании работы управления правами доступа в «ДокуВики».
diff --git a/lib/plugins/acl/lang/ru/lang.php b/lib/plugins/acl/lang/ru/lang.php
new file mode 100644
index 000000000..6d04dde21
--- /dev/null
+++ b/lib/plugins/acl/lang/ru/lang.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Russian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Denis Simakov <akinoame1@gmail.com>
+ * @author Змей Этерийский evil_snake@eternion.ru
+ * @author Hikaru Nakajima <jisatsu@mail.ru>
+ * @author Alexei Tereschenko <alexeitlex@yahoo.com>
+ * @author Irina Ponomareva irinaponomareva@webperfectionist.com
+ * @author Alexander Sorkin <kibizoid@gmail.com>
+ * @author Kirill Krasnov <krasnovforum@gmail.com>
+ * @author Vlad Tsybenko <vlad.development@gmail.com>
+ * @author Aleksey Osadchiy <rfc@nm.ru>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Ladyko Andrey <fylh@succexy.spb.ru>
+ * @author Eugene <windy.wanderer@gmail.com>
+ */
+$lang['admin_acl'] = 'Управление списками контроля доступа';
+$lang['acl_group'] = 'Группа';
+$lang['acl_user'] = 'Пользователь';
+$lang['acl_perms'] = 'Права доступа для';
+$lang['page'] = 'Страница';
+$lang['namespace'] = 'Пространство имён';
+$lang['btn_select'] = 'Выбрать';
+$lang['p_user_id'] = 'Сейчас пользователь <b class="acluser">%s</b> имеет следующие права на доступ к странице <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Сейчас пользователь <b class="acluser">%s</b> имеет следующие права на доступ к пространству имён <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Сейчас члены группы <b class="aclgroup">%s</b> имеют следующие права на доступ к странице <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Сейчас члены группы <b class="aclgroup">%s</b> cимеют следующие права на доступ к пространству имён <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Пожалуйста, <b>введите пользователя или группу</b> в форме выше, чтобы просмотреть или отредактировать права на доступ к странице <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Пожалуйста, <b>введите пользователя или группу</b> в форме выше, чтобы просмотреть или отредактировать права на доступ к пространству имён <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Замечание: эти права доступа не были заданы явно, а были унаследованы от других групп или пространств имён более высокого порядка.';
+$lang['p_isadmin'] = 'Замечание: выбранный пользователь всегда имеет полные права, так как он является суперпользователем.';
+$lang['p_include'] = 'Более высокие права доступа включают в себя более низкие. Права доступа «Создание», «Загрузка» и «Удаление» относятся только к пространствам имён, а не к страницам.';
+$lang['current'] = 'Текущие права ACL';
+$lang['where'] = 'Страница/Пространство имён';
+$lang['who'] = 'Пользователь/Группа';
+$lang['perm'] = 'Права доступа';
+$lang['acl_perm0'] = 'Нет доступа';
+$lang['acl_perm1'] = 'Чтение';
+$lang['acl_perm2'] = 'Правка';
+$lang['acl_perm4'] = 'Создание';
+$lang['acl_perm8'] = 'Загрузка файлов';
+$lang['acl_perm16'] = 'Удаление';
+$lang['acl_new'] = 'Добавить новую запись';
+$lang['acl_mod'] = 'Отредактировать запись';
diff --git a/lib/plugins/acl/lang/sk/help.txt b/lib/plugins/acl/lang/sk/help.txt
new file mode 100644
index 000000000..103a0341a
--- /dev/null
+++ b/lib/plugins/acl/lang/sk/help.txt
@@ -0,0 +1,11 @@
+=== Krátka nápoveda: ===
+
+Na tejto stránke môžete pridávať alebo rušiť oprávnenia pre menné priestory a stránky vo Vašej wiki.
+
+Ľavý panel zobrazuje všetky dostupné menné priestory a stránky.
+
+Formulár zobrazený vyššie Vám dovoľuje prehliadať a meniť oprávnenia pre vybraného používateľa alebo skupinu.
+
+V tabuľke nižšie sú zobrazené všetky aktuálne prístupové pravidlá. Môžete v nej rýchlo rušiť alebo meniť viacero pravidiel súčasne.
+
+Prečítanie [[doku>acl|oficiálnej dokumentácie ACL]] Vám môže pomôcť plne pochopiť spôsob ako fungujú prístupové pravidlá (oprávnenia) v DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/sk/lang.php b/lib/plugins/acl/lang/sk/lang.php
new file mode 100644
index 000000000..398f8c63d
--- /dev/null
+++ b/lib/plugins/acl/lang/sk/lang.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Slovak language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Ondrej Vegh <ov@vsieti.sk>
+ * @author Michal Mesko <michal.mesko@gmail.com>
+ * @author exusik@gmail.com
+ * @author Martin Michalek <michalek.dev@gmail.com>
+ */
+$lang['admin_acl'] = 'Správa zoznamu prístupových práv';
+$lang['acl_group'] = 'Skupina';
+$lang['acl_user'] = 'Užívateľ';
+$lang['acl_perms'] = 'Práva pre';
+$lang['page'] = 'Stránka';
+$lang['namespace'] = 'Menný priestor';
+$lang['btn_select'] = 'Vybrať';
+$lang['p_user_id'] = 'Používateľ <b class="acluser">%s</b> má aktuálne nasledujúce oprávnenia k stránke <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Používateľ <b class="acluser">%s</b> má aktuálne nasledujúce oprávnenia v mennom priestore <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Členovia skupiny <b class="aclgroup">%s</b> majú aktuálne nasledujúce oprávnenia k stránke <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Členovia skupiny <b class="aclgroup">%s</b> majú aktuálne nasledujúce oprávnenia v mennom priestore <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Prosím <b>zadajte používateľa alebo skupinu</b> do formulára zobrazeného vyššie, aby ste mohli prezerať alebo meniť oprávnenia k stránke <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Prosím <b>zadajte používateľa alebo skupinu</b> do formulára zobrazeného vyššie, aby ste mohli prezerať alebo meniť oprávnenia v mennom priestore <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Poznámka: Tieto oprávnenia neboli nastavené explicitne, ale boli odvodené z inej skupiny alebo nadradeného menného priestoru.';
+$lang['p_isadmin'] = 'Poznámka: Vybraná skupina alebo používateľ má vždy najvyššie oprávnenia, pretože je vedená/vedený ako správca.';
+$lang['p_include'] = 'Vyššie oprávnenia zahŕňajú nižšie. Oprávnenie Vytvoriť, Nahrať a Zmazať sa vzťahujú iba k menným priestorom, nie ku stránkam.';
+$lang['current'] = 'Aktuálne pravidlá prístupu (ACL)';
+$lang['where'] = 'Stránka/Menný priestor';
+$lang['who'] = 'Používateľ/Skupina';
+$lang['perm'] = 'Povolenia';
+$lang['acl_perm0'] = 'Žiadne';
+$lang['acl_perm1'] = 'Čítať';
+$lang['acl_perm2'] = 'Zmeniť';
+$lang['acl_perm4'] = 'Vytvoriť';
+$lang['acl_perm8'] = 'Nahrať súbor';
+$lang['acl_perm16'] = 'Zmazať';
+$lang['acl_new'] = 'Pridať nový záznam';
+$lang['acl_mod'] = 'Upraviť záznam';
diff --git a/lib/plugins/acl/lang/sl/help.txt b/lib/plugins/acl/lang/sl/help.txt
new file mode 100644
index 000000000..ff096ae0e
--- /dev/null
+++ b/lib/plugins/acl/lang/sl/help.txt
@@ -0,0 +1,11 @@
+=== Hitra pomoč ===
+
+Na tej strani je mogoče dodajati, odstranjevati in spreminjati dovoljenja za delo z wiki stranmi in imenskimi prostori.
+
+Na veli strani so izpisani vsi imenski prostori in strani.
+
+Na obrazcu zgoraj je mogoče pregledovati in spreminjati dovoljenja za izbranega uporabnika ali skupino.
+
+V preglednici spodaj so prikazana vsa pravila nadzora. Ta je mogoče hitro spreminjati ali brisati.
+
+Več podrobnosti o delovanju nadzora dostopa sistema DokuWiki je mogoče najti v [[doku>acl|uradni dokumentaciji ACL]].
diff --git a/lib/plugins/acl/lang/sl/lang.php b/lib/plugins/acl/lang/sl/lang.php
new file mode 100644
index 000000000..44e45e491
--- /dev/null
+++ b/lib/plugins/acl/lang/sl/lang.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Slovenian language file
+ *
+ * @author Dejan Levec <webphp@gmail.com>
+ * @author Boštjan Seničar <senicar@gmail.com>
+ * @author Gregor Skumavc (grega.skumavc@gmail.com)
+ * @author Matej Urbančič (mateju@svn.gnome.org)
+ */
+$lang['admin_acl'] = 'Upravljanje dostopa';
+$lang['acl_group'] = 'Skupina';
+$lang['acl_user'] = 'Uporabnik';
+$lang['acl_perms'] = 'Dovoljenja za';
+$lang['page'] = 'Stran';
+$lang['namespace'] = 'Imenski prostor';
+$lang['btn_select'] = 'Izberi';
+$lang['p_user_id'] = 'Uporabnik %s ima naslednja dovoljenja za stran %s: %s.';
+$lang['p_user_ns'] = 'Uporabnik %s ima naslednja dovoljenja za imenski prostor %s: %s.';
+$lang['p_group_id'] = 'Uporabniška skupina %s ima naslednja dovoljenja za stran %s: %s.';
+$lang['p_group_ns'] = 'Uporabniška skupina %s ima naslednja dovoljenja za imenski prostor %s: %s.';
+$lang['p_choose_id'] = 'Vnesite ime <b>uporabnika ali skupine</b> v zgornji obrazec za ogled ali urejanje dovoljenj za stran %s.';
+$lang['p_choose_ns'] = 'Vnesite ime <b>uporabnika ali skupine</b> v zgornji obrazec za ogled ali urejanje dovoljenj za imenski prostor %s.';
+$lang['p_inherited'] = 'Opomba: trenutna dovoljenja niso bila posebej določena, temveč so bila prevzeta iz drugih skupin ali višjih imenskih prostorov.';
+$lang['p_isadmin'] = 'Opomba: izbrana skupina ali uporabnik imajo vsa dovoljenja za spreminjanje, saj so določeni kot skrbniki sistema.';
+$lang['p_include'] = 'Višja dovoljenja vključujejo tudi nižja. ';
+$lang['current'] = 'Trenutna pravila dostopa';
+$lang['where'] = 'Stran / Imenski prostor';
+$lang['who'] = 'Uporabnik/Skupina';
+$lang['perm'] = 'Dovoljenja';
+$lang['acl_perm0'] = 'Nič';
+$lang['acl_perm1'] = 'Preberi';
+$lang['acl_perm2'] = 'Uredi';
+$lang['acl_perm4'] = 'Ustvari';
+$lang['acl_perm8'] = 'Naloži';
+$lang['acl_perm16'] = 'Zbriši';
+$lang['acl_new'] = 'Dodaj nov zapis';
+$lang['acl_mod'] = 'Spremeni zapis';
diff --git a/lib/plugins/acl/lang/sq/help.txt b/lib/plugins/acl/lang/sq/help.txt
new file mode 100644
index 000000000..84a567f8b
--- /dev/null
+++ b/lib/plugins/acl/lang/sq/help.txt
@@ -0,0 +1,11 @@
+=== Ndihmë e Shpejtë: ===
+
+Në këtë faqe mund të shtoni ose hiqni të drejta për hapësira emri dhe faqe në wiki-n tuaj.
+
+Paneli i majtë tregon të gjitha faqet dhe hapësirat e emrit të disponueshme.
+
+Forma më sipër ju lejon të shihni dhe ndryshoni lejet për një grup ose përdorues të përzgjedhur.
+
+Në tabelën më poshtë tregohen të gjitha rregullat e vendosjes së aksesit. Mund ta përdorni për të fshirë shpejt ose ndryshuar shumë rregulla njëkohësisht.
+
+Leximi i [[doku>acl|dokumentimit zyrtar mbi ACL]] mund t'ju ndihmojë për të kuptuar plotësisht sesi funksionin Kontrolli i Aksesit në DokuWiki.
diff --git a/lib/plugins/acl/lang/sq/lang.php b/lib/plugins/acl/lang/sq/lang.php
new file mode 100644
index 000000000..30fc99bb0
--- /dev/null
+++ b/lib/plugins/acl/lang/sq/lang.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Albanian language file
+ *
+ * @author Leonard Elezi leonard.elezi@depinfo.info
+ */
+$lang['admin_acl'] = 'Menaxhimi i Listës së Kontrollit të Aksesit';
+$lang['acl_group'] = 'Grup';
+$lang['acl_user'] = 'Përdorues';
+$lang['acl_perms'] = 'Të drejta për';
+$lang['page'] = 'Faqe';
+$lang['namespace'] = 'Hapësira e Emrit';
+$lang['btn_select'] = 'Zgjidh';
+$lang['p_user_id'] = 'Përdoruesi <b class="acluser">%s</b> momentalisht ka të drejtat e mëposhtme mbi faqen <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Përdoruesi <b class="acluser">%s</b> momentalisht ka të drejtat e mëposhtme mbi hapësirën e emrit <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Anëtarët e grupit <b class="aclgroup">%s</b> momentalisht kanë të drejtat e mëposhtme mbi faqen <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Anëtarët e grupit <b class="aclgroup">%s</b> momentalisht kanë të drejtat e mëposhtme mbi hapësirën e emrit <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Ju lutemi <b>futni një përdorues ose grup</b> në formën e mësipërme për të parë ose ndryshuar bashkësinë e të drejtave për faqen <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Ju lutemi <b>futni një përdorues ose grup</b> në formën e mësipërme për të parë ose ndryshuar bashkësinë e të drejtave për hapësirën e emrit <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Shënim: Ato të drejta nuk janë vendosur specifikisht por janë të trashëguara nga grupe të tjera ose hapësira emri më të larta.';
+$lang['p_isadmin'] = 'Shënim: Grupi ose përdoruesi i përzgjedhur ka gjithmonë të drejta të plota sepse është konfiguruar si superpërdorues.';
+$lang['p_include'] = 'Të drejtat më të larta i përfshijnë edhe ato më të ultat. Të drejtat Krijo, Ngarko dhe Fshi u aplikohen vetëm hapësirave të emrit, jo faqeve.';
+$lang['current'] = 'Rregullat aktuale ACL';
+$lang['where'] = 'Faqe/Hapësirë Emri';
+$lang['who'] = 'Përdorues/Grup';
+$lang['perm'] = 'Të Drejta';
+$lang['acl_perm0'] = 'Asgjë';
+$lang['acl_perm1'] = 'Lexim';
+$lang['acl_perm2'] = 'Redaktim';
+$lang['acl_perm4'] = 'Krijim';
+$lang['acl_perm8'] = 'Ngarkim';
+$lang['acl_perm16'] = 'Fshi';
+$lang['acl_new'] = 'Shto Hyrje të re';
+$lang['acl_mod'] = 'Ndrysho Hyrje';
diff --git a/lib/plugins/acl/lang/sr/help.txt b/lib/plugins/acl/lang/sr/help.txt
new file mode 100644
index 000000000..0ec8921d4
--- /dev/null
+++ b/lib/plugins/acl/lang/sr/help.txt
@@ -0,0 +1,11 @@
+=== Приручна помоћ: ===
+
+На овој страни можете додати или уклонити дозволе за странице и именске просторе на Вашем викију.
+
+Леви панел приказује све доступне именске просторе и странице.
+
+Формулар изнад омогућава приказ и измену дозвола за одабране кориснике или групе.
+
+У табели испод су приказане све тренутно постављене дозволе. Можете је користити за брзо брисање или измену више правила.
+
+Читање [[doku>acl|званичне документације о ACL]] Вам може помоћи у потпуном разумевању рада дозвола приступа у DokuWiki-ју.
diff --git a/lib/plugins/acl/lang/sr/lang.php b/lib/plugins/acl/lang/sr/lang.php
new file mode 100644
index 000000000..20fbb0382
--- /dev/null
+++ b/lib/plugins/acl/lang/sr/lang.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * serbian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Filip Brcic <brcha@users.sourceforge.net>
+ * @author Иван Петровић petrovicivan@ubuntusrbija.org
+ * @author Ivan Petrovic <petrovicivan@ubuntusrbija.org>
+ * @author Miroslav Šolti <solti.miroslav@gmail.com>
+ */
+$lang['admin_acl'] = 'Управљање листом контроле приступа';
+$lang['acl_group'] = 'Група';
+$lang['acl_user'] = 'Корисник';
+$lang['acl_perms'] = 'Дозволе за';
+$lang['page'] = 'Страница';
+$lang['namespace'] = 'Именски простор';
+$lang['btn_select'] = 'Одабери';
+$lang['p_user_id'] = 'Корисник <b class="acluser">%s</b> тренутно има следеће дозволе за ову страницу <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Корисник <b class="acluser">%s</b> тренутно има следеће дозволе за овај именски простор <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Чланови групе <b class="acluser">%s</b> тренутно имају следеће дозволе за ову страницу <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Чланови групе <b class="acluser">%s</b> тренутно имају следеће дозволе за овај именски простор <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Молим Вас <b>унесите корисника или групу</b> у формулар изнад да бисте приказали или изменили дозволе за страницу <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Молим Вас <b>унесите корисника или групу</b> у формулар изнад да бисте приказали или изменили дозволе за именски простор <b class="aclpage">%s</b>.';
+$lang['p_inherited'] = 'Напомена: Ове дозволе се не постављају експлицитно већ само тамо где се не сударају са осталим групама или вишем иманском простору.';
+$lang['p_isadmin'] = 'Напомена: Одабран корисник или група има увек пуне дозволе јер је постављен за суперкорисника.';
+$lang['p_include'] = 'Више дозволе укључују ниже. Дозволе одавања, слања и брисања ће бити примењене само на именске просторе, не и на стране.';
+$lang['current'] = 'Тренутна правила проступа';
+$lang['where'] = 'Страница/Именски простор';
+$lang['who'] = 'Корисник/Група';
+$lang['perm'] = 'Дозволе';
+$lang['acl_perm0'] = 'Ништа';
+$lang['acl_perm1'] = 'Читање';
+$lang['acl_perm2'] = 'Измена';
+$lang['acl_perm4'] = 'Прављење';
+$lang['acl_perm8'] = 'Слање';
+$lang['acl_perm16'] = 'Брисање';
+$lang['acl_new'] = 'Додај нови унос';
+$lang['acl_mod'] = 'Измени унос';
diff --git a/lib/plugins/acl/lang/sv/help.txt b/lib/plugins/acl/lang/sv/help.txt
new file mode 100644
index 000000000..5ba770fa0
--- /dev/null
+++ b/lib/plugins/acl/lang/sv/help.txt
@@ -0,0 +1,8 @@
+=== Hjälp ===
+På den här sidan kan du lägga till och ta bort åtkomsträttigheter för namnrymder och enstaka sidor i din wiki.
+
+Till vänster visas alla tillgängliga namnrymder och sidor du kan välja. I formuläret ovanför kan du sedan välja användare eller grupp för vilken åtkomsträttigheterna ska visas eller ändras.
+
+Tabellen nedanför visar samtliga uppsatta regler för åtkomsträttigheter. Den kan du använda för att snabbt ta bort eller ändra flera regler på en gång.
+
+Läs gärna [[doku>acl|den officiella dokumentationen för ACL]] som kan hjälpa dig till fullo förstå hur åtkomsträttigheter fungerar i DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/sv/lang.php b/lib/plugins/acl/lang/sv/lang.php
new file mode 100644
index 000000000..7f963d5e1
--- /dev/null
+++ b/lib/plugins/acl/lang/sv/lang.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * swedish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Per Foreby <per@foreby.se>
+ * @author Nicklas Henriksson <nicklas[at]nihe.se>
+ * @author Håkan Sandell <hakan.sandell[at]mydata.se>
+ * @author Dennis Karlsson
+ * @author Tormod Otter Johansson <tormod@latast.se>
+ * @author emil@sys.nu
+ * @author Pontus Bergendahl <pontus.bergendahl@gmail.com>
+ * @author Tormod Johansson tormod.otter.johansson@gmail.com
+ * @author Emil Lind <emil@sys.nu>
+ * @author Bogge Bogge <bogge@bogge.com>
+ * @author Peter Åström <eaustreum@gmail.com>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ * @author mikael@mallander.net
+ */
+$lang['admin_acl'] = 'Hantera behörighetslistan (ACL)';
+$lang['acl_group'] = 'Grupp';
+$lang['acl_user'] = 'Användare';
+$lang['acl_perms'] = 'Behörighet för';
+$lang['page'] = 'Sida';
+$lang['namespace'] = 'Namnrymd';
+$lang['btn_select'] = 'Välj';
+$lang['p_user_id'] = 'Användaren <b class="acluser">%s</b> har förnärvarande följande rättigheter på sidan <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Användaren <b class="acluser">%s</b> har för närvarande följande rättigheter i namnrymden <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Medlemmar av gruppen <b class="aclgroup">%s</b> har för närvarande följande rättigheter på sidan <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Medlemmar av gruppen <b class="aclgroup">%s</b> har för närvarande följande rättigheter i namnrymden <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Vänligen <b>ange en användare eller grupp</b> i formuläret ovan för att visa eller ändra rättigheterna för sidan <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Vänligen <b>ange en användare eller grupp</b> i formuläret ovan för att visa eller ändra rättigheterna för namnrymden <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Notering: De här rättigheterna är inte explicit satta utan var ärvda från andra grupper eller högre namnrymder.';
+$lang['p_isadmin'] = 'Notering: Den valda gruppen eller användaren har alltid fulla rättigheter på grund av att den är konfigurerad som superanvändare.';
+$lang['p_include'] = 'Högre rättigheter inkluderar lägre. Rättigheter för Skapa, Ladda upp och Radera är endast applicerbara namnrymder, inte sidor.';
+$lang['current'] = 'Nuvarande ACL regler';
+$lang['where'] = 'Sida/Namnrymd';
+$lang['who'] = 'Användare/Grupp';
+$lang['perm'] = 'Rättigheter';
+$lang['acl_perm0'] = 'Inga';
+$lang['acl_perm1'] = 'Läsa';
+$lang['acl_perm2'] = 'Redigera';
+$lang['acl_perm4'] = 'Skapa';
+$lang['acl_perm8'] = 'Ladda upp';
+$lang['acl_perm16'] = 'Radera';
+$lang['acl_new'] = 'Lägg till ny behörighet';
+$lang['acl_mod'] = 'Ändra behörighet';
diff --git a/lib/plugins/acl/lang/th/help.txt b/lib/plugins/acl/lang/th/help.txt
new file mode 100644
index 000000000..52edca93f
--- /dev/null
+++ b/lib/plugins/acl/lang/th/help.txt
@@ -0,0 +1,11 @@
+=== ตัวช่วยอย่างเร็ว ===
+
+ในหน้านี้คุณสามารถเพิ่มและถอดสิทธิ์สำหรับเนมสเปซ และเพจในวิกิของคุณ
+
+แถบด้านซ้ายจะแสดงรายชื่อเนมสเปซ และเพจที่มีอยู่ทั้งหมด
+
+แบบฟอร์มข้างบนอนุญาติให้คุณมองเห็น และแก้ไขสิทธิ์ของผู้ใช้หรือกลุ่มที่เลือกไว้ได้
+
+ในตารางด้านล่างได้แสดงกฏควบคุมการเข้าถึงทั้งหมดไว้ คุณสามารถใช้มันลบ หรือเปลี่ยนกฏครั้งละหลายๆตัวพร้อมกันได้อย่างรวดเร็ว
+
+การอ่าน [[doku>acl|official documentation on ACL]] น่าจะช่วยให้คุณเข้าใจวิธีควบคุมการเข้าถึงของโดกุวิกิได้อย่างถ่องแท้ \ No newline at end of file
diff --git a/lib/plugins/acl/lang/th/lang.php b/lib/plugins/acl/lang/th/lang.php
new file mode 100644
index 000000000..472c33cdc
--- /dev/null
+++ b/lib/plugins/acl/lang/th/lang.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Thai language file
+ *
+ * @author Komgrit Niyomrath <n.komgrit@gmail.com>
+ * @author Kittithat Arnontavilas mrtomyum@gmail.com
+ * @author Kittithat Arnontavilas <mrtomyum@gmail.com>
+ * @author Thanasak Sompaisansin <jombthep@gmail.com>
+ */
+$lang['admin_acl'] = 'จัดการรายชื่อเพื่อควบคุมการเข้าถึง (Access Control List:ACL)';
+$lang['acl_group'] = 'กลุ่ม';
+$lang['acl_user'] = 'ผู้ใช้';
+$lang['acl_perms'] = 'สิทธิสำหรับ';
+$lang['page'] = 'เพจ';
+$lang['namespace'] = 'เนมสเปซ';
+$lang['btn_select'] = 'เลือก';
+$lang['where'] = 'เพจ/เนมสเปซ';
+$lang['who'] = 'ผู้ใช้/กลุ่ม';
+$lang['perm'] = 'สิทธิ์';
+$lang['acl_perm0'] = 'ไร้สิทธิ์';
+$lang['acl_perm1'] = 'อ่าน';
+$lang['acl_perm2'] = 'แก้ไข';
+$lang['acl_perm4'] = 'สร้าง';
+$lang['acl_perm8'] = 'อัพโหลด';
+$lang['acl_perm16'] = 'ลบ';
+$lang['acl_new'] = 'เพิ่มเนื้อหาใหม่';
+$lang['acl_mod'] = 'ปรับแก้เนื้อหา';
diff --git a/lib/plugins/acl/lang/tr/help.txt b/lib/plugins/acl/lang/tr/help.txt
new file mode 100644
index 000000000..b467c5019
--- /dev/null
+++ b/lib/plugins/acl/lang/tr/help.txt
@@ -0,0 +1,11 @@
+=== Hızlı yardım: ===
+
+Bu sayfada Wiki'nizin namespace ve sayfaları için izinleri belirleyebilirsiniz.
+
+Soldaki kısım varolan namespace ve sayfaları listeler.
+
+Yukarıdaki kısım seçilen bir kullanıcı veya grup için izinleri görüp değiştirmenizi sağlar.
+
+Aşağıdaki tablo ise varolan erişim kontrol kurallarını gösterir. Bu tabloyu birden fazla kuralı hızlıca silip değiştirmek için kullanabilirsiniz.
+
+Resmi ACL dökümanını ([[doku>acl|official documentation on ACL]]) okuyarak erişim kontrolünün nasıl çalıştığını öğrenebilirsiniz.
diff --git a/lib/plugins/acl/lang/tr/lang.php b/lib/plugins/acl/lang/tr/lang.php
new file mode 100644
index 000000000..de96d2906
--- /dev/null
+++ b/lib/plugins/acl/lang/tr/lang.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * turkish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Selim Farsakoğlu <farsakogluselim@yahoo.de>
+ * @author Aydın Coşkuner <aydinweb@gmail.com>
+ * @author Cihan Kahveci <kahvecicihan@gmail.com>
+ * @author Yavuz Selim <yavuzselim@gmail.com>
+ * @author Caleb Maclennan <caleb@alerque.com>
+ */
+$lang['admin_acl'] = 'Erişim Kontrol Listesi (ACL) Yönetimi';
+$lang['acl_group'] = 'Grup';
+$lang['acl_user'] = 'Kullanıcı';
+$lang['acl_perms'] = 'Şunun için yetkiler:';
+$lang['page'] = 'Sayfa';
+$lang['namespace'] = 'Namespace';
+$lang['btn_select'] = 'Seç';
+$lang['p_user_id'] = '<b class="acluser">%s</b> kullanıcısının şu anda <b class="aclpage">%s</b> sayfası için yetkisi: <i>%s</i>.';
+$lang['p_user_ns'] = '<b class="acluser">%s</b> kullanıcısının şu anda <b class="aclns">%s</b> namesapace\'i için yetkisi: <i>%s</i>.';
+$lang['p_group_id'] = '<b class="aclgroup">%s</b> grubunun şu anda <b class="aclpage">%s</b> sayfası için yetkisi: <i>%s</i>.';
+$lang['p_group_ns'] = '<b class="aclgroup">%s</b> grubunun şu anda <b class="aclns">%s</b> namesapace\'i için yetkisi: <i>%s</i>.';
+$lang['p_choose_id'] = 'Lütfen <b class="aclpage">%s</b> sayfasına izin verilen yetkilerini görmek veya değiştirmek için yukarıdaki forma <b>bir kullanıcı veya grup adı</b> girin.';
+$lang['p_choose_ns'] = 'Lütfen <b class="aclpage">%s</b> namespace\'ie izin verilen yetkileri görmek veya değiştirmek için yukarıdaki forma <b>bir kullanıcı veya grup adı</b> girin.';
+$lang['p_inherited'] = 'Not: Bu izinler doğrudan ayarlanmadan başka grup veya üst namespace\'lerden gelmektedir.';
+$lang['p_isadmin'] = 'Not: Seçili grup veya kullanıcı, "Ana kullanıcı" olarak atandığından tüm izinlere sahiptir.';
+$lang['p_include'] = 'Üst seviye izinler alt izinleri içermektedir. Oluşturma, Yükleme ve Silme yetkisi sadece namespace\'e uygulanmaktadır. Bu yetki sayfalara uygulanmaz.';
+$lang['current'] = 'Şimdiki ACL(İzin Kontrol listesi) kuralları';
+$lang['where'] = 'Sayfa/Namespace';
+$lang['who'] = 'Kullanıcı/Grup';
+$lang['perm'] = 'İzinler';
+$lang['acl_perm0'] = 'Yok';
+$lang['acl_perm1'] = 'Okuma';
+$lang['acl_perm2'] = 'Değiştirme';
+$lang['acl_perm4'] = 'Oluşturma';
+$lang['acl_perm8'] = 'Yükleme';
+$lang['acl_perm16'] = 'Silme';
+$lang['acl_new'] = 'Yeni giriş ekle';
+$lang['acl_mod'] = 'Eski girişi değiştirme';
diff --git a/lib/plugins/acl/lang/uk/help.txt b/lib/plugins/acl/lang/uk/help.txt
new file mode 100644
index 000000000..d16af0aa9
--- /dev/null
+++ b/lib/plugins/acl/lang/uk/help.txt
@@ -0,0 +1,11 @@
+=== Швидка довідка: ===
+
+На цій сторінці ви можете додавати чи знищувати права доступу для просторів імен чи сторінок вашої вікі.
+
+Ліва панель показує всі доступні простори імен і сторінки.
+
+Верхня форма дозволяє переглянути і редагувати права доступу для обраного користувача чи групи
+
+В таблиці знизу показані всі оголошені правила доступу. Можете її використовувати для швидкого знищення чи модифікації кількох правил.
+
+Додаткова допомога в [[doku>acl|офіційній документації по ACL]] допоможе вам більше зрозуміти як працює контроль доступу у ДокуВікі. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/uk/lang.php b/lib/plugins/acl/lang/uk/lang.php
new file mode 100644
index 000000000..99b4b2623
--- /dev/null
+++ b/lib/plugins/acl/lang/uk/lang.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * ukrainian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Oleksiy Voronin <ovoronin@gmail.com>
+ * @author serg_stetsuk@ukr.net
+ * @author okunia@gmail.com
+ * @author Oleksandr Kunytsia <okunia@gmail.com>
+ * @author Uko uko@uar.net
+ * @author Ulrikhe Lukoie <lukoie@gmail>.com
+ */
+$lang['admin_acl'] = 'Керування списками контролю доступу';
+$lang['acl_group'] = 'Група';
+$lang['acl_user'] = 'Користувач';
+$lang['acl_perms'] = 'Права доступу для';
+$lang['page'] = 'Сторінка';
+$lang['namespace'] = 'Простір імен';
+$lang['btn_select'] = 'Вибрати';
+$lang['p_user_id'] = 'Користувач <b class="acluser">%s</b> зараз має такі права доступу до сторінки <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Користувач <b class="acluser">%s</b> зараз має такі права доступу до простору імен <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Члени групи <b class="aclgroup">%s</b> зараз мають такі права для сторінки <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Члени групи <b class="aclgroup">%s</b> зараз мають такі права доступу до простору імен <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Будь-ласка <b>введіть користувача або групу<b> в поле зверху, щоб подивитися чи змінити права доступу до сторінки <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Будь-ласка <b>введіть користувача або групу<b> у вікно зверху, щоб подивитися чи змінити права доступу до сторінки <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Зверніть увагу! Права доступу, не встановлені явно, наслідуються від інших груп чи вищих просторів імен.';
+$lang['p_isadmin'] = 'Зверніть увагу! Обрані група чи користувач завжди мають повні права доступу, оскільки вони є суперкористувачами.';
+$lang['p_include'] = 'Старші права доступу включають молодші. Створення, Завантаження і Вилучення застосовні лише до просторів імен.';
+$lang['current'] = 'Поточні правила ACL';
+$lang['where'] = 'Сторінка/Простір імен';
+$lang['who'] = 'Користувач/Група';
+$lang['perm'] = 'Права доступу';
+$lang['acl_perm0'] = 'Жодних';
+$lang['acl_perm1'] = 'Читання';
+$lang['acl_perm2'] = 'Редагування';
+$lang['acl_perm4'] = 'Створення';
+$lang['acl_perm8'] = 'Завантаження';
+$lang['acl_perm16'] = 'Вилучення';
+$lang['acl_new'] = 'Додати новий запис';
+$lang['acl_mod'] = 'Змінити запис';
diff --git a/lib/plugins/acl/lang/vi/lang.php b/lib/plugins/acl/lang/vi/lang.php
new file mode 100644
index 000000000..6237f79ba
--- /dev/null
+++ b/lib/plugins/acl/lang/vi/lang.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * vietnamese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author James Do <jdo@myrealbox.com>
+ */
+
+$lang['admin_acl'] = 'Quản lý phép truy nhật {Access Control List}';
+$lang['acl_group'] = 'Nhóm';
+$lang['acl_user'] = 'Người';
+$lang['acl_perms'] = 'Phép truy nhập cho';
+$lang['page'] = 'Trang';
+$lang['namespace'] = 'Không gian tên';
+
+$lang['acl_perm1'] = 'Đọc';
+$lang['acl_perm2'] = 'Biên soạn';
+$lang['acl_perm4'] = 'Tạo';
+$lang['acl_perm8'] = 'Tải lên';
+$lang['acl_new'] = 'Thêm mục mới';
+//Setup VIM: ex: et ts=2 :
diff --git a/lib/plugins/acl/lang/zh-tw/help.txt b/lib/plugins/acl/lang/zh-tw/help.txt
new file mode 100644
index 000000000..bc1bddb00
--- /dev/null
+++ b/lib/plugins/acl/lang/zh-tw/help.txt
@@ -0,0 +1,12 @@
+=== 快速指南: ===
+
+你可以用這個頁面為維基中的命名空間或頁面增加或移除權限。
+
+左方面板顯示了所有命名空間和頁面。
+
+上方表格允許你觀看及修改選取的使用者或群組的權限。
+
+下方表格顯示了目前所有的存取控制表 (ACL),你可以用它快速刪除或更改多項規則。
+
+閱讀 [[doku>acl|official documentation on ACL]] 可以幫助你完整地了解 DokuWiki 存取控制的運作。
+
diff --git a/lib/plugins/acl/lang/zh-tw/lang.php b/lib/plugins/acl/lang/zh-tw/lang.php
new file mode 100644
index 000000000..085537864
--- /dev/null
+++ b/lib/plugins/acl/lang/zh-tw/lang.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Chinese(Traditional) language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author chinsan <chinsan@mail2000.com.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-simptrad.html
+ * @author Wayne San <waynesan@zerozone.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmai.com>
+ * @author Cheng-Wei Chien <e.cwchien@gmail.com>
+ * @author Danny Lin <danny0838@pchome.com.tw>
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['admin_acl'] = '管理存取控制表 (ACL)';
+$lang['acl_group'] = '群組';
+$lang['acl_user'] = '使用者';
+$lang['acl_perms'] = '設定權限於';
+$lang['page'] = '頁面';
+$lang['namespace'] = '命名空間';
+$lang['btn_select'] = '選擇';
+$lang['p_user_id'] = '使用者 <b class="acluser">%s</b> 目前在頁面 <b class="aclpage">%s</b> 擁有以下權限:<i>%s</i>。';
+$lang['p_user_ns'] = '使用者 <b class=\"acluser\">%s</b> 目前在命名空間 <b class=\"aclns\">%s</b> 擁有以下權限:<i>%s</i>。';
+$lang['p_group_id'] = '群組 <b class="aclgroup">%s</b> 的成員目前在頁面 <b class="aclpage">%s</b> 擁有以下權限:<i>%s</i>。';
+$lang['p_group_ns'] = '群組 <b class=\"aclgroup\">%s</b> 的成員目前在命名空間 <b class=\"aclns\">%s</b> 擁有以下權限:<i>%s</i>。';
+$lang['p_choose_id'] = '請在上方表格<b>輸入使用者或群組</b>以檢視或編輯頁面 <b class="aclpage">%s</b> 的權限設定。';
+$lang['p_choose_ns'] = '請在上方表格<b>輸入使用者或群組</b>以檢視或編輯命名空間 <b class=\"aclns\">%s</b> 的權限設定。';
+$lang['p_inherited'] = '注意:這些權限並未明確指定,而是從群組或上層的命名空間繼承而來。';
+$lang['p_isadmin'] = '注意:選取的群組或使用者擁有完整權限,因為它被設定為超級使用者。';
+$lang['p_include'] = '較高的權限亦包含了較低的權限。新增、上傳與刪除權限只能設定在命名空間,不能設定在頁面。';
+$lang['current'] = '目前的存取控制規則';
+$lang['where'] = '頁面/命名空間';
+$lang['who'] = '使用者/群組';
+$lang['perm'] = '權限';
+$lang['acl_perm0'] = '無';
+$lang['acl_perm1'] = '讀取頁面';
+$lang['acl_perm2'] = '編輯頁面';
+$lang['acl_perm4'] = '新增頁面';
+$lang['acl_perm8'] = '上傳圖檔';
+$lang['acl_perm16'] = '刪除檔案';
+$lang['acl_new'] = '增加規則';
+$lang['acl_mod'] = '修改規則';
diff --git a/lib/plugins/acl/lang/zh/help.txt b/lib/plugins/acl/lang/zh/help.txt
new file mode 100644
index 000000000..526dcee9b
--- /dev/null
+++ b/lib/plugins/acl/lang/zh/help.txt
@@ -0,0 +1,11 @@
+=== 快速帮助 ===
+
+本页中您可以添加或移除命名空间或页面的权限。
+
+左边的窗格显示的是全部可用的命名空间和页面。
+
+您可以在上方的表格中查看并修改选定用户或组的权限。
+
+下方的表格中显示的是当前设置的全部访问控制规则。 您可以通过它快速删除或更改多条规则。
+
+参阅 [[doku>acl|official documentation on ACL]] 能帮助您完整地理解 DokuWiki 中的访问控制是如何工作的。
diff --git a/lib/plugins/acl/lang/zh/lang.php b/lib/plugins/acl/lang/zh/lang.php
new file mode 100644
index 000000000..983882eaf
--- /dev/null
+++ b/lib/plugins/acl/lang/zh/lang.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Chinese(Simplified) language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-tradsimp.html
+ * @author George Sheraton guxd@163.com
+ * @author Simon zhan <simonzhan@21cn.com>
+ * @author mr.jinyi@gmail.com
+ * @author ben <ben@livetom.com>
+ * @author lainme <lainme993@gmail.com>
+ * @author caii <zhoucaiqi@gmail.com>
+ * @author Hiphen Lee <jacob.b.leung@gmail.com>
+ * @author caii, patent agent in China <zhoucaiqi@gmail.com>
+ * @author lainme993@gmail.com
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['admin_acl'] = '访问控制列表(ACL)管理器';
+$lang['acl_group'] = '组';
+$lang['acl_user'] = '用户';
+$lang['acl_perms'] = '许可给';
+$lang['page'] = '页面';
+$lang['namespace'] = '命名空间';
+$lang['btn_select'] = '選擇';
+$lang['p_user_id'] = '用户 <b class="acluser">%s</b> 当前在页面 <b class="aclpage">%s</b> 拥有以下权限:<i>%s</i>。';
+$lang['p_user_ns'] = '用户 <b class="acluser">%s</b> 当前在命名空间 <b class="aclns">%s</b> 拥有以下权限:<i>%s</i>。';
+$lang['p_group_id'] = '<b class="aclgroup">%s</b> 组成员当前在页面 <b class="aclpage">%s</b> 拥有以下权限:<i>%s</i>。';
+$lang['p_group_ns'] = '<b class="aclgroup">%s</b> 组成员当前在命名空间 <b class="aclns">%s</b> 拥有以下权限:<i>%s</i>。';
+$lang['p_choose_id'] = '请在上表中<b>输入用户名或组名称</b>,来查看或编辑页面 <b class="aclpage">%s</b> 的权限设置。';
+$lang['p_choose_ns'] = '请在上表中<b>输入用户名或组名称</b>,来查看或编辑命名空间 <b class="aclns">%s</b> 的权限设置。';
+$lang['p_inherited'] = '请注意:这些权限并没有明确设定,而是从其他组或更高级的名称空间继承而来。';
+$lang['p_isadmin'] = '请注意:选定的组或用户拥有完全权限,因为它被设定为超级用户。';
+$lang['p_include'] = '高权限包含低权限。创建、上传和删除权限只能应用于名称空间,而不是单个页面。';
+$lang['current'] = '当前 ACL 规则';
+$lang['where'] = '页面/命名空间';
+$lang['who'] = '用户/组';
+$lang['perm'] = '权限';
+$lang['acl_perm0'] = '无';
+$lang['acl_perm1'] = '读取';
+$lang['acl_perm2'] = '编辑';
+$lang['acl_perm4'] = '创建';
+$lang['acl_perm8'] = '上传';
+$lang['acl_perm16'] = '删除';
+$lang['acl_new'] = '添加新条目';
+$lang['acl_mod'] = '编辑条目';
diff --git a/lib/plugins/acl/pix/group.png b/lib/plugins/acl/pix/group.png
new file mode 100644
index 000000000..d80eb2606
--- /dev/null
+++ b/lib/plugins/acl/pix/group.png
Binary files differ
diff --git a/lib/plugins/acl/pix/ns.png b/lib/plugins/acl/pix/ns.png
new file mode 100644
index 000000000..c35e832da
--- /dev/null
+++ b/lib/plugins/acl/pix/ns.png
Binary files differ
diff --git a/lib/plugins/acl/pix/page.png b/lib/plugins/acl/pix/page.png
new file mode 100644
index 000000000..b1b7ebe94
--- /dev/null
+++ b/lib/plugins/acl/pix/page.png
Binary files differ
diff --git a/lib/plugins/acl/pix/user.png b/lib/plugins/acl/pix/user.png
new file mode 100644
index 000000000..7b4a507a0
--- /dev/null
+++ b/lib/plugins/acl/pix/user.png
Binary files differ
diff --git a/lib/plugins/acl/plugin.info.txt b/lib/plugins/acl/plugin.info.txt
new file mode 100644
index 000000000..f108a2390
--- /dev/null
+++ b/lib/plugins/acl/plugin.info.txt
@@ -0,0 +1,6 @@
+author Andreas Gohr
+email andi@splitbrain.org
+date 2011-04-16
+name ACL Manager
+desc Manage Page Access Control Lists
+url http://dokuwiki.org/plugin:acl
diff --git a/lib/plugins/acl/rtl.css b/lib/plugins/acl/rtl.css
new file mode 100644
index 000000000..e79abe596
--- /dev/null
+++ b/lib/plugins/acl/rtl.css
@@ -0,0 +1,40 @@
+div#acl_manager div#acl__tree {
+ float: right;
+ text-align: right;
+}
+
+div#acl_manager div#acl__tree li {
+ padding-left: 0em;
+ padding-right: 1em;
+}
+
+div#acl_manager div#acl__tree ul img {
+ margin-left: 0.25em;
+ margin-right: 0em;
+}
+
+
+div#acl_manager div#acl__detail {
+ float: left;
+}
+
+div#acl_manager .aclgroup {
+ background: transparent url(pix/group.png) right 1px no-repeat;
+ padding: 1px 18px 1px 0px;
+}
+
+div#acl_manager .acluser {
+ background: transparent url(pix/user.png) right 1px no-repeat;
+ padding: 1px 18px 1px 0px;
+}
+
+div#acl_manager .aclpage {
+ background: transparent url(pix/page.png) right 1px no-repeat;
+ padding: 1px 18px 1px 0px;
+}
+
+div#acl_manager .aclns {
+ background: transparent url(pix/ns.png) right 1px no-repeat;
+ padding: 1px 18px 1px 0px;
+}
+
diff --git a/lib/plugins/acl/script.js b/lib/plugins/acl/script.js
new file mode 100644
index 000000000..0ba91cdc9
--- /dev/null
+++ b/lib/plugins/acl/script.js
@@ -0,0 +1,127 @@
+/**
+ * ACL Manager AJAX enhancements
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+var dw_acl = {
+ /**
+ * Initialize the object and attach the event handlers
+ */
+ init: function () {
+ var $tree;
+
+ //FIXME only one underscore!!
+ if (jQuery('#acl_manager').length === 0) {
+ return;
+ }
+
+ jQuery('#acl__user select').change(dw_acl.userselhandler);
+ jQuery('#acl__user input[type=submit]').click(dw_acl.loadinfo);
+
+ $tree = jQuery('#acl__tree');
+ $tree.dw_tree({toggle_selector: 'img',
+ load_data: function (show_sublist, $clicky) {
+ // get the enclosed link and the edit form
+ var $frm = jQuery('#acl__detail form');
+
+ jQuery.post(
+ DOKU_BASE + 'lib/plugins/acl/ajax.php',
+ jQuery.extend(dw_acl.parseatt($clicky.parent().find('a')[0].search),
+ {ajax: 'tree',
+ current_ns: $frm.find('input[name=ns]').val(),
+ current_id: $frm.find('input[name=id]').val()}),
+ show_sublist,
+ 'html'
+ );
+ },
+
+ toggle_display: function ($clicky, opening) {
+ $clicky.attr('src',
+ DOKU_BASE + 'lib/images/' +
+ (opening ? 'minus' : 'plus') + '.gif');
+ }});
+ $tree.delegate('a', 'click', dw_acl.treehandler);
+ },
+
+ /**
+ * Handle user dropdown
+ *
+ * Hides or shows the user/group entry box depending on what was selected in the
+ * dropdown element
+ */
+ userselhandler: function () {
+ // make entry field visible/invisible
+ jQuery('#acl__user input').toggle(this.value === '__g__' ||
+ this.value === '__u__');
+ dw_acl.loadinfo();
+ },
+
+ /**
+ * Load the current permission info and edit form
+ */
+ loadinfo: function () {
+ jQuery('#acl__info')
+ .html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="..." />')
+ .load(
+ DOKU_BASE + 'lib/plugins/acl/ajax.php',
+ jQuery('#acl__detail form').serialize() + '&ajax=info'
+ );
+ return false;
+ },
+
+ /**
+ * parse URL attributes into a associative array
+ *
+ * @todo put into global script lib?
+ */
+ parseatt: function (str) {
+ if (str[0] === '?') {
+ str = str.substr(1);
+ }
+ var attributes = {};
+ var all = str.split('&');
+ for (var i = 0; i < all.length; i++) {
+ var att = all[i].split('=');
+ attributes[att[0]] = decodeURIComponent(att[1]);
+ }
+ return attributes;
+ },
+
+ /**
+ * Handles clicks to the tree nodes
+ */
+ treehandler: function () {
+ var $link, $frm;
+
+ $link = jQuery(this);
+
+ // remove highlighting
+ jQuery('#acl__tree a.cur').removeClass('cur');
+
+ // add new highlighting
+ $link.addClass('cur');
+
+ // set new page to detail form
+ $frm = jQuery('#acl__detail form');
+ if ($link.hasClass('wikilink1')) {
+ $frm.find('input[name=ns]').val('');
+ $frm.find('input[name=id]').val(dw_acl.parseatt($link[0].search).id);
+ } else if ($link.hasClass('idx_dir')) {
+ $frm.find('input[name=ns]').val(dw_acl.parseatt($link[0].search).ns);
+ $frm.find('input[name=id]').val('');
+ }
+ dw_acl.loadinfo();
+
+ return false;
+ }
+};
+
+jQuery(dw_acl.init);
+
+var acl = {
+ init: DEPRECATED_WRAP(dw_acl.init, dw_acl),
+ userselhandler: DEPRECATED_WRAP(dw_acl.userselhandler, dw_acl),
+ loadinfo: DEPRECATED_WRAP(dw_acl.loadinfo, dw_acl),
+ parseatt: DEPRECATED_WRAP(dw_acl.parseatt, dw_acl),
+ treehandler: DEPRECATED_WRAP(dw_acl.treehandler, dw_acl)
+};
diff --git a/lib/plugins/acl/style.css b/lib/plugins/acl/style.css
new file mode 100644
index 000000000..b7154aa78
--- /dev/null
+++ b/lib/plugins/acl/style.css
@@ -0,0 +1,97 @@
+
+div#acl_manager div#acl__tree {
+ font-size: 90%;
+ width: 25%;
+ height: 300px;
+ float: left;
+ overflow: auto;
+ border: 1px solid __border__;
+ text-align: left;
+}
+
+div#acl_manager div#acl__tree a.cur {
+ background-color: __highlight__;
+ font-weight: bold;
+}
+
+div#acl_manager div#acl__tree ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+
+div#acl_manager div#acl__tree li {
+ padding-left: 1em;
+ list-style-image: none;
+}
+
+div#acl_manager div#acl__tree ul img {
+ margin-right: 0.25em;
+ cursor: pointer;
+}
+
+div#acl_manager div#acl__detail {
+ width: 73%;
+ height: 300px;
+ float: right;
+ overflow: auto;
+}
+
+div#acl_manager div#acl__detail fieldset {
+ width: 90%;
+}
+
+div#acl_manager div#acl__detail div#acl__user {
+ border: 1px solid __border__;
+ padding: 0.5em;
+ margin-bottom: 0.6em;
+}
+
+div#acl_manager table.inline {
+ width: 100%;
+ margin: 0;
+}
+
+div#acl_manager .aclgroup {
+ background: transparent url(pix/group.png) 0px 1px no-repeat;
+ padding: 1px 0px 1px 18px;
+}
+
+div#acl_manager .acluser {
+ background: transparent url(pix/user.png) 0px 1px no-repeat;
+ padding: 1px 0px 1px 18px;
+}
+
+div#acl_manager .aclpage {
+ background: transparent url(pix/page.png) 0px 1px no-repeat;
+ padding: 1px 0px 1px 18px;
+}
+
+div#acl_manager .aclns {
+ background: transparent url(pix/ns.png) 0px 1px no-repeat;
+ padding: 1px 0px 1px 18px;
+}
+
+div#acl_manager label.disabled {
+ color: __text_neu__!important;
+}
+
+#acl_manager label {
+ text-align: left;
+ font-weight: normal;
+ display: inline;
+}
+
+#acl_manager table {
+ margin-left: 10%;
+ width: 80%;
+}
+
+#acl_manager table tr {
+ background-color: inherit;
+}
+
+#acl_manager table tr:hover {
+ background-color: __background_alt__;
+}
+
diff --git a/lib/plugins/action.php b/lib/plugins/action.php
new file mode 100644
index 000000000..885bd7c96
--- /dev/null
+++ b/lib/plugins/action.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Action Plugin Prototype
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * All DokuWiki plugins to interfere with the event system
+ * need to inherit from this class
+ */
+class DokuWiki_Action_Plugin extends DokuWiki_Plugin {
+
+ /**
+ * Registers a callback function for a given event
+ */
+ function register($controller) {
+ trigger_error('register() not implemented in '.get_class($this), E_USER_WARNING);
+ }
+}
diff --git a/lib/plugins/admin.php b/lib/plugins/admin.php
new file mode 100644
index 000000000..9a1fb9fdc
--- /dev/null
+++ b/lib/plugins/admin.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Admin Plugin Prototype
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class DokuWiki_Admin_Plugin extends DokuWiki_Plugin {
+
+ function getMenuText($language) {
+ $menutext = $this->getLang('menu');
+ if (!$menutext) {
+ $info = $this->getInfo();
+ $menutext = $info['name'].' ...';
+ }
+ return $menutext;
+ }
+
+ function getMenuSort() {
+ return 1000;
+ }
+
+ function handle() {
+ trigger_error('handle() not implemented in '.get_class($this), E_USER_WARNING);
+ }
+
+ function html() {
+ trigger_error('html() not implemented in '.get_class($this), E_USER_WARNING);
+ }
+
+ function forAdminOnly() {
+ return true;
+ }
+
+ function getTOC(){
+ return array();
+ }
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/plugins/config/admin.php b/lib/plugins/config/admin.php
new file mode 100644
index 000000000..9a9bb5329
--- /dev/null
+++ b/lib/plugins/config/admin.php
@@ -0,0 +1,357 @@
+<?php
+/**
+ * Configuration Manager admin plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+define('CM_KEYMARKER','____'); // used for settings with multiple dimensions of array indices
+
+define('PLUGIN_SELF',dirname(__FILE__).'/');
+define('PLUGIN_METADATA',PLUGIN_SELF.'settings/config.metadata.php');
+if(!defined('DOKU_PLUGIN_IMAGES')) define('DOKU_PLUGIN_IMAGES',DOKU_BASE.'lib/plugins/config/images/');
+
+require_once(PLUGIN_SELF.'settings/config.class.php'); // main configuration class and generic settings classes
+require_once(PLUGIN_SELF.'settings/extra.class.php'); // settings classes specific to these settings
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_config extends DokuWiki_Admin_Plugin {
+
+ var $_file = PLUGIN_METADATA;
+ var $_config = null;
+ var $_input = null;
+ var $_changed = false; // set to true if configuration has altered
+ var $_error = false;
+ var $_session_started = false;
+ var $_localised_prompts = false;
+
+ function getMenuSort() { return 100; }
+
+ /**
+ * handle user request
+ */
+ function handle() {
+ global $ID;
+
+ if (!$this->_restore_session()) return $this->_close_session();
+ if (!isset($_REQUEST['save']) || ($_REQUEST['save'] != 1)) return $this->_close_session();
+ if (!checkSecurityToken()) return $this->_close_session();
+
+ if (is_null($this->_config)) { $this->_config = new configuration($this->_file); }
+
+ // don't go any further if the configuration is locked
+ if ($this->_config->_locked) return $this->_close_session();
+
+ $this->_input = $_REQUEST['config'];
+
+ while (list($key) = each($this->_config->setting)) {
+ $input = isset($this->_input[$key]) ? $this->_input[$key] : NULL;
+ if ($this->_config->setting[$key]->update($input)) {
+ $this->_changed = true;
+ }
+ if ($this->_config->setting[$key]->error()) $this->_error = true;
+ }
+
+ if ($this->_changed && !$this->_error) {
+ $this->_config->save_settings($this->getPluginName());
+
+ // save state & force a page reload to get the new settings to take effect
+ $_SESSION['PLUGIN_CONFIG'] = array('state' => 'updated', 'time' => time());
+ $this->_close_session();
+ header("Location: ".wl($ID,array('do'=>'admin','page'=>'config'),true,'&'));
+ exit();
+ }
+
+ $this->_close_session();
+ }
+
+ /**
+ * output appropriate html
+ */
+ function html() {
+ $allow_debug = $GLOBALS['conf']['allowdebug']; // avoid global $conf; here.
+ global $lang;
+ global $ID;
+
+ if (is_null($this->_config)) { $this->_config = new configuration($this->_file); }
+ $this->setupLocale(true);
+
+ print $this->locale_xhtml('intro');
+
+ ptln('<div id="config__manager">');
+
+ if ($this->_config->locked)
+ ptln('<div class="info">'.$this->getLang('locked').'</div>');
+ elseif ($this->_error)
+ ptln('<div class="error">'.$this->getLang('error').'</div>');
+ elseif ($this->_changed)
+ ptln('<div class="success">'.$this->getLang('updated').'</div>');
+
+ // POST to script() instead of wl($ID) so config manager still works if
+ // rewrite config is broken. Add $ID as hidden field to remember
+ // current ID in most cases.
+ ptln('<form action="'.script().'" method="post">');
+ ptln('<div class="no"><input type="hidden" name="id" value="'.$ID.'" /></div>');
+ formSecurityToken();
+ $this->_print_h1('dokuwiki_settings', $this->getLang('_header_dokuwiki'));
+
+ $undefined_settings = array();
+ $in_fieldset = false;
+ $first_plugin_fieldset = true;
+ $first_template_fieldset = true;
+ foreach($this->_config->setting as $setting) {
+ if (is_a($setting, 'setting_hidden')) {
+ // skip hidden (and undefined) settings
+ if ($allow_debug && is_a($setting, 'setting_undefined')) {
+ $undefined_settings[] = $setting;
+ } else {
+ continue;
+ }
+ } else if (is_a($setting, 'setting_fieldset')) {
+ // config setting group
+ if ($in_fieldset) {
+ ptln(' </table>');
+ ptln(' </fieldset>');
+ } else {
+ $in_fieldset = true;
+ }
+ if ($first_plugin_fieldset && substr($setting->_key, 0, 10)=='plugin'.CM_KEYMARKER) {
+ $this->_print_h1('plugin_settings', $this->getLang('_header_plugin'));
+ $first_plugin_fieldset = false;
+ } else if ($first_template_fieldset && substr($setting->_key, 0, 7)=='tpl'.CM_KEYMARKER) {
+ $this->_print_h1('template_settings', $this->getLang('_header_template'));
+ $first_template_fieldset = false;
+ }
+ ptln(' <fieldset id="'.$setting->_key.'">');
+ ptln(' <legend>'.$setting->prompt($this).'</legend>');
+ ptln(' <div class="table">');
+ ptln(' <table class="inline">');
+ } else {
+ // config settings
+ list($label,$input) = $setting->html($this, $this->_error);
+
+ $class = $setting->is_default() ? ' class="default"' : ($setting->is_protected() ? ' class="protected"' : '');
+ $error = $setting->error() ? ' class="value error"' : ' class="value"';
+ $icon = $setting->caution() ? '<img src="'.DOKU_PLUGIN_IMAGES.$setting->caution().'.png" alt="'.$setting->caution().'" title="'.$this->getLang($setting->caution()).'" />' : '';
+
+ ptln(' <tr'.$class.'>');
+ ptln(' <td class="label">');
+ ptln(' <span class="outkey">'.$setting->_out_key(true, true).'</span>');
+ ptln(' '.$icon.$label);
+ ptln(' </td>');
+ ptln(' <td'.$error.'>'.$input.'</td>');
+ ptln(' </tr>');
+ }
+ }
+
+ ptln(' </table>');
+ ptln(' </div>');
+ if ($in_fieldset) {
+ ptln(' </fieldset>');
+ }
+
+ // show undefined settings list
+ if ($allow_debug && !empty($undefined_settings)) {
+ function _setting_natural_comparison($a, $b) { return strnatcmp($a->_key, $b->_key); }
+ usort($undefined_settings, '_setting_natural_comparison');
+ $this->_print_h1('undefined_settings', $this->getLang('_header_undefined'));
+ ptln('<fieldset>');
+ ptln('<div class="table">');
+ ptln('<table class="inline">');
+ $undefined_setting_match = array();
+ foreach($undefined_settings as $setting) {
+ if (preg_match('/^(?:plugin|tpl)'.CM_KEYMARKER.'.*?'.CM_KEYMARKER.'(.*)$/', $setting->_key, $undefined_setting_match)) {
+ $undefined_setting_key = $undefined_setting_match[1];
+ } else {
+ $undefined_setting_key = $setting->_key;
+ }
+ ptln(' <tr>');
+ ptln(' <td class="label"><span title="$meta[\''.$undefined_setting_key.'\']">$'.$this->_config->_name.'[\''.$setting->_out_key().'\']</span></td>');
+ ptln(' <td>'.$this->getLang('_msg_'.get_class($setting)).'</td>');
+ ptln(' </tr>');
+ }
+ ptln('</table>');
+ ptln('</div>');
+ ptln('</fieldset>');
+ }
+
+ // finish up form
+ ptln('<p>');
+ ptln(' <input type="hidden" name="do" value="admin" />');
+ ptln(' <input type="hidden" name="page" value="config" />');
+
+ if (!$this->_config->locked) {
+ ptln(' <input type="hidden" name="save" value="1" />');
+ ptln(' <input type="submit" name="submit" class="button" value="'.$lang['btn_save'].'" accesskey="s" />');
+ ptln(' <input type="reset" class="button" value="'.$lang['btn_reset'].'" />');
+ }
+
+ ptln('</p>');
+
+ ptln('</form>');
+ ptln('</div>');
+ }
+
+ /**
+ * @return boolean true - proceed with handle, false - don't proceed
+ */
+ function _restore_session() {
+
+ // dokuwiki closes the session before act_dispatch. $_SESSION variables are all set,
+ // however they can't be changed without starting the session again
+ if (!headers_sent()) {
+ session_start();
+ $this->_session_started = true;
+ }
+
+ if (!isset($_SESSION['PLUGIN_CONFIG'])) return true;
+
+ $session = $_SESSION['PLUGIN_CONFIG'];
+ unset($_SESSION['PLUGIN_CONFIG']);
+
+ // still valid?
+ if (time() - $session['time'] > 120) return true;
+
+ switch ($session['state']) {
+ case 'updated' :
+ $this->_changed = true;
+ return false;
+ }
+
+ return true;
+ }
+
+ function _close_session() {
+ if ($this->_session_started) session_write_close();
+ }
+
+ function setupLocale($prompts=false) {
+
+ parent::setupLocale();
+ if (!$prompts || $this->_localised_prompts) return;
+
+ $this->_setup_localised_plugin_prompts();
+ $this->_localised_prompts = true;
+
+ }
+
+ function _setup_localised_plugin_prompts() {
+ global $conf;
+
+ $langfile = '/lang/'.$conf['lang'].'/settings.php';
+ $enlangfile = '/lang/en/settings.php';
+
+ if ($dh = opendir(DOKU_PLUGIN)) {
+ while (false !== ($plugin = readdir($dh))) {
+ if ($plugin == '.' || $plugin == '..' || $plugin == 'tmp' || $plugin == 'config') continue;
+ if (is_file(DOKU_PLUGIN.$plugin)) continue;
+
+ if (@file_exists(DOKU_PLUGIN.$plugin.$enlangfile)){
+ $lang = array();
+ @include(DOKU_PLUGIN.$plugin.$enlangfile);
+ if ($conf['lang'] != 'en') @include(DOKU_PLUGIN.$plugin.$langfile);
+ foreach ($lang as $key => $value){
+ $this->lang['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.$key] = $value;
+ }
+ }
+
+ // fill in the plugin name if missing (should exist for plugins with settings)
+ if (!isset($this->lang['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.'plugin_settings_name'])) {
+ $this->lang['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.'plugin_settings_name'] =
+ ucwords(str_replace('_', ' ', $plugin)).' '.$this->getLang('_plugin_sufix');
+ }
+ }
+ closedir($dh);
+ }
+
+ // the same for the active template
+ $tpl = $conf['template'];
+
+ if (@file_exists(tpl_incdir().$enlangfile)){
+ $lang = array();
+ @include(tpl_incdir().$enlangfile);
+ if ($conf['lang'] != 'en') @include(tpl_incdir().$langfile);
+ foreach ($lang as $key => $value){
+ $this->lang['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.$key] = $value;
+ }
+ }
+
+ // fill in the template name if missing (should exist for templates with settings)
+ if (!isset($this->lang['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.'template_settings_name'])) {
+ $this->lang['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.'template_settings_name'] =
+ ucwords(str_replace('_', ' ', $tpl)).' '.$this->getLang('_template_sufix');
+ }
+
+ return true;
+ }
+
+ /**
+ * Generates a two-level table of contents for the config plugin.
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+ function getTOC() {
+ if (is_null($this->_config)) { $this->_config = new configuration($this->_file); }
+ $this->setupLocale(true);
+
+ $allow_debug = $GLOBALS['conf']['allowdebug']; // avoid global $conf; here.
+
+ // gather toc data
+ $has_undefined = false;
+ $toc = array('conf'=>array(), 'plugin'=>array(), 'template'=>null);
+ foreach($this->_config->setting as $setting) {
+ if (is_a($setting, 'setting_fieldset')) {
+ if (substr($setting->_key, 0, 10)=='plugin'.CM_KEYMARKER) {
+ $toc['plugin'][] = $setting;
+ } else if (substr($setting->_key, 0, 7)=='tpl'.CM_KEYMARKER) {
+ $toc['template'] = $setting;
+ } else {
+ $toc['conf'][] = $setting;
+ }
+ } else if (!$has_undefined && is_a($setting, 'setting_undefined')) {
+ $has_undefined = true;
+ }
+ }
+
+ // build toc
+ $t = array();
+
+ $t[] = html_mktocitem('configuration_manager', $this->getLang('_configuration_manager'), 1);
+ $t[] = html_mktocitem('dokuwiki_settings', $this->getLang('_header_dokuwiki'), 1);
+ foreach($toc['conf'] as $setting) {
+ $name = $setting->prompt($this);
+ $t[] = html_mktocitem($setting->_key, $name, 2);
+ }
+ if (!empty($toc['plugin'])) {
+ $t[] = html_mktocitem('plugin_settings', $this->getLang('_header_plugin'), 1);
+ }
+ foreach($toc['plugin'] as $setting) {
+ $name = $setting->prompt($this);
+ $t[] = html_mktocitem($setting->_key, $name, 2);
+ }
+ if (isset($toc['template'])) {
+ $t[] = html_mktocitem('template_settings', $this->getLang('_header_template'), 1);
+ $setting = $toc['template'];
+ $name = $setting->prompt($this);
+ $t[] = html_mktocitem($setting->_key, $name, 2);
+ }
+ if ($has_undefined && $allow_debug) {
+ $t[] = html_mktocitem('undefined_settings', $this->getLang('_header_undefined'), 1);
+ }
+
+ return $t;
+ }
+
+ function _print_h1($id, $text) {
+ ptln('<h1><a name="'.$id.'" id="'.$id.'">'.$text.'</a></h1>');
+ }
+
+
+}
diff --git a/lib/plugins/config/images/danger.png b/lib/plugins/config/images/danger.png
new file mode 100644
index 000000000..7bd84f7a3
--- /dev/null
+++ b/lib/plugins/config/images/danger.png
Binary files differ
diff --git a/lib/plugins/config/images/security.png b/lib/plugins/config/images/security.png
new file mode 100644
index 000000000..1800f8e56
--- /dev/null
+++ b/lib/plugins/config/images/security.png
Binary files differ
diff --git a/lib/plugins/config/images/warning.png b/lib/plugins/config/images/warning.png
new file mode 100644
index 000000000..c5e482f84
--- /dev/null
+++ b/lib/plugins/config/images/warning.png
Binary files differ
diff --git a/lib/plugins/config/lang/af/lang.php b/lib/plugins/config/lang/af/lang.php
new file mode 100644
index 000000000..cf71576d8
--- /dev/null
+++ b/lib/plugins/config/lang/af/lang.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Afrikaans language file
+ *
+ */
+$lang['userewrite'] = 'Gebraik moie URLs';
+$lang['sepchar'] = 'Blydsy naam woord spassie';
+$lang['typography_o_0'] = 'Niks';
+$lang['userewrite_o_0'] = 'niks';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['deaccent_o_0'] = 'aff';
+$lang['gdlib_o_0'] = 'GD Lib nie beskibaar nie';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['compression_o_0'] = 'niks';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'moet nie gebrake nie';
+$lang['useheading_o_0'] = 'Noit';
+$lang['useheading_o_1'] = 'Altyde';
diff --git a/lib/plugins/config/lang/ar/intro.txt b/lib/plugins/config/lang/ar/intro.txt
new file mode 100644
index 000000000..d447ec315
--- /dev/null
+++ b/lib/plugins/config/lang/ar/intro.txt
@@ -0,0 +1,7 @@
+====== مدير الضبط ======
+
+استخدم هذه الصفحة للتحكم باعدادات دوكو ويكي المثبتة عندك. للمساعدة في أمر ما أشر إلى [[doku>config]]. لمعلومات اكثر عن هذه الاضافة انظر [[doku>plugin:config]].
+
+الاعدادات الظاهرة بخلفية حمراء فاتحة اعدادات محمية ولا يمكن تغييرها بهذه الاضافة. الاعدادات الظاهرة بخلفية زرقاء هي القيم الافتراضية والاعدادات الظاهرة بخلفية بيضاء خصصت لهذا التثبيت محليا. الاعدادات الزرقاء والبيضاء يمكن تغييرها.
+
+تأكد من ضغط زر **SAVE** قبل ترك الصفحة وإلا ستضيع تعديلاتك. \ No newline at end of file
diff --git a/lib/plugins/config/lang/ar/lang.php b/lib/plugins/config/lang/ar/lang.php
new file mode 100644
index 000000000..63d258485
--- /dev/null
+++ b/lib/plugins/config/lang/ar/lang.php
@@ -0,0 +1,185 @@
+<?php
+/**
+ * Arabic language file
+ *
+ * @author Yaman Hokan <always.smile.yh@hotmail.com>
+ * @author Usama Akkad <uahello@gmail.com>
+ * @author uahello@gmail.com
+ */
+$lang['menu'] = 'الإعدادات';
+$lang['error'] = 'لم تحدث الاعدادات بسبب قيمة غير صالحة، رجاء راجع تغييراتك ثم ارسلها.
+<br />القيم الخاطئة ستظهر محاطة بحدود حمراء.';
+$lang['updated'] = 'رفعت الاعدادات بنجاح.';
+$lang['nochoice'] = '(لا خيارات اخرى متاحة)';
+$lang['locked'] = 'تعذر تحديث ملف الاعدادات، إن لم يكن ذلك مقصودا، <br />
+تأكد من صحة اسم و صلاحيات ملف الاعدادات المحلي.';
+$lang['danger'] = 'خطر: تغيير هذا الخيار قد يؤدي إلى تعذر الوصول للويكي و قائمة الاعدادات.';
+$lang['warning'] = 'تحذير: تغييرهذا الخيار قد يؤدي لسلوك غير متوقع.';
+$lang['security'] = 'تحذير أمني: تغيير هذا الخيار قد يؤدي إلى مخاطرة أمنية.';
+$lang['_configuration_manager'] = 'مدير الاعدادات';
+$lang['_header_dokuwiki'] = 'اعدادات دوكو ويكي';
+$lang['_header_plugin'] = 'اعدادات الملحقات';
+$lang['_header_template'] = 'اعدادات القوالب';
+$lang['_header_undefined'] = 'اعدادات غير محددة';
+$lang['_basic'] = 'اعدادات اساسية';
+$lang['_display'] = 'اعدادات العرض';
+$lang['_authentication'] = 'اعدادات المواثقة';
+$lang['_anti_spam'] = 'اعدادات مضاد النفاية';
+$lang['_editing'] = 'اعدادات التحرير';
+$lang['_links'] = 'اعدادات الروابط';
+$lang['_media'] = 'اعدادات الوسائط';
+$lang['_advanced'] = 'اعدادات متقدمة';
+$lang['_network'] = 'اعدادات الشبكة';
+$lang['_plugin_sufix'] = 'اعدادات الملحقات';
+$lang['_template_sufix'] = 'اعدادات القوالب';
+$lang['_msg_setting_undefined'] = 'لا بيانات إعدادات.';
+$lang['_msg_setting_no_class'] = 'لا صنف إعدادات.';
+$lang['_msg_setting_no_default'] = 'لا قيمة افتراضية.';
+$lang['fmode'] = 'نمط انشاء الملفات';
+$lang['dmode'] = 'نمط انشاء المجلدات';
+$lang['lang'] = 'لغة الواجهة';
+$lang['basedir'] = 'مسار الخادوم (مثال. <code>/dokuwiki/</code>) اترك فارغا للاكتشاف التلقائي.';
+$lang['baseurl'] = 'عنوان الخادوم (مثال. <code>http://www.yourserver.com</code>). اترك فارغا للاكتشاف التلقائي.';
+$lang['savedir'] = 'دليل حفظ البيانات';
+$lang['start'] = 'اسم صفحة البداية';
+$lang['title'] = 'عنوان الويكي';
+$lang['template'] = 'القالب';
+$lang['license'] = 'تحت أي رخصة تريد اصدار المحتوى؟';
+$lang['fullpath'] = 'اظهر المحتوى الكامل للصفحات في ';
+$lang['recent'] = 'أحدث التغييرات';
+$lang['breadcrumbs'] = 'عدد العناقيد للزيارات';
+$lang['youarehere'] = 'عناقيد هرمية';
+$lang['typography'] = 'اعمل استبدالات طبوغرافية';
+$lang['htmlok'] = 'مكّن تضمين HTML';
+$lang['phpok'] = 'مكّن تضمين PHP';
+$lang['dformat'] = 'تنسيق التاريخ (انظر وظيفة PHP,s <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'التوقيع';
+$lang['toptoclevel'] = 'المستوى الأعلى لمحتويات الجدول';
+$lang['tocminheads'] = 'الحد الأدنى من الترويسات لبناء جدول المحتويات';
+$lang['maxtoclevel'] = 'المستوى الأقصى لمحتويات الجدول';
+$lang['maxseclevel'] = 'المستوى الأقصى لتحرير القسم';
+$lang['camelcase'] = 'استخدم CamelCase للروابط';
+$lang['deaccent'] = 'نظّف اسماء الصفحات';
+$lang['useheading'] = 'استخدم اول ترويسة كأسم للصفحة';
+$lang['refcheck'] = 'التحقق من مرجع الوسائط';
+$lang['refshow'] = 'عدد مراجع الوسائط لتعرض';
+$lang['allowdebug'] = 'مكّن التنقيح <b>عطّلها إن لم تكن بحاجلة لها!</b>';
+$lang['usewordblock'] = 'احجز الغثاء بناء على قائمة كلمات';
+$lang['indexdelay'] = 'التأخير قبل الفهرسة (ثوان)';
+$lang['relnofollow'] = 'استخدم rel="nofollow" للروابط الخارجية';
+$lang['mailguard'] = 'عناوين بريدية مبهمة';
+$lang['iexssprotect'] = 'تحقق الملفات المرفوعة من احتمال وجود أكواد جافاسكربت أو HTML ضارة';
+$lang['showuseras'] = 'الذي يعرض لاظهار المستخدم الذي قام بآخر تحرير لصفحة';
+$lang['useacl'] = 'استخدم قائمة التحم بالوصول';
+$lang['autopasswd'] = 'ولد كلمات سر تلقائيا';
+$lang['authtype'] = 'آلية المواثقة';
+$lang['passcrypt'] = 'نمط تشفير كلمة السر';
+$lang['defaultgroup'] = 'المجموعة الافتراضية';
+$lang['superuser'] = 'مجموعة المستخدم المتفوق أو مستخدم أو قائمة مفصولة بالفاصلة مستخدم1،@مجموعة، مستخدم2 صلاحيتهم الوصول الكامل لكل الصفحات و الوظائف بغض النظر عن اعدادات ACL';
+$lang['manager'] = 'مجموعة المدراء أو مستخدم أو قائمة مفصولة بالفاصلة مستخدم1،@مجموعة، مستخدم2 صلاحيتهم بعض الوظائف الادارية';
+$lang['profileconfirm'] = 'اكد تغيير اللاحة بكلمة المرور';
+$lang['disableactions'] = 'عطّل اجراءات دوكو ويكي';
+$lang['disableactions_check'] = 'تحقق';
+$lang['disableactions_subscription'] = 'اشترك/الغ الاشتراك';
+$lang['disableactions_wikicode'] = 'اعرض المصدر/صدّر صرفا';
+$lang['disableactions_other'] = 'اجراءات أخرى (مفصولة بالفاصلة)';
+$lang['sneaky_index'] = 'افتراضيا، ستعرض دوكو ويكي كل اسماء النطاقات في عرض الفهرس. تفعيل هذا الخيار سيخفي مالا يملك المستخدم صلاحية قراءته. قد يؤدي هذا إلى اخفاء نطاقات فرعية متاحة. وقد يؤدي لجعل صفحة الفهرس معطلة في بعض اعدادات ACL.';
+$lang['auth_security_timeout'] = 'زمن انتهاء أمان المواثقة (ثوان)';
+$lang['securecookie'] = 'هل يفرض على كعكات التصفح المعدة عبر HTTPS ان ترسل فقط عبر HTTPS من قبل المتصفح؟ عطل هذا إن كان الولوج للويكي مؤمنا فقط عبر SSL لكن تصفح الويكي غير مؤمن.';
+$lang['xmlrpc'] = 'مكّن/عطل واجهة XML-RPC.';
+$lang['xmlrpcuser'] = 'احصر الوصول لـ XML-RPC بمستخدمين أو مجموعات مفصولة بالفاصلة هنا. اتركها فارغة لتمكين الوصول للجميع.';
+$lang['updatecheck'] = 'تحقق من التحديثات و تنبيهات الأمان؟ دوكو ويكي ستحتاج للاتصال ب update.dokuwiki.org لأجل ذلك';
+$lang['userewrite'] = 'استعمل عناوين URLs جميلة';
+$lang['useslash'] = 'استخدم الشرطة كفاصل النطاق في العناوين';
+$lang['usedraft'] = 'احفظ المسودة تلقائيا أثناء التحرير';
+$lang['sepchar'] = 'فاصل كلمة اسم الصفحة';
+$lang['canonical'] = 'استخدم العناوين الشائعة كاملة';
+$lang['fnencode'] = 'نظام ترميز اسماء الملفات بغير الأسكي.';
+$lang['autoplural'] = 'تحقق من صيغ الجمع في الروابط';
+$lang['compression'] = 'طريقة الغضط لملفات attic';
+$lang['cachetime'] = 'الحد الأعظم لعمر المخُبأ (ثوان)';
+$lang['locktime'] = 'الحد الأعظمي لقفل الملف (ثوان)';
+$lang['fetchsize'] = 'الحجم الأعظمي (بايت) ل fetch.php لتنزيله من الخارج';
+$lang['notify'] = 'ارسل تنبيهات التغيير لهذا البريد';
+$lang['registernotify'] = 'ارسل بيانات عن المستخدمين المسجلين جديدا لهذا البريد';
+$lang['mailfrom'] = 'البريد الالكتروني ليستخدم للرسائل الآلية';
+$lang['mailprefix'] = 'بادئة موضوع البريد لتستخدم مع الرسائل الآلية';
+$lang['gzip_output'] = 'استخدم ترميز-محتوى gzip ل xhtml';
+$lang['gdlib'] = 'اصدار مكتبة GD';
+$lang['im_convert'] = 'المسار إلى اداة تحويل ImageMagick';
+$lang['jpg_quality'] = 'دقة ضغط JPG (0-100)';
+$lang['subscribers'] = 'مكن دعم اشتراك الصفحة';
+$lang['subscribe_time'] = 'المهلة بعد ارسال قوائم الاشتراكات والملخصات (ثوان); هذا يجب أن يكون أقل من الوقت المخصص في أيام أحدث التغييرات.';
+$lang['compress'] = 'رُص مخرجات CSS و جافا سكربت';
+$lang['hidepages'] = 'أخف الصفحات المنطبق عليها (تعابير شرطية)';
+$lang['send404'] = 'ارسل "HTTP 404/Page Not Found" للصفحات غير الموجودة';
+$lang['sitemap'] = 'ولد خرائط موقع جوجل (أيام)';
+$lang['xsendfile'] = 'استخدم ترويسة X-Sendfile لتمكين خادم الوب من تقديم ملفات ثابتة؟ يجب أن يكون خادم الوب داعما له.';
+$lang['renderer__core'] = '%s (نواة دوكو ويكي)';
+$lang['renderer__plugin'] = '%s (ملحق)';
+$lang['rememberme'] = 'اسمح بكعكات الدخول الدائم (تذكرني)';
+$lang['rss_type'] = 'نوع تلقيمات XML';
+$lang['rss_linkto'] = 'تلقيمات XML توصل إلى';
+$lang['rss_content'] = 'مالذي يعرض في عناصر تلقيمات XML؟';
+$lang['rss_update'] = 'تحديث تلقيم XML (ثوان)';
+$lang['recent_days'] = 'مدة إبقاء أحدث التغييرات (ايام)';
+$lang['rss_show_summary'] = 'تلقيم XML يظهر ملخصا في العنوان';
+$lang['target____wiki'] = 'النافذة الهدف للروابط الداخلية';
+$lang['target____interwiki'] = 'النافذة الهدف للروابط الممرة interwiki';
+$lang['target____extern'] = 'النافذة الهدف للروابط الخارجية';
+$lang['target____media'] = 'النافذة الهدف لروابط الوسائط';
+$lang['target____windows'] = 'النافذة الهدف لروابط النوافذ';
+$lang['proxy____host'] = 'اسم خادوم الوكيل';
+$lang['proxy____port'] = 'منفذ الوكيل';
+$lang['proxy____user'] = 'اسم مستخدم الوكيل';
+$lang['proxy____pass'] = 'كلمة سر الوكيل';
+$lang['proxy____ssl'] = 'استخدم ssl للاتصال بالوكيل';
+$lang['proxy____except'] = 'تعبير شرطي لمقابلة العناوين التي ستتجاوز البروكسي.';
+$lang['safemodehack'] = 'مكّن hack الوضع الآمن';
+$lang['ftp____host'] = 'خادوم FTP ل hack الوضع الآمن';
+$lang['ftp____port'] = 'منفذ FTP ل hack الوضع الآمن';
+$lang['ftp____user'] = 'اسم مستخدم FTP ل hack الوضع الآمن';
+$lang['ftp____pass'] = 'كلمة سر FTP ل hack الوضع الآمن';
+$lang['ftp____root'] = 'دليل الجذر ل FTP لأجل hack الوضع الآمن';
+$lang['license_o_'] = 'غير مختار';
+$lang['typography_o_0'] = 'لاشيء';
+$lang['typography_o_1'] = 'استبعاد الاقتباس المفرد';
+$lang['typography_o_2'] = 'تضمين علامات اقتباس مفردة (قد لا يعمل دائما)';
+$lang['userewrite_o_0'] = 'لاشيء';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'دو';
+$lang['deaccent_o_0'] = 'معطل';
+$lang['deaccent_o_1'] = 'أزل اللهجة';
+$lang['deaccent_o_2'] = 'اجعلها لاتينية';
+$lang['gdlib_o_0'] = 'مكتبة GD غير متوفرة';
+$lang['gdlib_o_1'] = 'الاصدار 1.x';
+$lang['gdlib_o_2'] = 'اكتشاف تلقائي';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'أتوم 0.3';
+$lang['rss_type_o_atom1'] = 'أتوم 1.0';
+$lang['rss_content_o_abstract'] = 'خلاصة';
+$lang['rss_content_o_diff'] = 'الفروق الموحدة';
+$lang['rss_content_o_htmldiff'] = 'جدول الفروق بهيئة HTML';
+$lang['rss_content_o_html'] = 'محتوى HTML الكامل للصفحة';
+$lang['rss_linkto_o_diff'] = 'عرض الاختلافات';
+$lang['rss_linkto_o_page'] = 'الصفحة المعدلة';
+$lang['rss_linkto_o_rev'] = 'قائمة بالمراجعات';
+$lang['rss_linkto_o_current'] = 'الصفحة الحالية';
+$lang['compression_o_0'] = 'لا شيء';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'لا تستخدم';
+$lang['xsendfile_o_1'] = 'ترويسة lighttpd مملوكة (قبل الاصدار 1.5)';
+$lang['xsendfile_o_2'] = 'ترويسة X-Sendfile قياسية';
+$lang['xsendfile_o_3'] = 'ترويسة Nginx X-Accel-Redirect مملوكة';
+$lang['showuseras_o_loginname'] = 'اسم الدخول';
+$lang['showuseras_o_username'] = 'اسم المستخدم الكامل';
+$lang['showuseras_o_email'] = 'عنوان بريد المستخدم (مبهم تبعا لاعدادات حارس_البريد)';
+$lang['showuseras_o_email_link'] = 'عنوان بريد المستخدم كـ مالتيو: رابط';
+$lang['useheading_o_0'] = 'أبدا';
+$lang['useheading_o_navigation'] = 'التنقل فقط';
+$lang['useheading_o_content'] = 'محتوى الويكي فقط';
+$lang['useheading_o_1'] = 'دائما';
+$lang['readdircache'] = 'المدة القصوى لتخزين ';
diff --git a/lib/plugins/config/lang/bg/intro.txt b/lib/plugins/config/lang/bg/intro.txt
new file mode 100644
index 000000000..db09e6838
--- /dev/null
+++ b/lib/plugins/config/lang/bg/intro.txt
@@ -0,0 +1,7 @@
+====== Диспечер на настройките ======
+
+От тук можете да управлявате настройките на вашето Dokuwiki. За отделните настройки вижте [[doku>config]]. За повече информация относно тази приставка вижте [[doku>plugin:config]].
+
+Настройките изобразени със светло червен фон са защитени и не могат да бъдат променяни с тази приставка. Настройките показани със син фон са стандартните стойности, а настройките с бял фон са били настроени локално за тази конкретна инсталация. Можете да променяте както сините, така и белите настройки.
+
+Не забравяйте да натиснете бутона **ЗАПИС** преди да напуснете страницата, в противен случай промените няма да бъдат приложени.
diff --git a/lib/plugins/config/lang/bg/lang.php b/lib/plugins/config/lang/bg/lang.php
new file mode 100644
index 000000000..ed29c079b
--- /dev/null
+++ b/lib/plugins/config/lang/bg/lang.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * bulgarian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Nikolay Vladimirov <nikolay@vladimiroff.com>
+ * @author Viktor Usunov <usun0v@mail.bg>
+ * @author Kiril <neohidra@gmail.com>
+ */
+$lang['menu'] = 'Настройки';
+$lang['error'] = 'Обновяването на настройките не е възможно, поради невалидна стойност, моля, прегледайте промените си и пробвайте отново.
+<br />Неверните стойности ще бъдат обградени с червена рамка.';
+$lang['updated'] = 'Обновяването на настройките е успешно.';
+$lang['nochoice'] = '(няма друг възможен избор)';
+$lang['locked'] = 'Обновяването на файла с настройките не е възможно, ако това не е нарочно, проверете,<br /> дали името на локалния файл с настройки и правата са верни.';
+$lang['danger'] = 'Внимание: промяна на опцията може да направи wiki-то и менюто за настройване недостъпни.';
+$lang['warning'] = 'Предупреждение: промяна на опцията може предизвика нежелани последици.';
+$lang['security'] = 'Предупреждение: промяна на опцията може да представлява риск за сигурността.';
+$lang['_configuration_manager'] = 'Диспечер на настройките';
+$lang['_header_dokuwiki'] = 'Настройки на DokuWiki';
+$lang['_header_plugin'] = 'Настройки на приставки';
+$lang['_header_template'] = 'Настройки на шаблони';
+$lang['_header_undefined'] = 'Неопределени настройки';
+$lang['_basic'] = 'Основни настройки';
+$lang['_display'] = 'Настройки за изобразяване';
+$lang['_authentication'] = 'Настройки за удостоверяване';
+$lang['_anti_spam'] = 'Настройки за борба със SPAM-ма';
+$lang['_editing'] = 'Настройки за редактиране';
+$lang['_links'] = 'Настройки на препратките';
+$lang['_media'] = 'Настройки на медията';
+$lang['_advanced'] = 'Допълнителни настройки';
+$lang['_network'] = 'Мрежови настройки';
+$lang['_plugin_sufix'] = ' - настройки на приставката';
+$lang['_template_sufix'] = ' - настройки на шаблона';
+$lang['_msg_setting_undefined'] = 'Няма метаданни за настройките.';
+$lang['_msg_setting_no_class'] = 'Няма клас настройки.';
+$lang['_msg_setting_no_default'] = 'Няма стандартна стойност.';
+$lang['fmode'] = 'Режим (права) за създаване на файлове';
+$lang['dmode'] = 'Режим (права) за създаване на директории';
+$lang['lang'] = 'Език';
+$lang['basedir'] = 'Главна директория (напр. <code>/dokuwiki/</code>). Оставете празно, за да бъде засечена автоматично.';
+$lang['baseurl'] = 'URL адрес (напр. <code>http://www.yourserver.com</code>). Оставете празно, за да бъде засечен автоматично.';
+$lang['savedir'] = 'Директория за записване на данните';
+$lang['cookiedir'] = 'Път за бисквитките. Оставите ли полето празно ще се ползва горния URL адрес.';
+$lang['start'] = 'Име на началната страница';
+$lang['title'] = 'Име на Wiki-то';
+$lang['template'] = 'Шаблон';
+$lang['license'] = 'Под какъв лиценз да бъде публикувано съдържанието?';
+$lang['fullpath'] = 'Показване на пълния път до страниците в долния колонтитул.';
+$lang['recent'] = 'Скорошни промени';
+$lang['breadcrumbs'] = 'Брой на следите';
+$lang['youarehere'] = 'Йерархични следи';
+$lang['typography'] = 'Замяна на последователност от символи с типографски еквивалент';
+$lang['htmlok'] = 'Разрешаване вграждането на HTML код';
+$lang['phpok'] = 'Разрешаване вграждането на PHP код';
+$lang['dformat'] = 'Формат на датата (виж. <a href="http://www.php.net/strftime">strftime</a> функцията на PHP)';
+$lang['signature'] = 'Подпис';
+$lang['toptoclevel'] = 'Главно ниво (заглавие) за съдържанието';
+$lang['tocminheads'] = 'Минимален брой заглавия, определящ дали да бъде създадено съдържание';
+$lang['maxtoclevel'] = 'Максимален брой нива (заглавия) за включване в съдържанието';
+$lang['maxseclevel'] = 'Максимален брой нива предоставяни за самостоятелно редактиране';
+$lang['camelcase'] = 'Ползване на CamelCase за линкове';
+$lang['deaccent'] = 'Почистване имената на страниците (на файловете)';
+$lang['useheading'] = 'Ползване на първото заглавие за име на страница';
+$lang['refcheck'] = 'Проверка за препратка към медия, преди да бъде изтрита';
+$lang['refshow'] = 'Брой на показваните медийни препратки';
+$lang['allowdebug'] = 'Включване на режи debug - <b>изключете, ако не е нужен!</b>';
+$lang['mediarevisions'] = 'Да се пазят ли стари версии на качените файлове (Mediarevisions)?';
+$lang['usewordblock'] = 'Блокиране на SPAM въз основа на на списък от думи';
+$lang['indexdelay'] = 'Забавяне преди индексиране (сек)';
+$lang['relnofollow'] = 'Ползване на rel="nofollow" за външни препратки';
+$lang['mailguard'] = 'Промяна на адресите на ел. поща (във форма непозволяваща пращането на SPAM)';
+$lang['iexssprotect'] = 'Проверяване на качените файлове за вероятен зловреден JavaScript и HTML код';
+$lang['showuseras'] = 'Какво да се показва за потребителя, който последно е променил страницата';
+$lang['useacl'] = 'Ползване на списъци за достъп';
+$lang['autopasswd'] = 'Автоматично генериране на пароли, на нови потребители и пращане по пощата';
+$lang['authtype'] = 'Метод за удостоверяване';
+$lang['passcrypt'] = 'Метод за криптиране на паролите';
+$lang['defaultgroup'] = 'Стандартна група';
+$lang['superuser'] = 'Супер потребител - група, потребител или списък със стойности разделени чрез запетая (user1,@group1,user2) с пълен достъп до всички страници и функции без значение от настройките на списъците за достъп (ACL)';
+$lang['manager'] = 'Управител - група, потребител или списък със стойности разделени чрез запетая (user1,@group1,user2) с достъп до определени управленски функции ';
+$lang['profileconfirm'] = 'Потвърждаване на промени в профила с парола';
+$lang['disableactions'] = 'Изключване функции на DokuWiki';
+$lang['disableactions_check'] = 'Проверка';
+$lang['disableactions_subscription'] = 'Абониране/Отписване';
+$lang['disableactions_wikicode'] = 'Преглед на кода/Експортиране на оригинална версия';
+$lang['disableactions_other'] = 'Други действия (разделени със запетая)';
+$lang['sneaky_index'] = 'Стандартно DokuWiki ще показва всички именни пространства в индекса. Опцията скрива тези, за които потребителят няма права за четене. Това може да доведе и до скриване на иначе достъпни подименни пространства. С определени настройки на списъците за контрол на достъпа (ACL) може да направи индекса неизползваем. ';
+$lang['auth_security_timeout'] = 'Автоматично проверяване на удостоверяването всеки (сек)';
+$lang['securecookie'] = 'Да се изпращат ли бисквитките зададени чрез HTTPS, само чрез HTTPS от браузъра? Изключете опцията, когато SSL се ползва само за вписване, а четенето е без SSL.
+';
+$lang['xmlrpc'] = 'Включване/Изключване на интерфейса XML-RPC.';
+$lang['xmlrpcuser'] = 'Ограничаване на XML-RPC достъпа до отделени със запетая групи или потребители. Оставете празно, за да даде достъп на всеки.';
+$lang['updatecheck'] = 'Проверяване за за нови версии и предупреждения за сигурността? Необходимо е Dokiwiki да може да се свързва със update.dokuwiki.org за тази функционалност.';
+$lang['userewrite'] = 'Ползване на nice URL адреси';
+$lang['useslash'] = 'Ползване на наклонена черта за разделител на именните пространства в URL';
+$lang['usedraft'] = 'Автоматично запазване на чернова по време на редактиране';
+$lang['sepchar'] = 'Разделител между думите в имената на страници';
+$lang['canonical'] = 'Ползване на напълно уеднаквени URL адреси (абсолютни адреси - http://server/path)';
+$lang['fnencode'] = 'Метод за кодиране на не-ASCII именуваните файлове.';
+$lang['autoplural'] = 'Проверяване за множествено число в препратките';
+$lang['compression'] = 'Метод за компресия на attic файлове';
+$lang['cachetime'] = 'Макс. период за съхраняване на кеша (сек)';
+$lang['locktime'] = 'Макс. период за съхраняване на заключените файлове (сек)';
+$lang['fetchsize'] = 'Максимален размер (байтове), който fetch.php може да сваля';
+$lang['notify'] = 'Пращане на съобщения за промени по страниците на следната eл. поща';
+$lang['registernotify'] = 'Пращане на информация за нови потребители на следната ел. поща';
+$lang['mailfrom'] = 'Ел. поща, която да се ползва за автоматично изпращане на ел. писма';
+$lang['mailprefix'] = 'Представка за темите (поле subject) на автоматично изпращаните ел. писма';
+$lang['gzip_output'] = 'Кодиране на съдържанието с gzip за xhtml';
+$lang['gdlib'] = 'Версия на GD Lib';
+$lang['im_convert'] = 'Път до инструмента за трансформация на ImageMagick';
+$lang['jpg_quality'] = 'Качество на JPG компресията (0-100)';
+$lang['subscribers'] = 'Включване на поддръжката за абониране към страници';
+$lang['subscribe_time'] = 'Време след което абонаментните списъци и обобщения се изпращат (сек); Трябва да е по-малко от времето определено в recent_days.';
+$lang['compress'] = 'Компактен CSS и javascript изглед';
+$lang['cssdatauri'] = 'Максимален размер, в байтове, до който изображенията посочени в .CSS файл ще бъдат вграждани в стила (stylesheet), за да се намали броя на HTTP заявките. Техниката не работи за версиите на IE преди 8! Препоръчителни стойности: <code>400</code> до <code>600</code> байта. Въведете <code>0</code> за изключване.';
+$lang['hidepages'] = 'Скриване на съвпадащите страници (regular expressions)';
+$lang['send404'] = 'Пращане на "HTTP 404/Page Not Found" за несъществуващи страници';
+$lang['sitemap'] = 'Генериране на Google sitemap (дни)';
+$lang['broken_iua'] = 'Отметнете, ако ignore_user_abort функцията не работи. Може да попречи на търсенето в страниците. Знае се, че комбинацията IIS+PHP/CGI е лоша. Вижте <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Грешка 852</a> за повече информация.';
+$lang['xsendfile'] = 'Ползване на Х-Sendfile header, за да може уебсървъра да дава статични файлове? Вашият уебсървър трябва да го поддържа.';
+$lang['renderer_xhtml'] = 'Представяне на основните изходни данни (xhtml) от wiki-то с';
+$lang['renderer__core'] = '%s (ядрото на DokuWiki)';
+$lang['renderer__plugin'] = '%s (приставка)';
+$lang['rememberme'] = 'Ползване на постоянни бисквитки за вписване (за функцията "Запомни ме")';
+$lang['rss_type'] = 'Тип на XML емисията';
+$lang['rss_linkto'] = 'XML емисията препраща към';
+$lang['rss_content'] = 'Какво да показват елементите на XML емисията?';
+$lang['rss_update'] = 'Интервал на актуализиране на XML емисията (сек)';
+$lang['recent_days'] = 'Колко от скорошните промени да се пазят (дни)';
+$lang['rss_show_summary'] = 'Показване на обобщение в заглавието на XML емисията';
+$lang['target____wiki'] = 'Прозорец за вътрешни препратки';
+$lang['target____interwiki'] = 'Прозорец за препратки в wiki-то';
+$lang['target____extern'] = 'Прозорец за външни препратки';
+$lang['target____media'] = 'Прозорец за медийни препратки';
+$lang['target____windows'] = 'Прозорец за препратки към Windows';
+$lang['proxy____host'] = 'Име на прокси сървър';
+$lang['proxy____port'] = 'Порт за проксито';
+$lang['proxy____user'] = 'Потребител за проксито';
+$lang['proxy____pass'] = 'Парола за проксито';
+$lang['proxy____ssl'] = 'Ползване на SSL при свързване с проксито';
+$lang['proxy____except'] = 'Регулярен израз определящ за кои URL адреси да не се ползва прокси сървър.';
+$lang['safemodehack'] = 'Ползване на хака safemode';
+$lang['ftp____host'] = 'FTP сървър за хака safemode';
+$lang['ftp____port'] = 'FTP порт за хака safemode';
+$lang['ftp____user'] = 'FTP потребител за хака safemode';
+$lang['ftp____pass'] = 'FTP парола за хака safemode';
+$lang['ftp____root'] = 'FTP главна директория за хака safemode';
+$lang['license_o_'] = 'Нищо не е избрано';
+$lang['typography_o_0'] = 'без';
+$lang['typography_o_1'] = 'с изключение на единични кавички';
+$lang['typography_o_2'] = 'включително единични кавички (не винаги работи)';
+$lang['userewrite_o_0'] = 'без';
+$lang['userewrite_o_1'] = 'файлът .htaccess';
+$lang['userewrite_o_2'] = 'вътрешно от DokuWiki ';
+$lang['deaccent_o_0'] = 'изключено';
+$lang['deaccent_o_1'] = 'премахване на акценти';
+$lang['deaccent_o_2'] = 'транслитерация';
+$lang['gdlib_o_0'] = 'GD Lib не е достъпна';
+$lang['gdlib_o_1'] = 'Версия 1.x';
+$lang['gdlib_o_2'] = 'Автоматично разпознаване';
+$lang['rss_type_o_rss'] = 'RSS версия 0.91';
+$lang['rss_type_o_rss1'] = 'RSS версия 1.0';
+$lang['rss_type_o_rss2'] = 'RSS версия 2.0';
+$lang['rss_type_o_atom'] = 'Atom версия 0.3';
+$lang['rss_type_o_atom1'] = 'Atom версия 1.0';
+$lang['rss_content_o_abstract'] = 'Извлечение';
+$lang['rss_content_o_diff'] = 'Обединени разлики';
+$lang['rss_content_o_htmldiff'] = 'Таблица с разликите в HTML формат';
+$lang['rss_content_o_html'] = 'Цялото съдържание на HTML страницата';
+$lang['rss_linkto_o_diff'] = 'изглед на разликите';
+$lang['rss_linkto_o_page'] = 'променената страница';
+$lang['rss_linkto_o_rev'] = 'списък на версиите';
+$lang['rss_linkto_o_current'] = 'текущата страница';
+$lang['compression_o_0'] = 'без';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'не използвайте';
+$lang['xsendfile_o_1'] = 'Специфичен lighttpd header (преди версия 1.5)';
+$lang['xsendfile_o_2'] = 'Стандартен X-Sendfile header';
+$lang['xsendfile_o_3'] = 'Специфичен Nginx X-Accel-Redirect header за пренасочване';
+$lang['showuseras_o_loginname'] = 'Име за вписване';
+$lang['showuseras_o_username'] = 'Пълно потребителско име';
+$lang['showuseras_o_email'] = 'Ел, поща (променени според настройките на mailguard)';
+$lang['showuseras_o_email_link'] = 'Ел. поща под формата на връзка тип mailto:';
+$lang['useheading_o_0'] = 'Никога';
+$lang['useheading_o_navigation'] = 'Само за навигация';
+$lang['useheading_o_content'] = 'Само за съдържанието на Wiki-то';
+$lang['useheading_o_1'] = 'Винаги';
+$lang['readdircache'] = 'Максимален период за съхраняване кеша на readdir (сек)';
diff --git a/lib/plugins/config/lang/ca-valencia/intro.txt b/lib/plugins/config/lang/ca-valencia/intro.txt
new file mode 100644
index 000000000..40729e5fe
--- /dev/null
+++ b/lib/plugins/config/lang/ca-valencia/intro.txt
@@ -0,0 +1,10 @@
+====== Gestor de configuració ======
+
+Controle des d'esta pàgina els ajusts de DokuWiki.
+Per a obtindre ajuda sobre cada ajust vaja a [[doku>config]].
+Per a més informació al voltant d'este plúgin vaja a [[doku>config]].
+
+Els ajusts mostrats en un fondo roig claret estan protegits i no els pot
+modificar en este plúgin. Els ajusts mostrats en un fondo blau tenen els valors predeterminats i els ajusts mostrats en un fondo blanc han segut modificats localment per ad esta instalació. Abdós ajusts, blaus i blancs, es poden modificar.
+
+Recorde pulsar el botó **GUARDAR** ans d'anar-se'n d'esta pàgina o perdrà els canvis que haja fet. \ No newline at end of file
diff --git a/lib/plugins/config/lang/ca-valencia/lang.php b/lib/plugins/config/lang/ca-valencia/lang.php
new file mode 100644
index 000000000..76f11a4a5
--- /dev/null
+++ b/lib/plugins/config/lang/ca-valencia/lang.php
@@ -0,0 +1,182 @@
+<?php
+/**
+ * valencian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Bernat Arlandis i Mañó <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@llenguaitecnologia.com>
+ */
+$lang['menu'] = 'Ajusts de configuració';
+$lang['error'] = 'Els ajusts no s\'han actualisat per algun valor invàlit, per favor, revise els canvis i torne a guardar.
+<br />Els valors incorrectes es mostraran en una vora roja.';
+$lang['updated'] = 'Els ajusts s\'han actualisat correctament.';
+$lang['nochoice'] = '(no n\'hi ha atres opcions disponibles)';
+$lang['locked'] = 'L\'archiu de configuració no es pot actualisar, si açò no és intencionat,<br /> comprove que els permissos de l\'archiu de configuració local estiguen be.';
+$lang['danger'] = 'Perill: canviant esta opció pot fer inaccessibles el wiki i el menú de configuració.';
+$lang['warning'] = 'Advertència: canviar esta opció pot causar un comportament imprevist.';
+$lang['security'] = 'Advertència de seguritat: canviar esta opció pot presentar un risc de seguritat.';
+$lang['_configuration_manager'] = 'Gestor de configuració';
+$lang['_header_dokuwiki'] = 'Ajusts de DokuWiki';
+$lang['_header_plugin'] = 'Configuració de plúgins';
+$lang['_header_template'] = 'Configuració de plantilles';
+$lang['_header_undefined'] = 'Atres configuracions';
+$lang['_basic'] = 'Ajusts bàsics';
+$lang['_display'] = 'Ajusts de visualisació';
+$lang['_authentication'] = 'Ajusts d\'autenticació';
+$lang['_anti_spam'] = 'Ajusts anti-spam';
+$lang['_editing'] = 'Ajusts d\'edició';
+$lang['_links'] = 'Ajusts de vínculs';
+$lang['_media'] = 'Ajusts de mijos';
+$lang['_advanced'] = 'Ajusts alvançats';
+$lang['_network'] = 'Ajusts de ret';
+$lang['_plugin_sufix'] = 'Ajusts de plúgins';
+$lang['_template_sufix'] = '(ajusts de la plantilla)';
+$lang['_msg_setting_undefined'] = 'Ajust sense informació.';
+$lang['_msg_setting_no_class'] = 'Ajust sense classe.';
+$lang['_msg_setting_no_default'] = 'Sense valor predeterminat.';
+$lang['fmode'] = 'Modo de creació d\'archius';
+$lang['dmode'] = 'Modo de creació de directoris';
+$lang['lang'] = 'Idioma';
+$lang['basedir'] = 'Directori base';
+$lang['baseurl'] = 'URL base';
+$lang['savedir'] = 'Directori per a guardar senyes';
+$lang['start'] = 'Nom de la pàgina inicial';
+$lang['title'] = 'Títul del Wiki';
+$lang['template'] = 'Plantilla';
+$lang['license'] = '¿Baix quina llicència deuen publicar-se els continguts?';
+$lang['fullpath'] = 'Mostrar en el peu el camí complet a les pàgines';
+$lang['recent'] = 'Canvis recents';
+$lang['breadcrumbs'] = 'Llongitut del rastre';
+$lang['youarehere'] = 'Rastre jeràrquic';
+$lang['typography'] = 'Fer substitucions tipogràfiques';
+$lang['htmlok'] = 'Permetre HTML';
+$lang['phpok'] = 'Permetre PHP';
+$lang['dformat'] = 'Format de data (vore la funció <a href="http://www.php.net/date">date</a> de PHP)';
+$lang['signature'] = 'Firma';
+$lang['toptoclevel'] = 'Nivell superior de la taula de continguts';
+$lang['tocminheads'] = 'Número mínim de titulars que generen una TDC';
+$lang['maxtoclevel'] = 'Nivell màxim de la taula de continguts';
+$lang['maxseclevel'] = 'Nivell màxim d\'edició de seccions';
+$lang['camelcase'] = 'Utilisar CamelCase per als vínculs';
+$lang['deaccent'] = 'Depurar els noms de pàgines';
+$lang['useheading'] = 'Utilisar el primer titular per al nom de pàgina';
+$lang['refcheck'] = 'Comprovar referències a mijos';
+$lang['refshow'] = 'Número de referències a mijos a mostrar';
+$lang['allowdebug'] = 'Permetre depurar (<b>¡desactivar quan no es necessite!</b>)';
+$lang['usewordblock'] = 'Bloquejar spam basant-se en una llista de paraules';
+$lang['indexdelay'] = 'Retart abans d\'indexar (seg.)';
+$lang['relnofollow'] = 'Utilisar rel="nofollow" en vínculs externs';
+$lang['mailguard'] = 'Ofuscar les direccions de correu';
+$lang['iexssprotect'] = 'Comprovar que els archius pujats no tinguen possible còdic Javascript o HTML maliciós';
+$lang['showuseras'] = 'Qué mostrar quan aparega l\'últim usuari que ha editat la pàgina';
+$lang['useacl'] = 'Utilisar llistes de control d\'accés';
+$lang['autopasswd'] = 'Generar contrasenyes automàticament';
+$lang['authtype'] = 'Sistema d\'autenticació';
+$lang['passcrypt'] = 'Método de sifrat de la contrasenya';
+$lang['defaultgroup'] = 'Grup predeterminat';
+$lang['superuser'] = 'Super-usuari - grup, usuari o llista separada per comes (usuari1,@grup1,usuari2) en accés total a totes les pàgines i funcions independentment dels ajusts ACL';
+$lang['manager'] = 'Manager - grup, usuari o llista separada per comes (usuari1,@grup1,usuari2) en accés a certes funcions d\'administració';
+$lang['profileconfirm'] = 'Confirmar canvis al perfil en la contrasenya';
+$lang['disableactions'] = 'Desactivar accions de DokuWiki';
+$lang['disableactions_check'] = 'Comprovar';
+$lang['disableactions_subscription'] = 'Subscriure\'s/Desubscriure\'s';
+$lang['disableactions_wikicode'] = 'Vore font/exportar còdic';
+$lang['disableactions_other'] = 'Atres accions (separades per comes)';
+$lang['sneaky_index'] = 'Normalment, DokuWiki mostra tots els espais de noms en la vista d\'índex. Activant esta opció s\'ocultaran aquells per als que l\'usuari no tinga permís de llectura. Açò pot ocultar subespais accessibles i inutilisar l\'índex per a certes configuracions del ACL.';
+$lang['auth_security_timeout'] = 'Temps de seguritat màxim per a l\'autenticació (segons)';
+$lang['securecookie'] = '¿El navegador deuria enviar per HTTPS només les galletes que s\'han generat per HTTPS? Desactive esta opció quan utilise SSL només en la pàgina d\'inici de sessió.';
+$lang['xmlrpc'] = 'Activar/desactivar interfaç XML-RPC.';
+$lang['xmlrpcuser'] = 'Restringir l\'accés XML-RPC a la llista d\'usuaris i grups separada per comes definida ací. Deixar buit per a donar accés a tots.';
+$lang['updatecheck'] = '¿Buscar actualisacions i advertències de seguritat? DokuWiki necessita conectar a update.dokuwiki.org per ad açò.';
+$lang['userewrite'] = 'Utilisar URL millorades';
+$lang['useslash'] = 'Utilisar \'/\' per a separar espais de noms en les URL';
+$lang['usedraft'] = 'Guardar automàticament un borrador mentres edite';
+$lang['sepchar'] = 'Separador de paraules en els noms de pàgines';
+$lang['canonical'] = 'Utilisar URL totalment canòniques';
+$lang['autoplural'] = 'Buscar formes en plural en els vínculs';
+$lang['compression'] = 'Método de compressió per als archius de l\'àtic';
+$lang['cachetime'] = 'Edat màxima de la caché (seg.)';
+$lang['locktime'] = 'Edat màxima d\'archius de bloqueig (seg.)';
+$lang['fetchsize'] = 'Tamany màxim (bytes) que fetch.php pot descarregar externament';
+$lang['notify'] = 'Enviar notificacions de canvis ad esta direcció de correu';
+$lang['registernotify'] = 'Enviar informació d\'usuaris recentment registrats ad esta direcció de correu';
+$lang['mailfrom'] = 'Direcció de correu a utilisar per a mensages automàtics';
+$lang['gzip_output'] = 'Utilisar Content-Encoding gzip per a xhtml';
+$lang['gdlib'] = 'Versió de GD Lib';
+$lang['im_convert'] = 'Ruta a la ferramenta de conversió ImageMagick';
+$lang['jpg_quality'] = 'Calitat de compressió JPG (0-100)';
+$lang['subscribers'] = 'Activar la subscripció a pàgines';
+$lang['compress'] = 'Compactar l\'eixida CSS i Javascript';
+$lang['hidepages'] = 'Amagar les pàgines coincidents (expressions regulars)';
+$lang['send404'] = 'Enviar "HTTP 404/Page Not Found" per a les pàgines que no existixen';
+$lang['sitemap'] = 'Generar sitemap de Google (dies)';
+$lang['broken_iua'] = '¿La funció ignore_user_abort funciona mal en este sistema? Podria ser la causa d\'un índex de busca que no funcione. Es sap que IIS+PHP/CGI té este problema. Veja <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> per a més informació.';
+$lang['xsendfile'] = '¿Utilisar l\'encapçalat X-Sendfile per a que el servidor web servixca archius estàtics? El servidor web ho ha d\'admetre.';
+$lang['renderer_xhtml'] = 'Visualisador a utilisar per a l\'eixida principal del wiki (xhtml)';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (plúgin)';
+$lang['rememberme'] = 'Permetre recordar permanentment la sessió (recordar-me)';
+$lang['rss_type'] = 'Tipo de canal XML';
+$lang['rss_linkto'] = 'El canal XML vincula a';
+$lang['rss_content'] = '¿Qué mostrar en els ítems del canal XML?';
+$lang['rss_update'] = 'Interval d\'actualisació del canal XML (seg.)';
+$lang['recent_days'] = 'Quànts canvis recents guardar (dies)';
+$lang['rss_show_summary'] = 'Que el canal XML mostre el sumari en el títul';
+$lang['target____wiki'] = 'Finestra destí per a vínculs interns';
+$lang['target____interwiki'] = 'Finestra destí per a vínculs d\'interwiki';
+$lang['target____extern'] = 'Finestra destí per a vínculs externs';
+$lang['target____media'] = 'Finestra destí per a vinculs a mijos';
+$lang['target____windows'] = 'Finestra destí per a vínculs a finestres';
+$lang['proxy____host'] = 'Nom del servidor proxy';
+$lang['proxy____port'] = 'Port del proxy';
+$lang['proxy____user'] = 'Nom d\'usuari del proxy';
+$lang['proxy____pass'] = 'Contrasenya del proxy';
+$lang['proxy____ssl'] = 'Utilisar SSL per a conectar al proxy';
+$lang['safemodehack'] = 'Activar \'hack\' de modo segur';
+$lang['ftp____host'] = 'Servidor FTP per al \'hack\' de modo segur';
+$lang['ftp____port'] = 'Port FTP per al \'hack\' de modo segur';
+$lang['ftp____user'] = 'Nom de l\'usuari per al \'hack\' de modo segur';
+$lang['ftp____pass'] = 'Contrasenya FTP per al \'hack\' de modo segur';
+$lang['ftp____root'] = 'Directori base FTP per al \'hack\' de modo segur';
+$lang['license_o_'] = 'Cap triada';
+$lang['typography_o_0'] = 'cap';
+$lang['typography_o_1'] = 'Excloure cometes simples';
+$lang['typography_o_2'] = 'Incloure cometes simples (podria no funcionar sempre)';
+$lang['userewrite_o_0'] = 'cap';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Interna de DokuWiki';
+$lang['deaccent_o_0'] = 'desactivat';
+$lang['deaccent_o_1'] = 'llevar accents';
+$lang['deaccent_o_2'] = 'romanisar';
+$lang['gdlib_o_0'] = 'GD Lib no està disponible';
+$lang['gdlib_o_1'] = 'Versió 1.x';
+$lang['gdlib_o_2'] = 'Autodetecció';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Abstracte';
+$lang['rss_content_o_diff'] = 'Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'Taula de diferències en format HTML';
+$lang['rss_content_o_html'] = 'Contingut complet de la pàgina en HTML';
+$lang['rss_linkto_o_diff'] = 'mostrar diferències';
+$lang['rss_linkto_o_page'] = 'la pàgina revisada';
+$lang['rss_linkto_o_rev'] = 'llista de revisions';
+$lang['rss_linkto_o_current'] = 'la pàgina actual';
+$lang['compression_o_0'] = 'cap';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'No utilisar';
+$lang['xsendfile_o_1'] = 'Encapçalat propietari lighttpd (abans de la versió 1.5)';
+$lang['xsendfile_o_2'] = 'Encapçalat Standard X-Sendfile';
+$lang['xsendfile_o_3'] = 'Encapçalat propietari Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Nom d\'inici de sessió';
+$lang['showuseras_o_username'] = 'Nom complet de l\'usuari';
+$lang['showuseras_o_email'] = 'Direcció de correu de l\'usuari (oculta segons la configuració)';
+$lang['showuseras_o_email_link'] = 'Direcció de correu de l\'usuari com un víncul mailto:';
+$lang['useheading_o_0'] = 'Mai';
+$lang['useheading_o_navigation'] = 'Només navegació';
+$lang['useheading_o_content'] = 'Només contingut del wiki';
+$lang['useheading_o_1'] = 'Sempre';
diff --git a/lib/plugins/config/lang/ca/intro.txt b/lib/plugins/config/lang/ca/intro.txt
new file mode 100644
index 000000000..9ce4e6605
--- /dev/null
+++ b/lib/plugins/config/lang/ca/intro.txt
@@ -0,0 +1,7 @@
+====== Gestió de la configuració ======
+
+Utilitzeu aquesta pàgina per controlar els paràmetres de la vostra instal·lació de DokuWiki. Ajuda sobre paràmetres individuals en [[doku>config]]. Més detalls sobre aquest connector en [[doku>plugin:config]].
+
+Els paràmetres que es visualitzen sobre fons vermell clar estan protegits i no es poden modificar amb aquest connector. Els paràmetres que es visualitzen sobre fons blau tenen valors per defecte. Els de fons blanc s'han configurat localment per a aquesta instal·lació. Tant els blaus com els blanc es poden modificar.
+
+Recordeu que cal prémer el botó **DESA** abans de sortir d'aquesta pàgina, o si no es perdrien els canvis.
diff --git a/lib/plugins/config/lang/ca/lang.php b/lib/plugins/config/lang/ca/lang.php
new file mode 100644
index 000000000..1a2a22881
--- /dev/null
+++ b/lib/plugins/config/lang/ca/lang.php
@@ -0,0 +1,182 @@
+<?php
+/**
+ * Catalan language file
+ *
+ * @author Carles Bellver <carles.bellver@gmail.com>
+ * @author carles.bellver@gmail.com
+ * @author carles.bellver@cent.uji.es
+ * @author Carles Bellver <carles.bellver@cent.uji.es>
+ */
+$lang['menu'] = 'Paràmetres de configuració';
+$lang['error'] = 'Els paràmetres no s\'han pogut actualitzar per causa d\'un valor incorrecte Reviseu els canvis i torneu a enviar-los.<br />Els valors incorrectes es ressaltaran amb un marc vermell.';
+$lang['updated'] = 'Els paràmetres s\'han actualitzat amb èxit.';
+$lang['nochoice'] = '(no hi altres opcions disponibles)';
+$lang['locked'] = 'El fitxer de paràmetres no es pot actualitzar. Si això és involuntari, <br />
+assegureu-vos que el nom i els permisos del fitxer local de paràmetres són correctes.';
+$lang['danger'] = 'Alerta: si canvieu aquesta opció podeu fer que el wiki i el menú de configuració no siguin accessibles.';
+$lang['warning'] = 'Avís: modificar aquesta opció pot provocar un comportament no desitjat.';
+$lang['security'] = 'Avís de seguretat: modificar aquesta opció pot implicar un risc de seguretat.';
+$lang['_configuration_manager'] = 'Gestió de la configuració';
+$lang['_header_dokuwiki'] = 'Paràmetres de DokuWiki';
+$lang['_header_plugin'] = 'Paràmetres de connectors';
+$lang['_header_template'] = 'Paràmetres de plantilles';
+$lang['_header_undefined'] = 'Paràmetres no definits';
+$lang['_basic'] = 'Paràmetres bàsics';
+$lang['_display'] = 'Paràmetres de visualització';
+$lang['_authentication'] = 'Paràmetres d\'autenticació';
+$lang['_anti_spam'] = 'Paràmetres anti-brossa';
+$lang['_editing'] = 'Paràmetres d\'edició';
+$lang['_links'] = 'Paràmetres d\'enllaços';
+$lang['_media'] = 'Paràmetres de mitjans';
+$lang['_advanced'] = 'Paràmetres avançats';
+$lang['_network'] = 'Paràmetres de xarxa';
+$lang['_plugin_sufix'] = 'Paràmetres de connectors';
+$lang['_template_sufix'] = 'Paràmetres de plantilla';
+$lang['_msg_setting_undefined'] = 'Falten metadades de paràmetre.';
+$lang['_msg_setting_no_class'] = 'Falta classe de paràmetre.';
+$lang['_msg_setting_no_default'] = 'No hi ha valor per defecte.';
+$lang['fmode'] = 'Mode de creació de fitxers';
+$lang['dmode'] = 'Mode de creació de directoris';
+$lang['lang'] = 'Idioma';
+$lang['basedir'] = 'Directori base';
+$lang['baseurl'] = 'URL base';
+$lang['savedir'] = 'Directori per desar les dades';
+$lang['start'] = 'Nom de la pàgina d\'inici';
+$lang['title'] = 'Títol del wiki';
+$lang['template'] = 'Plantilla';
+$lang['license'] = 'Amb quina llicència voleu publicar el contingut?';
+$lang['fullpath'] = 'Mostra el camí complet de les pàgines al peu';
+$lang['recent'] = 'Canvis recents';
+$lang['breadcrumbs'] = 'Nombre d\'engrunes';
+$lang['youarehere'] = 'Camí d\'engrunes jeràrquic';
+$lang['typography'] = 'Substitucions tipogràfiques';
+$lang['htmlok'] = 'Permet HTML incrustat';
+$lang['phpok'] = 'Permet PHP incrustat';
+$lang['dformat'] = 'Format de data (vg. la funció PHP <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Signatura';
+$lang['toptoclevel'] = 'Nivell superior per a la taula de continguts';
+$lang['tocminheads'] = 'Quantitat mínima d\'encapçalaments que determina si es construeix o no la taula de continguts.';
+$lang['maxtoclevel'] = 'Nivell màxim per a la taula de continguts';
+$lang['maxseclevel'] = 'Nivell màxim d\'edició de seccions';
+$lang['camelcase'] = 'Utilitza CamelCase per als enllaços';
+$lang['deaccent'] = 'Noms de pàgina nets';
+$lang['useheading'] = 'Utilitza el primer encapçalament per als noms de pàgina';
+$lang['refcheck'] = 'Comprova la referència en els fitxers de mitjans';
+$lang['refshow'] = 'Nombre de referències de mitjans per mostrar';
+$lang['allowdebug'] = 'Permet depuració <strong>inhabiliteu si no és necessari</strong>';
+$lang['usewordblock'] = 'Bloca brossa per llista de paraules';
+$lang['indexdelay'] = 'Retard abans d\'indexar (segons)';
+$lang['relnofollow'] = 'Utilitza rel="nofollow" en enllaços externs';
+$lang['mailguard'] = 'Ofusca les adreces de correu';
+$lang['iexssprotect'] = 'Comprova codi HTML o Javascript maligne en els fitxers penjats';
+$lang['showuseras'] = 'Què cal visualitzar quan es mostra el darrer usuari que ha editat la pàgina';
+$lang['useacl'] = 'Utilitza llistes de control d\'accés';
+$lang['autopasswd'] = 'Generació automàtica de contrasenyes';
+$lang['authtype'] = 'Rerefons d\'autenticació';
+$lang['passcrypt'] = 'Mètode d\'encriptació de contrasenyes';
+$lang['defaultgroup'] = 'Grup per defecte';
+$lang['superuser'] = 'Superusuari: un grup o usuari amb accés complet a totes les pàgines i funcions independentment dels paràmetres ACL';
+$lang['manager'] = 'Administrador: un grup o usuari amb accés a certes funcions d\'administració';
+$lang['profileconfirm'] = 'Confirma amb contrasenya els canvis en el perfil';
+$lang['disableactions'] = 'Inhabilita accions DokuWiki';
+$lang['disableactions_check'] = 'Revisa';
+$lang['disableactions_subscription'] = 'Subscripció/cancel·lació';
+$lang['disableactions_wikicode'] = 'Mostra/exporta font';
+$lang['disableactions_other'] = 'Altres accions (separades per comes)';
+$lang['sneaky_index'] = 'Per defecte, DokuWiki mostrarà tots els espai en la visualització d\'índex. Si activeu aquest paràmetre, s\'ocultaran aquells espais en els quals l\'usuari no té accés de lectura. Això pot fer que s\'ocultin subespais que sí que són accessibles. En algunes configuracions ACL pot fer que l\'índex resulti inutilitzable.';
+$lang['auth_security_timeout'] = 'Temps d\'espera de seguretat en l\'autenticació (segons)';
+$lang['securecookie'] = 'Les galetes que s\'han creat via HTTPS, només s\'han d\'enviar des del navegador per HTTPS? Inhabiliteu aquesta opció si només l\'inici de sessió del wiki es fa amb SSL i la navegació del wiki es fa sense seguretat.';
+$lang['xmlrpc'] = 'Habilita/inhabilita la interfície XML-RPC';
+$lang['xmlrpcuser'] = 'Restringeix l\'accés per XML-RPC als usuaris o grups següents, separats per comes. Deixeu aquest camp en blanc per donar accés a tothom.';
+$lang['updatecheck'] = 'Comprova actualitzacions i avisos de seguretat. DokuWiki necessitarà contactar amb update.dokuwiki.org per utilitzar aquesta característica.';
+$lang['userewrite'] = 'Utilitza URL nets';
+$lang['useslash'] = 'Utilitza la barra / com a separador d\'espais en els URL';
+$lang['usedraft'] = 'Desa automàticament un esborrany mentre s\'edita';
+$lang['sepchar'] = 'Separador de paraules en els noms de pàgina';
+$lang['canonical'] = 'Utilitza URL canònics complets';
+$lang['autoplural'] = 'Comprova formes plurals en els enllaços';
+$lang['compression'] = 'Mètode de compressió per als fitxers de les golfes';
+$lang['cachetime'] = 'Durada màxima de la memòria cau (segons)';
+$lang['locktime'] = 'Durada màxima dels fitxers de bloqueig (segons)';
+$lang['fetchsize'] = 'Mida màxima (bytes) que fetch.php pot baixar d\'un lloc extern';
+$lang['notify'] = 'Envia notificacions de canvis a aquesta adreça de correu';
+$lang['registernotify'] = 'Envia informació sobre nous usuaris registrats a aquesta adreça de correu';
+$lang['mailfrom'] = 'Adreça de correu remitent per a missatges automàtics';
+$lang['gzip_output'] = 'Codifica contingut xhtml com a gzip';
+$lang['gdlib'] = 'Versió GD Lib';
+$lang['im_convert'] = 'Camí de la utilitat convert d\'ImageMagick';
+$lang['jpg_quality'] = 'Qualitat de compressió JPEG (0-100)';
+$lang['subscribers'] = 'Habilita la subscripció a pàgines';
+$lang['compress'] = 'Sortida CSS i Javascript compacta';
+$lang['hidepages'] = 'Oculta pàgines coincidents (expressions regulars)';
+$lang['send404'] = 'Envia "HTTP 404/Page Not Found" per a les pàgines inexistents';
+$lang['sitemap'] = 'Genera mapa del lloc en format Google (dies)';
+$lang['broken_iua'] = 'No funciona en el vostre sistema la funció ignore_user_abort? Això podria malmetre l\'índex de cerques. Amb IIS+PHP/CGI se sap que no funciona. Vg. <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> per a més informació.';
+$lang['xsendfile'] = 'Utilitza la capçalera X-Sendfile perquè el servidor web distribueixi fitxers estàtics. No funciona amb tots els servidors web.';
+$lang['renderer_xhtml'] = 'Renderitzador que cal utilitzar per a la sortida principal (xhtml) del wiki';
+$lang['renderer__core'] = '%s (ànima del dokuwiki)';
+$lang['renderer__plugin'] = '%s (connector)';
+$lang['rememberme'] = 'Permet galetes de sessió permanents ("recorda\'m")';
+$lang['rss_type'] = 'Tipus de canal XML';
+$lang['rss_linkto'] = 'Destinació dels enllaços en el canal XML';
+$lang['rss_content'] = 'Què es mostrarà en els elements del canal XML?';
+$lang['rss_update'] = 'Interval d\'actualització del canal XML (segons)';
+$lang['recent_days'] = 'Quantitat de canvis recents que es mantenen (dies)';
+$lang['rss_show_summary'] = 'Mostra resum en els títols del canal XML';
+$lang['target____wiki'] = 'Finestra de destinació en enllaços interns';
+$lang['target____interwiki'] = 'Finestra de destinació en enllaços interwiki';
+$lang['target____extern'] = 'Finestra de destinació en enllaços externs';
+$lang['target____media'] = 'Finestra de destinació en enllaços de mitjans';
+$lang['target____windows'] = 'Finestra de destinació en enllaços de Windows';
+$lang['proxy____host'] = 'Nom del servidor intermediari';
+$lang['proxy____port'] = 'Port del servidor intermediari';
+$lang['proxy____user'] = 'Nom d\'usuari del servidor intermediari';
+$lang['proxy____pass'] = 'Contrasenya del servidor intermediari';
+$lang['proxy____ssl'] = 'Utilitza SSL per connectar amb el servidor intermediari';
+$lang['safemodehack'] = 'Utilitza el hack per a safemode';
+$lang['ftp____host'] = 'Servidor FTP per al hack de safemode';
+$lang['ftp____port'] = 'Port FTP per al hack de safemode';
+$lang['ftp____user'] = 'Nom d\'usuari FTP per al hack de safemode';
+$lang['ftp____pass'] = 'Contrasenya FTP per al hack de safemode';
+$lang['ftp____root'] = 'Directori arrel FTP per al hack de safemode';
+$lang['license_o_'] = 'Cap selecció';
+$lang['typography_o_0'] = 'cap';
+$lang['typography_o_1'] = 'només cometes dobles';
+$lang['typography_o_2'] = 'totes les cometes (podria no funcionar sempre)';
+$lang['userewrite_o_0'] = 'cap';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'intern del DokuWiki';
+$lang['deaccent_o_0'] = 'desactivat';
+$lang['deaccent_o_1'] = 'treure accents';
+$lang['deaccent_o_2'] = 'romanització';
+$lang['gdlib_o_0'] = 'GD Lib no està disponible';
+$lang['gdlib_o_1'] = 'Versió 1.x';
+$lang['gdlib_o_2'] = 'Detecció automàtica';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Resum';
+$lang['rss_content_o_diff'] = 'Diff unificat';
+$lang['rss_content_o_htmldiff'] = 'Taula de diferències en format HTML';
+$lang['rss_content_o_html'] = 'Contingut complet de la pàgina en format HTML';
+$lang['rss_linkto_o_diff'] = 'Visualització de diferències';
+$lang['rss_linkto_o_page'] = 'pàgina modificada';
+$lang['rss_linkto_o_rev'] = 'llista de revisions';
+$lang['rss_linkto_o_current'] = 'revisió actual';
+$lang['compression_o_0'] = 'cap';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'no utilitzis';
+$lang['xsendfile_o_1'] = 'Capçalera pròpia de lighttpd (anterior a la versió 1.5)';
+$lang['xsendfile_o_2'] = 'Capçalera X-Sendfile estàndard';
+$lang['xsendfile_o_3'] = 'Capçalera X-Accel-Redirect de propietat de Nginx ';
+$lang['showuseras_o_loginname'] = 'Nom d\'usuari';
+$lang['showuseras_o_username'] = 'Nom complet de l\'usuari';
+$lang['showuseras_o_email'] = 'Adreça de correu electrònic de l\'usuari (ofuscada segons el paràmetre de configuració corresponent)';
+$lang['showuseras_o_email_link'] = 'Adreça de correu electrònic amb enllaç mailto:';
+$lang['useheading_o_0'] = 'Mai';
+$lang['useheading_o_navigation'] = 'Només navegació';
+$lang['useheading_o_content'] = 'Només contingut wiki';
+$lang['useheading_o_1'] = 'Sempre';
diff --git a/lib/plugins/config/lang/cs/intro.txt b/lib/plugins/config/lang/cs/intro.txt
new file mode 100644
index 000000000..63381b84e
--- /dev/null
+++ b/lib/plugins/config/lang/cs/intro.txt
@@ -0,0 +1,8 @@
+====== Správa nastavení ======
+
+Tuto stránku můžete používat ke správě nastavení vaší instalace DokuWiki. Nápovědu pro konkrétní položky nastavení naleznete na [[doku>config]]. Pro další detaily o tomto pluginu viz [[doku>plugin:config]].
+
+Položky se světle červeným pozadím jsou chráněné a nelze je upravovat tímto pluginem. Položky s modrým pozadím jsou výchozí hodnoty a položky s bílým pozadím byly nastaveny lokálně v této konkrétní instalaci. Modré i bílé položky je možné upravovat.
+
+Než opustíte tuto stránku, nezapomeňte stisknout tlačítko **Uložit**, jinak budou změny ztraceny.
+
diff --git a/lib/plugins/config/lang/cs/lang.php b/lib/plugins/config/lang/cs/lang.php
new file mode 100644
index 000000000..bf87e99d5
--- /dev/null
+++ b/lib/plugins/config/lang/cs/lang.php
@@ -0,0 +1,201 @@
+<?php
+/**
+ * Czech language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Bohumir Zamecnik <bohumir@zamecnik.org>
+ * @author Zbynek Krivka <zbynek.krivka@seznam.cz>
+ * @author tomas@valenta.cz
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @author Lefty <lefty@multihost.cz>
+ * @author Vojta Beran <xmamut@email.cz>
+ * @author zbynek.krivka@seznam.cz
+ */
+$lang['menu'] = 'Správa nastavení';
+$lang['error'] = 'Nastavení nebyla změněna kvůli alespoň jedné neplatné položce,
+zkontrolujte prosím své úpravy a odešlete je znovu.<br />
+Neplatné hodnoty se zobrazí v červeném rámečku.';
+$lang['updated'] = 'Nastavení byla úspěšně upravena.';
+$lang['nochoice'] = '(nejsou k dispozici žádné další volby)';
+$lang['locked'] = 'Nelze upravovat soubor s nastavením. Pokud to není záměrné,
+ujistěte se, <br /> že název a přístupová práva souboru s lokálním
+nastavením jsou v pořádku.';
+$lang['danger'] = 'Pozor: Změna tohoto nastavení může způsobit nedostupnost wiki a konfiguračních menu.';
+$lang['warning'] = 'Varování: Změna nastavení může mít za následek chybné chování.';
+$lang['security'] = 'Bezpečnostní varování: Změna tohoto nastavení může způsobit bezpečnostní riziko.';
+$lang['_configuration_manager'] = 'Správa nastavení';
+$lang['_header_dokuwiki'] = 'Nastavení DokuWiki';
+$lang['_header_plugin'] = 'Nastavení pluginů';
+$lang['_header_template'] = 'Nastavení šablon';
+$lang['_header_undefined'] = 'Další nastavení';
+$lang['_basic'] = 'Základní nastavení';
+$lang['_display'] = 'Nastavení zobrazení';
+$lang['_authentication'] = 'Nastavení autentizace';
+$lang['_anti_spam'] = 'Protispamová nastavení';
+$lang['_editing'] = 'Nastavení editace';
+$lang['_links'] = 'Nastavení odkazů';
+$lang['_media'] = 'Nastavení médií';
+$lang['_advanced'] = 'Pokročilá nastavení';
+$lang['_network'] = 'Nastavení sítě';
+$lang['_plugin_sufix'] = 'Nastavení pluginů ';
+$lang['_template_sufix'] = 'Nastavení šablon';
+$lang['_msg_setting_undefined'] = 'Chybí metadata položky.';
+$lang['_msg_setting_no_class'] = 'Chybí třída položky.';
+$lang['_msg_setting_no_default'] = 'Chybí výchozí hodnota položky.';
+$lang['fmode'] = 'Přístupová práva pro vytváření souborů';
+$lang['dmode'] = 'Přístupová práva pro vytváření adresářů';
+$lang['lang'] = 'Jazyk';
+$lang['basedir'] = 'Kořenový adresář (např. <code>/dokuwiki/</code>). Pro autodetekci nechte prázdné.';
+$lang['baseurl'] = 'Kořenové URL (např. <code>http://www.yourserver.com</code>). Pro autodetekci nechte prázdné.';
+$lang['savedir'] = 'Adresář pro ukládání dat';
+$lang['cookiedir'] = 'Cesta pro cookie. Není-li vyplněno, použije se kořenové URL.';
+$lang['start'] = 'Název úvodní stránky';
+$lang['title'] = 'Název celé wiki';
+$lang['template'] = 'Šablona';
+$lang['license'] = 'Pod jakou licencí má být tento obsah publikován?';
+$lang['fullpath'] = 'Ukazovat plnou cestu ke stránkám v patičce';
+$lang['recent'] = 'Nedávné změny';
+$lang['breadcrumbs'] = 'Počet odkazů na navštívené stránky';
+$lang['youarehere'] = 'Hierarchická "drobečková" navigace';
+$lang['typography'] = 'Provádět typografické nahrazování';
+$lang['htmlok'] = 'Povolit vložené HTML';
+$lang['phpok'] = 'Povolit vložené PHP';
+$lang['dformat'] = 'Formát data (viz PHP funkci <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Podpis';
+$lang['toptoclevel'] = 'Nejvyšší úroveň, kterou začít automaticky generovaný obsah';
+$lang['tocminheads'] = 'Nejnižší počet hlavních nadpisů, aby se vygeneroval obsah';
+$lang['maxtoclevel'] = 'Maximální počet úrovní v automaticky generovaném obsahu';
+$lang['maxseclevel'] = 'Nejnižší úroveň pro editaci i po sekcích';
+$lang['camelcase'] = 'Používat CamelCase v odkazech';
+$lang['deaccent'] = 'Čistit názvy stránek';
+$lang['useheading'] = 'Používat první nadpis jako název stránky';
+$lang['refcheck'] = 'Kontrolovat odkazy na média (před vymazáním)';
+$lang['refshow'] = 'Počet zobrazených odkazů na média';
+$lang['allowdebug'] = 'Povolit debugování. <b>Vypněte, pokud to nepotřebujete!</b>';
+$lang['usewordblock'] = 'Blokovat spam za použití seznamu známých spamových slov';
+$lang['indexdelay'] = 'Časová prodleva před indexací (v sekundách)';
+$lang['relnofollow'] = 'Používat rel="nofollow" na externí odkazy';
+$lang['mailguard'] = 'Metoda "zamaskování" emailových adres';
+$lang['iexssprotect'] = 'Zkontrolovat nahrané soubory vůči možnému škodlivému JavaScriptu či HTML';
+$lang['showuseras'] = 'Co se má přesně zobrazit, když se ukazuje uživatel, který naposledy editoval stránku';
+$lang['useacl'] = 'Používat přístupová práva (ACL)';
+$lang['autopasswd'] = 'Generovat hesla automaticky';
+$lang['authtype'] = 'Metoda autentizace';
+$lang['passcrypt'] = 'Metoda šifrování hesel';
+$lang['defaultgroup'] = 'Výchozí skupina';
+$lang['superuser'] = 'Superuživatel - skupina nebo uživatel s plnými právy pro přístup ke všem stránkách bez ohledu na nastavení ACL';
+$lang['manager'] = 'Manažer - skupina nebo uživatel s přístupem k některým správcovským funkcím';
+$lang['profileconfirm'] = 'Potvrdit změny v profilu zadáním hesla';
+$lang['disableactions'] = 'Vypnout DokuWiki akce';
+$lang['disableactions_check'] = 'Zkontrolovat';
+$lang['disableactions_subscription'] = 'Přihlásit se/Odhlásit se ze seznamu pro odběr změn';
+$lang['disableactions_wikicode'] = 'Prohlížet zdrojové kódy/Export wiki textu';
+$lang['disableactions_other'] = 'Další akce (oddělené čárkou)';
+$lang['sneaky_index'] = 'Ve výchozím nastavení DokuWiki zobrazuje v indexu všechny
+jmenné prostory. Zapnutím této volby se skryjí ty jmenné prostory,
+k nimž uživatel nemá právo pro čtení, což může ale způsobit, že
+vnořené jmenné prostory, k nimž právo má, budou přesto skryty.
+To může mít za následek, že index bude při některých
+nastaveních ACL nepoužitelný.';
+$lang['auth_security_timeout'] = 'Časový limit pro autentikaci (v sekundách)';
+$lang['securecookie'] = 'Má prohlížeč posílat cookies nastavené přes HTTPS opět jen přes HTTPS? Vypněte tuto volbu, pokud chcete, aby bylo pomocí SSL zabezpečeno pouze přihlašování do wiki, ale obsah budete prohlížet nezabezpečeně.';
+$lang['xmlrpc'] = 'Povolit/Zakázat rozhraní XML-RPC.';
+$lang['xmlrpcuser'] = 'Omezit přístup pomocí XML-RPC pouze na zde zadané skupiny či uživatele (oddělené čárkami). Necháte-li pole prázdné, dáte přístup komukoliv.';
+$lang['updatecheck'] = 'Kontrolovat aktualizace a bezpečnostní varování? DokuWiki potřebuje pro tuto funkci přístup k update.dokuwiki.org';
+$lang['userewrite'] = 'Používat "pěkná" URL';
+$lang['useslash'] = 'Používat lomítko jako oddělovač jmenných prostorů v URL';
+$lang['usedraft'] = 'Během editace ukládat koncept automaticky';
+$lang['sepchar'] = 'Znak pro oddělování slov v názvech stránek';
+$lang['canonical'] = 'Používat plně kanonická URL';
+$lang['fnencode'] = 'Metoda pro kódování ne-ASCII názvů souborů';
+$lang['autoplural'] = 'Kontrolovat plurálové tvary v odkazech';
+$lang['compression'] = 'Metoda komprese pro staré verze';
+$lang['cachetime'] = 'Maximální životnost cache (v sekundách)';
+$lang['locktime'] = 'Maximální životnost zámkových souborů (v sekundách)';
+$lang['fetchsize'] = 'Maximální velikost souboru (v bajtech), co ještě fetch.php bude stahovat z externích zdrojů';
+$lang['notify'] = 'Posílat oznámení o změnách na následující emailovou adresu';
+$lang['registernotify'] = 'Posílat informace o nově registrovaných uživatelích na tuto mailovou adresu';
+$lang['mailfrom'] = 'E-mailová adresa, která se bude používat pro automatické maily';
+$lang['mailprefix'] = 'Předpona předmětu e-mailu, která se bude používat pro automatické maily';
+$lang['gzip_output'] = 'Používat pro xhtml Content-Encoding gzip';
+$lang['gdlib'] = 'Verze GD knihovny';
+$lang['im_convert'] = 'Cesta k nástroji convert z balíku ImageMagick';
+$lang['jpg_quality'] = 'Kvalita komprese JPEG (0-100)';
+$lang['subscribers'] = 'Možnost přihlásit se k odběru novinek stránky';
+$lang['subscribe_time'] = 'Časový interval v sekundách, ve kterém jsou posílány změny a souhrny změn. Interval by neměl být kratší než čas uvedený v recent_days.';
+$lang['compress'] = 'Zahustit CSS a JavaScript výstup';
+$lang['cssdatauri'] = 'Velikost [v bajtech] obrázků odkazovaných v CSS souborech, které budou pro ušetření HTTP požadavku vestavěny do stylu. Tato technika nefunguje v IE 7 a starším. Doporučená hodnota je mezi <code>400</code> a <code>600</code> bajty. Pro vypnutí nastavte na <code>0</code>.';
+$lang['hidepages'] = 'Skrýt stránky odpovídající vzoru (regulární výrazy)';
+$lang['send404'] = 'Posílat "HTTP 404/Page Not Found" pro neexistují stránky';
+$lang['sitemap'] = 'Generovat Google sitemap (interval ve dnech)';
+$lang['broken_iua'] = 'Je na vašem systému funkce ignore_user_abort porouchaná? To může způsobovat nefunkčnost vyhledávacího indexu. O kombinaci IIS+PHP/CGI je známo, že nefunguje správně. Viz <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> pro více informací.';
+$lang['xsendfile'] = 'Používat X-Sendfile hlavničky pro download statických souborů z webserveru? Je však požadována podpora této funkce na straně Vašeho webserveru.';
+$lang['renderer_xhtml'] = 'Vykreslovací jádro pro hlavní (xhtml) výstup wiki';
+$lang['renderer__core'] = '%s (jádro DokuWiki)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Povolit trvaté přihlašovací cookies (zapamatuj si mě)';
+$lang['rss_type'] = 'Typ XML kanálu';
+$lang['rss_linkto'] = 'XML kanál odkazuje na';
+$lang['rss_content'] = 'Co zobrazovat v položkách XML kanálu?';
+$lang['rss_update'] = 'Interval aktualizace XML kanálu (v sekundách)';
+$lang['recent_days'] = 'Jak staré nedávných změny uchovávat (ve dnech)';
+$lang['rss_show_summary'] = 'XML kanál ukazuje souhrn v titulku';
+$lang['target____wiki'] = 'Cílové okno pro interní odkazy';
+$lang['target____interwiki'] = 'Cílové okno pro interwiki odkazy';
+$lang['target____extern'] = 'Cílové okno pro externí odkazy';
+$lang['target____media'] = 'Cílové okno pro odkazy na média';
+$lang['target____windows'] = 'Cílové okno pro odkazy na windows sdílení';
+$lang['proxy____host'] = 'Název proxy serveru';
+$lang['proxy____port'] = 'Proxy port';
+$lang['proxy____user'] = 'Proxy uživatelské jméno';
+$lang['proxy____pass'] = 'Proxy heslo';
+$lang['proxy____ssl'] = 'Použít SSL při připojení k proxy';
+$lang['proxy____except'] = 'Regulární výrazy pro URL, pro které bude přeskočena proxy.';
+$lang['safemodehack'] = 'Zapnout safemode hack';
+$lang['ftp____host'] = 'FTP server pro safemode hack';
+$lang['ftp____port'] = 'FTP port pro safemode hack';
+$lang['ftp____user'] = 'FTP uživatelské jméno pro safemode hack';
+$lang['ftp____pass'] = 'FTP heslo pro safemode hack';
+$lang['ftp____root'] = 'FTP kořenový adresář pro safemode hack';
+$lang['license_o_'] = 'Nic nevybráno';
+$lang['typography_o_0'] = 'vypnuto';
+$lang['typography_o_1'] = 'Pouze uvozovky';
+$lang['typography_o_2'] = 'Všechny typy uvozovek a apostrofů (nemusí vždy fungovat)';
+$lang['userewrite_o_0'] = 'vypnuto';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'interní metoda DokuWiki';
+$lang['deaccent_o_0'] = 'vypnuto';
+$lang['deaccent_o_1'] = 'odstranit diakritiku';
+$lang['deaccent_o_2'] = 'převést na latinku';
+$lang['gdlib_o_0'] = 'GD knihovna není k dispozici';
+$lang['gdlib_o_1'] = 'Verze 1.x';
+$lang['gdlib_o_2'] = 'Autodetekce';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Abstraktní';
+$lang['rss_content_o_diff'] = 'Sjednocený Diff';
+$lang['rss_content_o_htmldiff'] = 'diff tabulka v HTML formátu';
+$lang['rss_content_o_html'] = 'Úplný HTML obsah stránky';
+$lang['rss_linkto_o_diff'] = 'přehled změn';
+$lang['rss_linkto_o_page'] = 'stránku samotnou';
+$lang['rss_linkto_o_rev'] = 'seznam revizí';
+$lang['rss_linkto_o_current'] = 'nejnovější revize';
+$lang['compression_o_0'] = 'vypnuto';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nepoužívat';
+$lang['xsendfile_o_1'] = 'Proprietární hlavička lighttpd (před releasem 1.5)';
+$lang['xsendfile_o_2'] = 'Standardní hlavička X-Sendfile';
+$lang['xsendfile_o_3'] = 'Proprietární hlavička Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Přihlašovací jméno';
+$lang['showuseras_o_username'] = 'Celé jméno uživatele';
+$lang['showuseras_o_email'] = 'E-mailová adresa uživatele ("zamaskována" aktuálně nastavenou metodou)';
+$lang['showuseras_o_email_link'] = 'E-mailová adresa uživatele jako mailto: odkaz';
+$lang['useheading_o_0'] = 'Nikdy';
+$lang['useheading_o_navigation'] = 'Pouze pro navigaci';
+$lang['useheading_o_content'] = 'Pouze pro wiki obsah';
+$lang['useheading_o_1'] = 'Vždy';
+$lang['readdircache'] = 'Maximální stáří readdir cache (sec)';
diff --git a/lib/plugins/config/lang/da/intro.txt b/lib/plugins/config/lang/da/intro.txt
new file mode 100644
index 000000000..f20961b98
--- /dev/null
+++ b/lib/plugins/config/lang/da/intro.txt
@@ -0,0 +1,8 @@
+====== Opsætningsstyring ======
+
+Brug denne side til at kontrollere indstillingerne for din Dokuwiki-opsætning. For at få hjælp med specifikke indstillinger, se [[doku>config]]. For flere detaljer om denne udvidelse, se [[doku>plugin:config]].
+
+Indstillinger vist med lys rød baggrund er beskyttede og kan ikke ændres med denne udvidelse. Indstillinger vist med blå baggrund er standardindstillinger og indstillinger vist med hvid baggrund er blevet sat lokalt denne konkrete opsætning. Både blå og hvide indstillinger kan ændres.
+
+Husk at trykke på **Gem**-knappen før du forlader siden, for at du ikke mister dine ændringer.
+
diff --git a/lib/plugins/config/lang/da/lang.php b/lib/plugins/config/lang/da/lang.php
new file mode 100644
index 000000000..a4c0bba75
--- /dev/null
+++ b/lib/plugins/config/lang/da/lang.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * Danish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Lars Næsbye Christensen <larsnaesbye@stud.ku.dk>
+ * @author Kalle Sommer Nielsen <kalle@php.net>
+ * @author Esben Laursen <hyber@hyber.dk>
+ * @author Harith <haj@berlingske.dk>
+ * @author Daniel Ejsing-Duun <dokuwiki@zilvador.dk>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author rasmus@kinnerup.com
+ * @author Michael Pedersen subben@gmail.com
+ */
+$lang['menu'] = 'Opsætningsindstillinger';
+$lang['error'] = 'Indstillingerne blev ikke opdateret på grund af en ugyldig værdi, Gennemse venligst dine ændringer og gem dem igen.
+ <br />Ugyldige værdier vil blive rammet ind med rødt.';
+$lang['updated'] = 'Indstillingerne blev opdateret korrekt.';
+$lang['nochoice'] = '(ingen andre valgmuligheder)';
+$lang['locked'] = 'Indstillingsfilen kunne ikke opdateres, Hvis dette er en fejl, <br />
+sørg da for at navnet på den lokale indstillingsfil samt dens rettigheder er korrekte.';
+$lang['danger'] = 'Fare: Ændring af denne mulighed kan gøre din wiki og opsætningsoversigt utilgængelige.';
+$lang['warning'] = 'Advarsel: Ændring af denne mulighed kan forårsage utilsigtet opførsel.';
+$lang['security'] = 'Sikkerhedsadvarsel: Ændring af denne mulighed kan forårsage en sikkerhedsrisiko.';
+$lang['_configuration_manager'] = 'Opsætningsstyring';
+$lang['_header_dokuwiki'] = 'DokuWiki indstillinger';
+$lang['_header_plugin'] = 'Udvidelsesindstillinger';
+$lang['_header_template'] = 'Skabelonindstillinger';
+$lang['_header_undefined'] = 'Ikke satte indstillinger';
+$lang['_basic'] = 'Grundindstillinger';
+$lang['_display'] = 'Synlighedsindstillinger';
+$lang['_authentication'] = 'Bekræftelsesindstillinger';
+$lang['_anti_spam'] = 'Trafikkontrolsindstillinger';
+$lang['_editing'] = 'Redigeringsindstillinger';
+$lang['_links'] = 'Henvisningsindstillinger';
+$lang['_media'] = 'Medieindstillinger';
+$lang['_advanced'] = 'Avancerede indstillinger';
+$lang['_network'] = 'Netværksindstillinger';
+$lang['_plugin_sufix'] = 'Udvidelsesindstillinger';
+$lang['_template_sufix'] = 'Skabelonindstillinger';
+$lang['_msg_setting_undefined'] = 'Ingen indstillingsmetadata.';
+$lang['_msg_setting_no_class'] = 'Ingen indstillingsklasse.';
+$lang['_msg_setting_no_default'] = 'Ingen standardværdi.';
+$lang['fmode'] = 'Filoprettelsestilstand';
+$lang['dmode'] = 'Katalogoprettelsestilstand';
+$lang['lang'] = 'Sprog';
+$lang['basedir'] = 'Grundkatalog';
+$lang['baseurl'] = 'Grundadresse';
+$lang['savedir'] = 'Katalog til opbevaring af data';
+$lang['start'] = 'Startsidens navn';
+$lang['title'] = 'Wiki titel';
+$lang['template'] = 'Skabelon';
+$lang['license'] = 'Under hvilken licens skal dit indhold frigives?';
+$lang['fullpath'] = 'Vis den fulde sti til siderne i bundlinjen';
+$lang['recent'] = 'Nylige ændringer';
+$lang['breadcrumbs'] = 'Stilængde';
+$lang['youarehere'] = 'Hierarkisk sti';
+$lang['typography'] = 'Typografiske erstatninger';
+$lang['htmlok'] = 'Tillad indlejret HTML';
+$lang['phpok'] = 'Tillad indlejret PHP';
+$lang['dformat'] = 'Datoformat (se PHP\'s <a href="http://www.php.net/strftime">strftime</a>-funktion)';
+$lang['signature'] = 'Underskrift';
+$lang['toptoclevel'] = 'Øverste niveau for indholdsfortegnelse';
+$lang['tocminheads'] = 'Mindste antal overskrifter for at danne Indholdsfortegnelsen';
+$lang['maxtoclevel'] = 'Højeste niveau for indholdsfortegnelse';
+$lang['maxseclevel'] = 'Højeste niveau for redigering af sektioner';
+$lang['camelcase'] = 'Brug KamelKasse til henvisninger';
+$lang['deaccent'] = 'Pæne sidenavne';
+$lang['useheading'] = 'Brug første overskrift til sidenavne';
+$lang['refcheck'] = 'Mediehenvisningerkontrol';
+$lang['refshow'] = 'Antal viste mediehenvisninger';
+$lang['allowdebug'] = 'Tillad fejlretning <b>slå fra hvis unødvendig!</b>';
+$lang['usewordblock'] = 'Hindr uønsket brug med en ordliste';
+$lang['indexdelay'] = 'Tidsforsinkelse før katalogisering (sek.)';
+$lang['relnofollow'] = 'Brug rel="nofollow" til udadgående henvisninger';
+$lang['mailguard'] = 'Slør elektroniske adresser';
+$lang['iexssprotect'] = 'Gennemse oplagte filer for mulig skadelig JavaScript- eller HTML-kode.';
+$lang['showuseras'] = 'Hvad skal vises når den sidste bruger, der har ændret siden, fremstilles';
+$lang['useacl'] = 'Benyt adgangskontrollister';
+$lang['autopasswd'] = 'Generer adgangskoder automatisk';
+$lang['authtype'] = 'Bekræftelsesgrundlag';
+$lang['passcrypt'] = 'Krypteringsmetode for adgangskoder';
+$lang['defaultgroup'] = 'Standardgruppe';
+$lang['superuser'] = 'Superbruger';
+$lang['manager'] = 'Bestyrer - en gruppe eller bruger med adgang til bestemte styrende funktioner';
+$lang['profileconfirm'] = 'Bekræft profilændringer med kodeord';
+$lang['disableactions'] = 'Slå DokuWiki-muligheder fra';
+$lang['disableactions_check'] = 'Tjek';
+$lang['disableactions_subscription'] = 'Tliføj/Fjern opskrivning';
+$lang['disableactions_wikicode'] = 'Vis kilde/Eksporter grundkode';
+$lang['disableactions_other'] = 'Andre muligheder (kommasepareret)';
+$lang['sneaky_index'] = 'DokuWiki vil som standard vise alle navnerum i indholdsfortegnelsen. Ved at slå denne valgmulighed til vil skjule de navnerum, hvor brugeren ikke har læsetilladelse. Dette kan føre til, at tilgængelige undernavnerum bliver skjult. Ligeledes kan det også gøre indholdsfortegnelsen ubrugelig med visse ACL-opsætninger.';
+$lang['auth_security_timeout'] = 'Tidsudløb for bekræftelse (sekunder)';
+$lang['securecookie'] = 'Skal datafiler skabt af HTTPS kun sendes af HTTPS gennem browseren? Slå denne valgmulighed fra hvis kun brugen af din wiki er SSL-beskyttet, mens den almindelige tilgang udefra ikke er sikret.';
+$lang['xmlrpc'] = 'Slå XML-RPC-grænseflade til/fra.';
+$lang['xmlrpcuser'] = 'Begræns XML-RPC-adgang til de nævnte og med komma adskilte grupper eller brugere. Lad den stå tom for at give alle adgang.';
+$lang['updatecheck'] = 'Kig efter opdateringer og sikkerhedsadvarsler? DokuWiki er nødt til at kontakte update.dokuwiki.org for at tilgå denne funktion.';
+$lang['userewrite'] = 'Brug pæne netadresser';
+$lang['useslash'] = 'Brug skråstreg som navnerumsdeler i netadresser';
+$lang['usedraft'] = 'Gem automatisk en kladde under redigering';
+$lang['sepchar'] = 'Orddelingstegn til sidenavne';
+$lang['canonical'] = 'Benyt fuldt kanoniske netadresser';
+$lang['fnencode'] = 'Metode for indkodning af ikke ASCII filnavne';
+$lang['autoplural'] = 'Tjek for flertalsendelser i henvisninger';
+$lang['compression'] = 'Pakningsmetode for attic-filer';
+$lang['cachetime'] = 'Længste levetid for "cache" (sek)';
+$lang['locktime'] = 'Længste levetid for låsefiler (sek)';
+$lang['fetchsize'] = 'Største antal (bytes) fetch.php må hente udefra';
+$lang['notify'] = 'Send ændringsmeddelelser til denne e-adresse';
+$lang['registernotify'] = 'Send info om nyoprettede brugere til denne e-adresse';
+$lang['mailfrom'] = 'E-adresse til brug for automatiske meddelelser';
+$lang['gzip_output'] = 'Benyt gzip-Content-Encoding (indholdskryptering) til XHTML';
+$lang['gdlib'] = 'Udgave af GD Lib';
+$lang['im_convert'] = 'Sti til ImageMagick\'s omdannerværktøj';
+$lang['jpg_quality'] = 'JPG komprimeringskvalitet (0-100)';
+$lang['subscribers'] = 'Slå understøttelse af abonnement på sider til';
+$lang['subscribe_time'] = 'Tid der går før abonnementlister og nyhedsbreve er sendt (i sekunder). Denne værdi skal være mindre end den tid specificeret under recent_days.';
+$lang['compress'] = 'Komprimer CSS- og JavaScript-filer';
+$lang['hidepages'] = 'Skjul lignende sider (almindelige udtryk)';
+$lang['send404'] = 'Send "HTTP 404/Page Not Found" for ikke-eksisterende sider';
+$lang['sitemap'] = 'Generer Google-"sitemap" (dage)';
+$lang['broken_iua'] = 'Er funktionen "ignore_user_abort" uvirksom på dit system? Dette kunne forårsage en ikke virkende søgeoversigt. IIS+PHP/CGI er kendt for ikke at virke. Se <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Fejl 852</a> for flere oplysninger.';
+$lang['xsendfile'] = 'Brug hovedfilen til X-Sendfile for at få netserveren til at sende statiske filer? Din netserver skal understøtte dette for at bruge det.';
+$lang['renderer_xhtml'] = 'Udskriver der skal bruges til størstedelen af wiki-udskriften (XHTML)';
+$lang['renderer__core'] = '%s (dokuwiki-kerne)';
+$lang['renderer__plugin'] = '%s (udvidelse)';
+$lang['rememberme'] = 'Tillad varige datafiler for brugernavne (husk mig)';
+$lang['rss_type'] = 'Type af XML-liste';
+$lang['rss_linkto'] = 'XML-liste henviser til';
+$lang['rss_content'] = 'Hvad skal der vises i XML-listepunkteren?';
+$lang['rss_update'] = 'XML-listens opdateringsinterval (sek)';
+$lang['recent_days'] = 'Hvor mange nye ændringer der skal beholdes (dage)';
+$lang['rss_show_summary'] = 'XML-liste vis referat i overskriften';
+$lang['target____wiki'] = 'Målvindue for indre henvisninger';
+$lang['target____interwiki'] = 'Målvindue for egne wikihenvisninger ';
+$lang['target____extern'] = 'Målvindue for udadgående henvisninger';
+$lang['target____media'] = 'Målvindue for mediehenvisninger';
+$lang['target____windows'] = 'Målvindue til Windows-henvisninger';
+$lang['proxy____host'] = 'Proxy-servernavn';
+$lang['proxy____port'] = 'Proxy-port';
+$lang['proxy____user'] = 'Proxy-brugernavn';
+$lang['proxy____pass'] = 'Proxy-kodeord';
+$lang['proxy____ssl'] = 'Brug SSL til at forbinde til proxy';
+$lang['proxy____except'] = 'Regular expression til at matche URL\'er for hvilke proxier der skal ignores';
+$lang['safemodehack'] = 'Slå "safemode hack" til ';
+$lang['ftp____host'] = 'FTP-server til "safemode hack"';
+$lang['ftp____port'] = 'FTP-port til "safemode hack"';
+$lang['ftp____user'] = 'FTP-brugernavn til "safemode hack"';
+$lang['ftp____pass'] = 'FTP-adgangskode til "safemode hack"';
+$lang['ftp____root'] = 'FTP-rodmappe til "safemode hack"';
+$lang['license_o_'] = 'Ingen valgt';
+$lang['typography_o_0'] = 'ingen';
+$lang['typography_o_1'] = 'Kun gåseøjne';
+$lang['typography_o_2'] = 'Tillader enkelttegnscitering (vil måske ikke altid virke)';
+$lang['userewrite_o_0'] = 'ingen';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Dokuwiki indre';
+$lang['deaccent_o_0'] = 'fra';
+$lang['deaccent_o_1'] = 'fjern accenttegn';
+$lang['deaccent_o_2'] = 'romaniser';
+$lang['gdlib_o_0'] = 'GD Lib ikke tilstede';
+$lang['gdlib_o_1'] = 'Udgave 1.x';
+$lang['gdlib_o_2'] = 'automatisk sondering';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Abstrakt';
+$lang['rss_content_o_diff'] = '"Unified Diff" (Sammensat)';
+$lang['rss_content_o_htmldiff'] = 'HTML-formateret diff-tabel';
+$lang['rss_content_o_html'] = 'Fuldt HTML-sideindhold';
+$lang['rss_linkto_o_diff'] = 'liste over forskelle';
+$lang['rss_linkto_o_page'] = 'den redigerede side';
+$lang['rss_linkto_o_rev'] = 'liste over ændringer';
+$lang['rss_linkto_o_current'] = 'den nuværende side';
+$lang['compression_o_0'] = 'ingen';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'brug ikke';
+$lang['xsendfile_o_1'] = 'Proprietær lighttpd-hovedfil (før udgave 1.5)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile-hovedfil';
+$lang['xsendfile_o_3'] = 'Proprietær Nginx X-Accel-Redirect hovedfil';
+$lang['showuseras_o_loginname'] = 'Brugernavn';
+$lang['showuseras_o_username'] = 'Brugerens fulde navn';
+$lang['showuseras_o_email'] = 'Brugerens e-adresse (ændret i forhold til mailguard-indstillingerne)';
+$lang['showuseras_o_email_link'] = 'Brugers e-adresse som en mailto:-henvisning';
+$lang['useheading_o_0'] = 'Aldrig';
+$lang['useheading_o_navigation'] = 'Kun navigering';
+$lang['useheading_o_content'] = 'Kun wiki-indhold';
+$lang['useheading_o_1'] = 'Altid';
+$lang['readdircache'] = 'Maksimum alder for readdir hukommelse (sek)';
diff --git a/lib/plugins/config/lang/de-informal/intro.txt b/lib/plugins/config/lang/de-informal/intro.txt
new file mode 100644
index 000000000..7ac1b47d9
--- /dev/null
+++ b/lib/plugins/config/lang/de-informal/intro.txt
@@ -0,0 +1,7 @@
+===== Einstellungs-Manager =====
+
+Benutze diese Seite zur Kontrolle der Einstellungen deiner DokuWiki-Installation. Für Hilfe zu individuellen Einstellungen gehe zu [[doku>config]]. Für mehr Details über diese Erweiterungen siehe [[doku>plugin:config]].
+
+Einstellungen die mit einem hellroten Hintergrund angezeigt werden, können mit dieser Erweiterung nicht verändert werden. Einstellungen mit einem blauen Hintergrund sind Standardwerte und Einstellungen mit einem weißen Hintergrund wurden lokal gesetzt für diese Installation. Sowohl blaue als auch weiße Einstellungen können angepasst werden.
+
+Denke dran **Speichern** zu drücken bevor du die Seite verlässt, andernfalls werden deine Änderungen nicht übernommen. \ No newline at end of file
diff --git a/lib/plugins/config/lang/de-informal/lang.php b/lib/plugins/config/lang/de-informal/lang.php
new file mode 100644
index 000000000..1a66c4a8e
--- /dev/null
+++ b/lib/plugins/config/lang/de-informal/lang.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * German (informal) language file
+ *
+ * @author Alexander Fischer <tbanus@os-forge.net>
+ * @author Juergen Schwarzer <jschwarzer@freenet.de>
+ * @author Marcel Metz <marcel_metz@gmx.de>
+ * @author Matthias Schulte <post@lupo49.de>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Einstellungen';
+$lang['error'] = 'Einstellungen wurden nicht aktualisiert auf Grund eines ungültigen Wertes. Bitte überprüfe deine Änderungen und versuche es erneut.<br />Die/der ungültige(n) Wert(e) werden durch eine rote Umrandung hervorgehoben.';
+$lang['updated'] = 'Einstellungen erfolgreich aktualisiert.';
+$lang['nochoice'] = '(keine andere Option möglich)';
+$lang['locked'] = 'Die Einstellungsdatei kann nicht aktualisiert werden. Wenn dies unbeabsichtigt ist stelle sicher, dass der Name und die Zugriffsrechte der Einstellungsdatei richtig sind.';
+$lang['danger'] = '**Achtung**: Eine Änderung dieser Einstellung kann dein Wiki und das Einstellungsmenü unerreichbar machen.';
+$lang['warning'] = 'Achtung: Eine Änderungen dieser Option kann zu unbeabsichtigtem Verhalten führen.';
+$lang['security'] = 'Sicherheitswarnung: Eine Änderungen dieser Option können ein Sicherheitsrisiko bedeuten.';
+$lang['_configuration_manager'] = 'Einstellungen';
+$lang['_header_dokuwiki'] = 'DokuWiki-Einstellungen';
+$lang['_header_plugin'] = 'Plugin-Einstellungen';
+$lang['_header_template'] = 'Vorlageneinstellungen';
+$lang['_header_undefined'] = 'unbestimmte Einstellungen';
+$lang['_basic'] = 'Grundeinstellungen';
+$lang['_display'] = 'Darstellungs-Einstellungen';
+$lang['_authentication'] = 'Bestätigungseinstellungen';
+$lang['_anti_spam'] = 'Anti-Spam-Einstellungen';
+$lang['_editing'] = 'Bearbeitungseinstellungen';
+$lang['_links'] = 'Link-Einstellungen';
+$lang['_media'] = 'Media-Einstellungen';
+$lang['_advanced'] = 'erweiterte Einstellungen';
+$lang['_network'] = 'Netzwerk-Einstellungen';
+$lang['_plugin_sufix'] = 'Plugin-Einstellungen';
+$lang['_template_sufix'] = 'Vorlageneinstellungen';
+$lang['_msg_setting_undefined'] = 'Keine Konfigurationsmetadaten.';
+$lang['_msg_setting_no_class'] = 'Keine Konfigurationsklasse.';
+$lang['_msg_setting_no_default'] = 'Kein Standardwert.';
+$lang['fmode'] = 'Zugriffsrechte bei Dateierstellung';
+$lang['dmode'] = 'Zugriffsrechte bei Verzeichniserstellung';
+$lang['lang'] = 'Sprache';
+$lang['basedir'] = 'Installationsverzeichnis';
+$lang['baseurl'] = 'Installationspfad (URL)';
+$lang['savedir'] = 'Ordner zum Speichern von Daten';
+$lang['cookiedir'] = 'Cookie Pfad. Leer lassen, um die Standard-Url zu belassen.';
+$lang['start'] = 'Name der Startseite';
+$lang['title'] = 'Wiki Titel';
+$lang['template'] = 'Vorlage';
+$lang['license'] = 'Unter welcher Lizenz sollte Ihr Inhalt veröffentlicht werden?';
+$lang['fullpath'] = 'Zeige vollen Pfad der Datei in Fußzeile an';
+$lang['recent'] = 'letzte Änderungen';
+$lang['breadcrumbs'] = 'Anzahl der Einträge im "Krümelpfad"';
+$lang['youarehere'] = 'Hierarchische Pfadnavigation verwenden';
+$lang['typography'] = 'Mach drucktechnische Ersetzungen';
+$lang['htmlok'] = 'Erlaube eingebettetes HTML';
+$lang['phpok'] = 'Erlaube eingebettetes PHP';
+$lang['dformat'] = 'Datumsformat (siehe PHPs <a href="http://www.php.net/strftime">strftime</a> Funktion)';
+$lang['signature'] = 'Signatur';
+$lang['toptoclevel'] = 'Inhaltsverzeichnis bei dieser Überschriftengröße beginnen';
+$lang['tocminheads'] = 'Mindestanzahl der Überschriften die entscheidet, ob ein Inhaltsverzeichnis erscheinen soll';
+$lang['maxtoclevel'] = 'Maximale Überschriftsgröße für Inhaltsverzeichnis';
+$lang['maxseclevel'] = 'Abschnitte bis zu dieser Stufe einzeln editierbar machen';
+$lang['camelcase'] = 'CamelCase-Verlinkungen verwenden';
+$lang['deaccent'] = 'Seitennamen bereinigen';
+$lang['useheading'] = 'Erste Überschrift als Seitennamen verwenden';
+$lang['refcheck'] = 'Auf Verwendung beim Löschen von Media-Dateien testen';
+$lang['refshow'] = 'Wie viele Verwendungsorte der Media-Datei zeigen';
+$lang['allowdebug'] = 'Debug-Ausgaben erlauben <b>Abschalten wenn nicht benötigt!</b>';
+$lang['mediarevisions'] = 'Media-Revisionen (ältere Versionen) aktivieren?';
+$lang['usewordblock'] = 'Blockiere Spam basierend auf der Wortliste';
+$lang['indexdelay'] = 'Zeit bevor Suchmaschinenindexierung erlaubt ist';
+$lang['relnofollow'] = 'rel="nofollow" verwenden';
+$lang['mailguard'] = 'E-Mail-Adressen schützen';
+$lang['iexssprotect'] = 'Hochgeladene Dateien auf bösartigen JavaScript- und HTML-Code untersuchen';
+$lang['showuseras'] = 'Was angezeigt werden soll, wenn der Benutzer, der zuletzt eine Seite bearbeitet hat, angezeigt wird';
+$lang['useacl'] = 'Benutze Zugangskontrollliste';
+$lang['autopasswd'] = 'Automatisch erzeugte Passwörter';
+$lang['authtype'] = 'Authentifizierungsmethode';
+$lang['passcrypt'] = 'Passwortverschlüsselungsmethode';
+$lang['defaultgroup'] = 'Standardgruppe';
+$lang['superuser'] = 'Administrator - Eine Gruppe oder Nutzer mit vollem Zugriff auf alle Seiten und Administrationswerkzeuge.';
+$lang['manager'] = 'Manager - Eine Gruppe oder Nutzer mit Zugriff auf einige Administrationswerkzeuge.';
+$lang['profileconfirm'] = 'Änderungen am Benutzerprofil mit Passwort bestätigen';
+$lang['disableactions'] = 'Deaktiviere DokuWiki\'s Zugriffe';
+$lang['disableactions_check'] = 'Check';
+$lang['disableactions_subscription'] = 'Bestellen/Abbestellen';
+$lang['disableactions_wikicode'] = 'Zeige Quelle/Exportiere Rohdaten';
+$lang['disableactions_other'] = 'Weitere Aktionen (durch Komma getrennt)';
+$lang['sneaky_index'] = 'Standardmäßig zeigt DokuWiki alle Namensräume in der Indexansicht an. Bei Aktivierung dieser Einstellung werden alle Namensräume versteckt, in welchen der Benutzer keine Leserechte hat. Dies könnte dazu führen, dass lesbare Unternamensräume versteckt werden. Dies kann die Indexansicht bei bestimmten Zugangskontrolleinstellungen unbenutzbar machen.';
+$lang['auth_security_timeout'] = 'Zeitüberschreitung bei der Authentifizierung (Sekunden)';
+$lang['securecookie'] = 'Sollen Cookies, die via HTTPS gesetzt wurden nur per HTTPS versendet werden? Deaktiviere diese Option, wenn nur der Login deines Wikis mit SSL gesichert ist, aber das Betrachten des Wikis ungesichert geschieht.';
+$lang['xmlrpc'] = 'Aktiviere/Deaktiviere die XML-RPC-Schnittstelle';
+$lang['xmlrpcuser'] = 'XML-RPC-Zugriff auf folgende Gruppen oder Benutzer (kommasepariert) beschränken. Wenn du dieses Feld leer lässt, wir der Zugriff jedem gewährt.';
+$lang['updatecheck'] = 'Automatisch auf Updates und Sicherheitswarnungen prüfen? DokuWiki muss sich dafür mit update.dokuwiki.org verbinden.';
+$lang['userewrite'] = 'Benutze schöne URLs';
+$lang['useslash'] = 'Benutze Schrägstrich als Namensraumtrenner in URLs';
+$lang['usedraft'] = 'Speichere automatisch Entwürfe während der Bearbeitung';
+$lang['sepchar'] = 'Worttrenner für Seitennamen in URLs';
+$lang['canonical'] = 'Immer Links mit vollständigen URLs erzeugen';
+$lang['fnencode'] = 'Methode um nicht-ASCII Dateinamen zu kodieren.';
+$lang['autoplural'] = 'Bei Links automatisch nach vorhandenen Pluralformen suchen';
+$lang['compression'] = 'Komprimierungsmethode für alte Seitenrevisionen';
+$lang['cachetime'] = 'Maximale Cachespeicherung (Sekunden)';
+$lang['locktime'] = 'Maximales Alter für Seitensperren (Sekunden)';
+$lang['fetchsize'] = 'Maximale Größe (in Bytes), die fetch.php von extern herunterladen darf';
+$lang['notify'] = 'Sende Änderungsbenachrichtigungen an diese E-Mail-Adresse.';
+$lang['registernotify'] = 'Sende Information bei neu registrierten Benutzern an diese E-Mail-Adresse.';
+$lang['mailfrom'] = 'Absenderadresse für automatisch erzeugte E-Mails';
+$lang['mailprefix'] = 'Präfix für E-Mail-Betreff beim automatischen Versand von Benachrichtigungen';
+$lang['gzip_output'] = 'Seiten mit gzip komprimiert ausliefern';
+$lang['gdlib'] = 'GD Lib Version';
+$lang['im_convert'] = 'Pfad zu ImageMagicks-Konvertierwerkzeug';
+$lang['jpg_quality'] = 'JPEG Kompressionsqualität (0-100)';
+$lang['subscribers'] = 'E-Mail-Abos zulassen';
+$lang['subscribe_time'] = 'Zeit nach der Zusammenfassungs- und Änderungslisten-E-Mails verschickt werden; Dieser Wert sollte kleiner als die in recent_days konfigurierte Zeit sein.';
+$lang['compress'] = 'JavaScript und Stylesheets komprimieren';
+$lang['cssdatauri'] = 'Größe in Bytes, bis zu der Bilder in css-Dateien referenziert werden können, um HTTP-Anfragen zu minimieren. Diese Technik funktioniert nicht im IE 7 und älter! <code>400</code> bis <code>600</code> Bytes sind gute Werte. Setze <code>0</code> für inaktive Funktion.';
+$lang['hidepages'] = 'Seiten verstecken (Regulärer Ausdruck)';
+$lang['send404'] = 'Sende "HTTP 404/Seite nicht gefunden" für nicht existierende Seiten';
+$lang['sitemap'] = 'Erzeuge Google Sitemaps (Tage)';
+$lang['broken_iua'] = 'Falls die Funktion ignore_user_abort auf deinem System nicht funktioniert, könnte der Such-Index nicht funktionieren. IIS+PHP/CGI ist bekannt dafür. Siehe auch <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>.';
+$lang['xsendfile'] = 'Den X-Sendfile-Header nutzen, um Dateien direkt vom Webserver ausliefern zu lassen? Dein Webserver muss dies unterstützen!';
+$lang['renderer_xhtml'] = 'Standard-Renderer für die normale (XHTML) Wiki-Ausgabe.';
+$lang['renderer__core'] = '%s (DokuWiki Kern)';
+$lang['renderer__plugin'] = '%s (Erweiterung)';
+$lang['rememberme'] = 'Permanente Login-Cookies erlauben (Auf diesem Computer eingeloggt bleiben)';
+$lang['rss_type'] = 'XML-Feed-Format';
+$lang['rss_linkto'] = 'XML-Feed verlinken auf';
+$lang['rss_content'] = 'Was soll in XML-Feedinhalten angezeigt werden?';
+$lang['rss_update'] = 'Aktualisierungsintervall für XML-Feeds (Sekunden)';
+$lang['recent_days'] = 'Wie viele Änderungen sollen vorgehalten werden? (Tage)';
+$lang['rss_show_summary'] = 'Bearbeitungs-Zusammenfassung im XML-Feed anzeigen';
+$lang['target____wiki'] = 'Zielfenstername für interne Links';
+$lang['target____interwiki'] = 'Zielfenstername für InterWiki-Links';
+$lang['target____extern'] = 'Zielfenstername für externe Links';
+$lang['target____media'] = 'Zielfenstername für Medienlinks';
+$lang['target____windows'] = 'Zielfenstername für Windows-Freigaben-Links';
+$lang['proxy____host'] = 'Proxyadresse';
+$lang['proxy____port'] = 'Proxyport';
+$lang['proxy____user'] = 'Benutzername für den Proxy';
+$lang['proxy____pass'] = 'Passwort von dem Proxybenutzer';
+$lang['proxy____ssl'] = 'SSL verwenden um auf den Proxy zu zugreifen';
+$lang['proxy____except'] = 'Regulärer Ausdruck um Adressen zu beschreiben, für die kein Proxy verwendet werden soll';
+$lang['safemodehack'] = 'Aktiviere safemode Hack';
+$lang['ftp____host'] = 'FTP Server für safemode Hack';
+$lang['ftp____port'] = 'FTP Port für safemode Hack';
+$lang['ftp____user'] = 'FTP Benutzername für safemode Hack';
+$lang['ftp____pass'] = 'FTP Passwort für safemode Hack';
+$lang['ftp____root'] = 'FTP Wurzelverzeichnis für Safemodehack';
+$lang['license_o_'] = 'Nichts ausgewählt';
+$lang['typography_o_0'] = 'nichts';
+$lang['typography_o_1'] = 'ohne einfache Anführungszeichen';
+$lang['typography_o_2'] = 'mit einfachen Anführungszeichen (funktioniert nicht immer)';
+$lang['userewrite_o_0'] = 'nichts';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki intern';
+$lang['deaccent_o_0'] = 'aus';
+$lang['deaccent_o_1'] = 'Entferne Akzente';
+$lang['deaccent_o_2'] = 'romanisieren';
+$lang['gdlib_o_0'] = 'GD lib ist nicht verfügbar';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Autoerkennung';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Zusammenfassung';
+$lang['rss_content_o_diff'] = 'Vereinigtes Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML formatierte Diff-Tabelle';
+$lang['rss_content_o_html'] = 'Vollständiger HTML-Inhalt';
+$lang['rss_linkto_o_diff'] = 'Ansicht der Unterschiede';
+$lang['rss_linkto_o_page'] = 'geänderte Seite';
+$lang['rss_linkto_o_rev'] = 'Liste der Revisionen';
+$lang['rss_linkto_o_current'] = 'Die aktuelle Seite';
+$lang['compression_o_0'] = 'nichts';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'Nicht benutzen';
+$lang['xsendfile_o_1'] = 'Proprietärer lighttpd-Header (vor Release 1.5)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile-Header';
+$lang['xsendfile_o_3'] = 'Proprietärer Nginx X-Accel-Redirect-Header';
+$lang['showuseras_o_loginname'] = 'Login-Name';
+$lang['showuseras_o_username'] = 'Voller Name des Nutzers';
+$lang['showuseras_o_email'] = 'E-Mail-Adresse des Benutzers (je nach Mailguard-Einstellung verschleiert)';
+$lang['showuseras_o_email_link'] = 'E-Mail-Adresse des Benutzers als mailto:-Link';
+$lang['useheading_o_0'] = 'Niemals';
+$lang['useheading_o_navigation'] = 'Nur Navigation';
+$lang['useheading_o_content'] = 'Nur Wiki-Inhalt';
+$lang['useheading_o_1'] = 'Immer';
+$lang['readdircache'] = 'Maximales Alter des readdir-Caches (Sekunden)';
diff --git a/lib/plugins/config/lang/de/intro.txt b/lib/plugins/config/lang/de/intro.txt
new file mode 100644
index 000000000..efb807738
--- /dev/null
+++ b/lib/plugins/config/lang/de/intro.txt
@@ -0,0 +1,10 @@
+====== Konfiguration ======
+
+Dieses Plugin hilft Ihnen bei der Konfiguration von DokuWiki. Hilfe zu den einzelnen Einstellungen finden Sie unter [[doku>config]]. Mehr Information zu diesem Plugin ist unter [[doku>plugin:config]] erhältlich.
+
+Einstellungen mit einem hellroten Hintergrund sind gesichert und können nicht mit diesem Plugin verändert werden, Einstellungen mit hellblauem Hintergrund sind Voreinstellungen, weiß hinterlegte Felder zeigen lokal veränderte Werte an. Sowohl die blauen als auch die weißen Felder können verändert werden.
+
+Bitte vergessen Sie nicht **Speichern** zu drücken bevor Sie die Seite verlassen, andernfalls gehen Ihre Änderungen verloren.
+
+
+
diff --git a/lib/plugins/config/lang/de/lang.php b/lib/plugins/config/lang/de/lang.php
new file mode 100644
index 000000000..a9a275349
--- /dev/null
+++ b/lib/plugins/config/lang/de/lang.php
@@ -0,0 +1,202 @@
+<?php
+/**
+ * German language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Dirk Einecke <dirk@dirkeinecke.de>
+ * @author Blitzi94@gmx.de
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Niels Lange <niels@boldencursief.nl>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Paul Lachewsky <kaeptn.haddock@gmail.com>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Konfiguration';
+$lang['error'] = 'Die Einstellungen wurden wegen einer fehlerhaften Eingabe nicht gespeichert.
+<br />Bitte überprüfen sie die rot umrandeten Eingaben und speichern Sie erneut.';
+$lang['updated'] = 'Einstellungen erfolgreich gespeichert.';
+$lang['nochoice'] = '(keine Auswahlmöglichkeiten vorhanden)';
+$lang['locked'] = 'Die Konfigurationsdatei kann nicht geändert werden, wenn dies unbeabsichtigt ist
+ <br />überprüfen Sie, dass die Dateiberechtigungen korrekt gesetzt sind.';
+$lang['danger'] = 'Vorsicht: Die Änderung dieser Option könnte Ihr Wiki und das Konfigurationsmenü unzugänglich machen.';
+$lang['warning'] = 'Hinweis: Die Änderung dieser Option könnte unbeabsichtigtes Verhalten hervorrufen.';
+$lang['security'] = 'Sicherheitswarnung: Die Änderung dieser Option könnte ein Sicherheitsrisiko darstellen.';
+$lang['_configuration_manager'] = 'Konfiguration';
+$lang['_header_dokuwiki'] = 'DokuWiki-Konfiguration';
+$lang['_header_plugin'] = 'Plugin-Konfiguration';
+$lang['_header_template'] = 'Template-Konfiguration';
+$lang['_header_undefined'] = 'Unbekannte Einstellungen';
+$lang['_basic'] = 'Grund-Konfiguration';
+$lang['_display'] = 'Anzeige-Konfiguration';
+$lang['_authentication'] = 'Authentifizierungs-Konfiguration';
+$lang['_anti_spam'] = 'Anti-Spam-Konfiguration';
+$lang['_editing'] = 'Bearbeitungs-Konfiguration';
+$lang['_links'] = 'Link-Konfiguration';
+$lang['_media'] = 'Medien-Konfiguration';
+$lang['_advanced'] = 'Erweiterte Konfiguration';
+$lang['_network'] = 'Netzwerk-Konfiguration';
+$lang['_plugin_sufix'] = 'Plugin-Konfiguration';
+$lang['_template_sufix'] = 'Template-Konfiguration';
+$lang['_msg_setting_undefined'] = 'Keine Konfigurationsmetadaten.';
+$lang['_msg_setting_no_class'] = 'Keine Konfigurationsklasse.';
+$lang['_msg_setting_no_default'] = 'Kein Standardwert.';
+$lang['fmode'] = 'Rechte für neue Dateien';
+$lang['dmode'] = 'Rechte für neue Verzeichnisse';
+$lang['lang'] = 'Sprache';
+$lang['basedir'] = 'Installationsverzeichnis';
+$lang['baseurl'] = 'Installationspfad (URL)';
+$lang['savedir'] = 'Speicherverzeichnis';
+$lang['cookiedir'] = 'Cookiepfad. Frei lassen, um den gleichen Pfad wie "baseurl" zu benutzen.';
+$lang['start'] = 'Startseitenname';
+$lang['title'] = 'Titel des Wikis';
+$lang['template'] = 'Designvorlage (Template)';
+$lang['license'] = 'Unter welcher Lizenz sollen Ihre Inhalte veröffentlicht werden?';
+$lang['fullpath'] = 'Den kompletten Dateipfad im Footer anzeigen';
+$lang['recent'] = 'Anzahl der Einträge in der Änderungsliste';
+$lang['breadcrumbs'] = 'Anzahl der Einträge im "Krümelpfad"';
+$lang['youarehere'] = 'Hierarchische Pfadnavigation verwenden';
+$lang['typography'] = 'Typographische Ersetzungen';
+$lang['htmlok'] = 'HTML erlauben';
+$lang['phpok'] = 'PHP erlauben';
+$lang['dformat'] = 'Datumsformat (Siehe PHP <a href="http://www.php.net/strftime">strftime</a> Funktion)';
+$lang['signature'] = 'Signatur';
+$lang['toptoclevel'] = 'Inhaltsverzeichnis bei dieser Überschriftengröße beginnen';
+$lang['tocminheads'] = 'Mindestanzahl der Überschriften die entscheidet, ob ein Inhaltsverzeichnis erscheinen soll';
+$lang['maxtoclevel'] = 'Maximale Überschriftsgröße für Inhaltsverzeichnis';
+$lang['maxseclevel'] = 'Abschnitte bis zu dieser Stufe einzeln editierbar machen';
+$lang['camelcase'] = 'CamelCase-Verlinkungen verwenden';
+$lang['deaccent'] = 'Seitennamen bereinigen';
+$lang['useheading'] = 'Erste Überschrift als Seitennamen verwenden';
+$lang['refcheck'] = 'Auf Verwendung beim Löschen von Media-Dateien testen';
+$lang['refshow'] = 'Wiev iele Verwendungsorte der Media-Datei zeigen';
+$lang['allowdebug'] = 'Debug-Ausgaben erlauben <b>Abschalten wenn nicht benötigt!</b>';
+$lang['mediarevisions'] = 'Media-Revisionen (ältere Versionen) aktivieren?';
+$lang['usewordblock'] = 'Spam-Blocking benutzen';
+$lang['indexdelay'] = 'Zeit bevor Suchmaschinenindexierung erlaubt ist';
+$lang['relnofollow'] = 'rel="nofollow" verwenden';
+$lang['mailguard'] = 'E-Mail-Adressen schützen';
+$lang['iexssprotect'] = 'Hochgeladene Dateien auf bösartigen JavaScript- und HTML-Code untersuchen';
+$lang['showuseras'] = 'Was angezeigt werden soll, wenn der Benutzer, der zuletzt eine Seite bearbeitet hat, angezeigt wird';
+$lang['useacl'] = 'Zugangskontrolle verwenden';
+$lang['autopasswd'] = 'Passwort automatisch generieren';
+$lang['authtype'] = 'Authentifizierungsmechanismus';
+$lang['passcrypt'] = 'Verschlüsselungsmechanismus';
+$lang['defaultgroup'] = 'Standardgruppe';
+$lang['superuser'] = 'Administrator - Eine Gruppe oder Nutzer mit vollem Zugriff auf alle Seiten und Administrationswerkzeuge.';
+$lang['manager'] = 'Manager - Eine Gruppe oder Nutzer mit Zugriff auf einige Administrationswerkzeuge.';
+$lang['profileconfirm'] = 'Profiländerung nur nach Passwortbestätigung';
+$lang['disableactions'] = 'DokuWiki-Aktionen deaktivieren';
+$lang['disableactions_check'] = 'Check';
+$lang['disableactions_subscription'] = 'Seiten-Abonnements';
+$lang['disableactions_wikicode'] = 'Quelltext betrachten/exportieren';
+$lang['disableactions_other'] = 'Andere Aktionen (durch Komma getrennt)';
+$lang['sneaky_index'] = 'Standardmäßig zeigt DokuWiki alle Namensräume in der Übersicht. Wenn diese Option aktiviert wird, werden alle Namensräume, für die der Benutzer keine Lese-Rechte hat, nicht angezeigt. Dies kann unter Umständen dazu führen, das lesbare Unter-Namensräume nicht angezeigt werden und macht die Übersicht evtl. unbrauchbar in Kombination mit bestimmten ACL Einstellungen.';
+$lang['auth_security_timeout'] = 'Authentifikations-Timeout (Sekunden)';
+$lang['securecookie'] = 'Sollen Cookies, die via HTTPS gesetzt wurden nur per HTTPS versendet werden? Deaktivieren Sie diese Option, wenn nur der Login Ihres Wikis mit SSL gesichert ist, aber das Betrachten des Wikis ungesichert geschieht.';
+$lang['xmlrpc'] = 'XML-RPC-Zugriff erlauben.';
+$lang['xmlrpcuser'] = 'XML-RPC-Zugriff auf folgende Gruppen oder Benutzer (kommasepariert) beschränken. Wenn Sie dieses Feld leer lassen, wir der Zugriff jedem gewährt.';
+$lang['updatecheck'] = 'Automatisch auf Updates und Sicherheitswarnungen prüfen? DokuWiki muss sich dafür mit update.dokuwiki.org verbinden.';
+$lang['userewrite'] = 'URL rewriting';
+$lang['useslash'] = 'Schrägstrich (/) als Namensraumtrenner in URLs verwenden';
+$lang['usedraft'] = 'Während des Bearbeitens automatisch Zwischenentwürfe speichern';
+$lang['sepchar'] = 'Worttrenner für Seitennamen in URLs';
+$lang['canonical'] = 'Immer Links mit vollständigen URLs erzeugen';
+$lang['fnencode'] = 'Methode um nicht-ASCII Dateinamen zu kodieren.';
+$lang['autoplural'] = 'Bei Links automatisch nach vorhandenen Pluralformen suchen';
+$lang['compression'] = 'Komprimierungsmethode für alte Seitenrevisionen';
+$lang['cachetime'] = 'Maximale Cachespeicherung (Sekunden)';
+$lang['locktime'] = 'Maximales Alter für Seitensperren (Sekunden)';
+$lang['fetchsize'] = 'Maximale Größe (in Bytes), die fetch.php von extern herunterladen darf';
+$lang['notify'] = 'Änderungsmitteilungen an diese E-Mail-Adresse versenden';
+$lang['registernotify'] = 'Information über neu registrierte Nutzer an diese E-Mail-Adresse senden';
+$lang['mailfrom'] = 'Absender-E-Mail-Adresse für automatische Mails';
+$lang['mailprefix'] = 'Präfix für E-Mail-Betreff beim automatischen Versand von Benachrichtigungen';
+$lang['gzip_output'] = 'Seiten mit gzip komprimiert ausliefern';
+$lang['gdlib'] = 'GD Lib Version';
+$lang['im_convert'] = 'Pfad zu ImageMagicks-Konvertierwerkzeug';
+$lang['jpg_quality'] = 'JPEG Kompressionsqualität (0-100)';
+$lang['subscribers'] = 'E-Mail-Abos zulassen';
+$lang['subscribe_time'] = 'Zeit nach der Zusammenfassungs- und Änderungslisten-E-Mails verschickt werden; Dieser Wert sollte kleiner als die in recent_days konfigurierte Zeit sein.';
+$lang['compress'] = 'JavaScript und Stylesheets komprimieren';
+$lang['cssdatauri'] = 'Größe in Bytes, bis zu der Bilder in css-Dateien referenziert werden können, um HTTP-Anfragen zu minimieren. Diese Technik funktioniert nicht im IE 7 und älter! Empfohlene Einstellung: <code>400</code> to <code>600</code> Bytes. Setzen Sie die Einstellung auf <code>0</code> um die Funktion zu deaktivieren.';
+$lang['hidepages'] = 'Seiten verstecken (Regulärer Ausdruck)';
+$lang['send404'] = 'Bei nicht vorhandenen Seiten mit 404 Fehlercode antworten';
+$lang['sitemap'] = 'Google Sitemap erzeugen (Tage)';
+$lang['broken_iua'] = 'Falls die Funktion ignore_user_abort auf Ihrem System nicht funktioniert, könnte der Such-Index nicht funktionieren. IIS+PHP/CGI ist bekannt dafür. Siehe auch <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>.';
+$lang['xsendfile'] = 'Den X-Sendfile-Header nutzen, um Dateien direkt vom Webserver ausliefern zu lassen? Ihr Webserver muss dies unterstützen!';
+$lang['renderer_xhtml'] = 'Standard-Renderer für die normale (XHTML) Wiki-Ausgabe.';
+$lang['renderer__core'] = '%s (DokuWiki Kern)';
+$lang['renderer__plugin'] = '%s (Plugin)';
+$lang['rememberme'] = 'Permanente Login-Cookies erlauben (Auf diesem Computer eingeloggt bleiben)';
+$lang['rss_type'] = 'XML-Feed-Format';
+$lang['rss_linkto'] = 'XML-Feed verlinken auf';
+$lang['rss_content'] = 'Welche Inhalte sollen im XML-Feed dargestellt werden?';
+$lang['rss_update'] = 'XML-Feed Aktualisierungsintervall (Sekunden)';
+$lang['recent_days'] = 'Wieviele letzte Änderungen sollen einsehbar bleiben? (Tage)';
+$lang['rss_show_summary'] = 'Bearbeitungs-Zusammenfassung im XML-Feed anzeigen';
+$lang['target____wiki'] = 'Zielfenster für interne Links (target Attribut)';
+$lang['target____interwiki'] = 'Zielfenster für InterWiki-Links (target Attribut)';
+$lang['target____extern'] = 'Zielfenster für Externe Links (target Attribut)';
+$lang['target____media'] = 'Zielfenster für (Bild-)Dateien (target Attribut)';
+$lang['target____windows'] = 'Zielfenster für Windows Freigaben (target Attribut)';
+$lang['proxy____host'] = 'Proxy-Server';
+$lang['proxy____port'] = 'Proxy-Port';
+$lang['proxy____user'] = 'Proxy Nutzername';
+$lang['proxy____pass'] = 'Proxy Passwort';
+$lang['proxy____ssl'] = 'SSL bei Verbindung zum Proxy verwenden';
+$lang['proxy____except'] = 'Regulärer Ausdruck um Adressen zu beschreiben, für die kein Proxy verwendet werden soll';
+$lang['safemodehack'] = 'Safemodehack verwenden';
+$lang['ftp____host'] = 'FTP-Host für Safemodehack';
+$lang['ftp____port'] = 'FTP-Port für Safemodehack';
+$lang['ftp____user'] = 'FTP Nutzername für Safemodehack';
+$lang['ftp____pass'] = 'FTP Passwort für Safemodehack';
+$lang['ftp____root'] = 'FTP Wurzelverzeichnis für Safemodehack';
+$lang['license_o_'] = 'Keine gewählt';
+$lang['typography_o_0'] = 'keine';
+$lang['typography_o_1'] = 'ohne einfache Anführungszeichen';
+$lang['typography_o_2'] = 'mit einfachen Anführungszeichen (funktioniert nicht immer)';
+$lang['userewrite_o_0'] = 'keines';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki';
+$lang['deaccent_o_0'] = 'aus';
+$lang['deaccent_o_1'] = 'Akzente und Umlaute umwandeln';
+$lang['deaccent_o_2'] = 'Umschrift';
+$lang['gdlib_o_0'] = 'GD Lib nicht verfügbar';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Automatisch finden';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Abstrakt';
+$lang['rss_content_o_diff'] = 'Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML formatierte Diff-Tabelle';
+$lang['rss_content_o_html'] = 'Vollständiger HTML-Inhalt';
+$lang['rss_linkto_o_diff'] = 'Änderungen zeigen';
+$lang['rss_linkto_o_page'] = 'geänderte Seite';
+$lang['rss_linkto_o_rev'] = 'Liste aller Änderungen';
+$lang['rss_linkto_o_current'] = 'Aktuelle Seite';
+$lang['compression_o_0'] = 'keine';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nicht benutzen';
+$lang['xsendfile_o_1'] = 'Proprietärer lighttpd-Header (vor Release 1.5)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile-Header';
+$lang['xsendfile_o_3'] = 'Proprietärer Nginx X-Accel-Redirect-Header';
+$lang['showuseras_o_loginname'] = 'Loginname';
+$lang['showuseras_o_username'] = 'Vollständiger Name des Benutzers';
+$lang['showuseras_o_email'] = 'E-Mail-Adresse des Benutzers (je nach Mailguard-Einstellung verschleiert)';
+$lang['showuseras_o_email_link'] = 'E-Mail-Adresse des Benutzers als mailto:-Link';
+$lang['useheading_o_0'] = 'Nie';
+$lang['useheading_o_navigation'] = 'Nur Navigation';
+$lang['useheading_o_content'] = 'Nur Wikiinhalt';
+$lang['useheading_o_1'] = 'Immer';
+$lang['readdircache'] = 'Maximales Alter des readdir-Caches (Sekunden)';
diff --git a/lib/plugins/config/lang/el/intro.txt b/lib/plugins/config/lang/el/intro.txt
new file mode 100644
index 000000000..f10636720
--- /dev/null
+++ b/lib/plugins/config/lang/el/intro.txt
@@ -0,0 +1,7 @@
+====== Ρυθμίσεις ======
+
+Χρησιμοποιήστε αυτή την σελίδα για να ρυθμίσετε την λειτουργία του Dokuwiki σας. Για βοήθεια σχετικά με τις ρυθμίσεις δείτε την σελίδα [[doku>config]]. Για περισσότερες λεπτομέρειες σχετικά με αυτή την επέκταση δείτε την σελίδα [[doku>plugin:config]].
+
+Οι ρυθμίσεις που εμφανίζονται σε απαλό κόκκινο φόντο είναι κλειδωμένες και δεν μπορούν να τροποποιηθούν μέσω αυτής της επέκτασης. Οι ρυθμίσεις που εμφανίζονται σε μπλε φόντο είναι οι προεπιλεγμένες ενώ οι ρυθμίσεις που εμφανίζονται σε λευκό φόντο είναι αυτές που διαφέρουν από τις προεπιλεγμένες. Και οι ρυθμίσεις που εμφανίζονται σε μπλε φόντο και οι ρυθμίσεις που εμφανίζονται σε λευκό φόντο μπορούν να τροποποιηθούν.
+
+Θυμηθείτε να επιλέξετε **Αποθήκευση** αφού κάνετε τις αλλαγές που θέλετε.
diff --git a/lib/plugins/config/lang/el/lang.php b/lib/plugins/config/lang/el/lang.php
new file mode 100644
index 000000000..9f5d121de
--- /dev/null
+++ b/lib/plugins/config/lang/el/lang.php
@@ -0,0 +1,195 @@
+<?php
+/**
+ * Greek language file
+ *
+ * Based on DokuWiki Version rc2007-05-24 english language file
+ * Original english language file contents included for reference
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Thanos Massias <tm@thriasio.gr>
+ * @author Αθανάσιος Νταής <homunculus@wana.gr>
+ * @author Konstantinos Koryllos <koryllos@gmail.com>
+ * @author George Petsagourakis <petsagouris@gmail.com>
+ * @author Petros Vidalis <pvidalis@gmail.com>
+ */
+$lang['menu'] = 'Ρυθμίσεις';
+$lang['error'] = 'Οι ρυθμίσεις σας δεν έγιναν δεκτές λόγω λανθασμένης τιμής κάποιας ρύθμισης. Διορθώστε την λάθος τιμή και προσπαθήστε ξανά.
+ <br />Η λανθασμένη τιμή υποδεικνύεται με κόκκινο πλαίσιο.';
+$lang['updated'] = 'Επιτυχής τροποποίηση ρυθμίσεων.';
+$lang['nochoice'] = '(δεν υπάρχουν άλλες διαθέσιμες επιλογές)';
+$lang['locked'] = 'Το αρχείο ρυθμίσεων δεν μπορεί να τροποποιηθεί. <br />Εάν αυτό δεν είναι επιθυμητό, διορθώστε τα δικαιώματα πρόσβασης του αρχείου ρυθμίσεων';
+$lang['danger'] = 'Κίνδυνος: Η αλλαγή αυτής της επιλογής θα μπορούσε να αποτρέψει την πρόσβαση στο wiki και στις ρυθμίσεις του.';
+$lang['warning'] = 'Προσοχή: Η αλλαγή αυτής της επιλογής θα μπορούσε να προκαλέσει ανεπιθύμητη συμπεριφορά.';
+$lang['security'] = 'Προσοχή: Η αλλαγή αυτής της επιλογής θα μπορούσε να προκαλέσει προβλήματα ασφαλείας.';
+$lang['_configuration_manager'] = 'Ρυθμίσεις';
+$lang['_header_dokuwiki'] = 'Ρυθμίσεις DokuWiki';
+$lang['_header_plugin'] = 'Ρυθμίσεις Επεκτάσεων';
+$lang['_header_template'] = 'Ρυθμίσεις Προτύπων παρουσίασης';
+$lang['_header_undefined'] = 'Διάφορες Ρυθμίσεις';
+$lang['_basic'] = 'Βασικές Ρυθμίσεις';
+$lang['_display'] = 'Ρυθμίσεις Εμφάνισης';
+$lang['_authentication'] = 'Ρυθμίσεις Ασφαλείας';
+$lang['_anti_spam'] = 'Ρυθμίσεις Anti-Spam';
+$lang['_editing'] = 'Ρυθμίσεις Σύνταξης σελίδων';
+$lang['_links'] = 'Ρυθμίσεις Συνδέσμων';
+$lang['_media'] = 'Ρυθμίσεις Αρχείων';
+$lang['_advanced'] = 'Ρυθμίσεις για Προχωρημένους';
+$lang['_network'] = 'Ρυθμίσεις Δικτύου';
+$lang['_plugin_sufix'] = 'Ρυθμίσεις Επεκτάσεων';
+$lang['_template_sufix'] = 'Ρυθμίσεις Προτύπων παρουσίασης';
+$lang['_msg_setting_undefined'] = 'Δεν έχουν οριστεί metadata.';
+$lang['_msg_setting_no_class'] = 'Δεν έχει οριστεί κλάση.';
+$lang['_msg_setting_no_default'] = 'Δεν υπάρχει τιμή εξ ορισμού.';
+$lang['fmode'] = 'Δικαιώματα πρόσβασης δημιουργούμενων αρχείων';
+$lang['dmode'] = 'Δικαιώματα πρόσβασης δημιουργούμενων φακέλων';
+$lang['lang'] = 'Γλώσσα';
+$lang['basedir'] = 'Αρχικός Φάκελος';
+$lang['baseurl'] = 'Αρχικό URL';
+$lang['savedir'] = 'Φάκελος για την αποθήκευση δεδομένων';
+$lang['cookiedir'] = 'Διαδρομή cookie. Αφήστε την κενή για την χρησιμοποίηση της αρχικής URL.';
+$lang['start'] = 'Ονομασία αρχικής σελίδας';
+$lang['title'] = 'Τίτλος Wiki';
+$lang['template'] = 'Πρότυπο προβολής';
+$lang['license'] = 'Κάτω από ποια άδεια θέλετε να δημοσιευτεί το υλικό σας?';
+$lang['fullpath'] = 'Εμφάνιση πλήρους διαδρομής σελίδας στην υποκεφαλίδα';
+$lang['recent'] = 'Αριθμός πρόσφατων αλλαγών ανά σελίδα';
+$lang['breadcrumbs'] = 'Αριθμός συνδέσμων ιστορικού';
+$lang['youarehere'] = 'Εμφάνιση ιεραρχικής προβολής τρέχουσας σελίδας';
+$lang['typography'] = 'Μετατροπή ειδικών χαρακτήρων στο τυπογραφικό ισοδύναμό τους';
+$lang['htmlok'] = 'Να επιτρέπεται η ενσωμάτωση HTML';
+$lang['phpok'] = 'Να επιτρέπεται η ενσωμάτωση PHP';
+$lang['dformat'] = 'Μορφή ημερομηνίας (βλέπε την <a href="http://www.php.net/strftime">strftime</a> function της PHP)';
+$lang['signature'] = 'Υπογραφή';
+$lang['toptoclevel'] = 'Ανώτατο επίπεδο πίνακα περιεχομένων σελίδας';
+$lang['tocminheads'] = 'Ελάχιστος αριθμός κεφαλίδων για την δημιουργία πίνακα περιεχομένων - TOC';
+$lang['maxtoclevel'] = 'Μέγιστο επίπεδο για πίνακα περιεχομένων σελίδας';
+$lang['maxseclevel'] = 'Μέγιστο επίπεδο για εμφάνιση της επιλογής τροποποίησης επιπέδου';
+$lang['camelcase'] = 'Χρήση CamelCase στους συνδέσμους';
+$lang['deaccent'] = 'Αφαίρεση σημείων στίξης από ονόματα σελίδων';
+$lang['useheading'] = 'Χρήση κεφαλίδας πρώτου επιπέδου σαν τίτλο συνδέσμων';
+$lang['refcheck'] = 'Πριν τη διαγραφή ενός αρχείου να ελέγχεται η ύπαρξη σελίδων που το χρησιμοποιούν';
+$lang['refshow'] = 'Εμφανιζόμενος αριθμός σελίδων που χρησιμοποιούν ένα αρχείο';
+$lang['allowdebug'] = 'Δεδομένα εκσφαλμάτωσης (debug) <b>απενεργοποιήστε τα εάν δεν τα έχετε ανάγκη!</b>';
+$lang['usewordblock'] = 'Χρήστη λίστα απαγορευμένων λέξεων για καταπολέμηση του spam';
+$lang['indexdelay'] = 'Χρόνος αναμονής προτού επιτραπεί σε μηχανές αναζήτησης να ευρετηριάσουν μια τροποποιημένη σελίδα (sec)';
+$lang['relnofollow'] = 'Χρήση rel="nofollow"';
+$lang['mailguard'] = 'Κωδικοποίηση e-mail διευθύνσεων';
+$lang['iexssprotect'] = 'Έλεγχος μεταφορτώσεων για πιθανώς επικίνδυνο κώδικα JavaScript ή HTML';
+$lang['showuseras'] = 'Τι να εμφανίζεται όταν φαίνεται ο χρήστης που τροποποίησε τελευταίος μία σελίδα';
+$lang['useacl'] = 'Χρήση Λίστας Δικαιωμάτων Πρόσβασης (ACL)';
+$lang['autopasswd'] = 'Αυτόματη δημιουργία κωδικού χρήστη';
+$lang['authtype'] = 'Τύπος πιστοποίησης στοιχείων χρήστη';
+$lang['passcrypt'] = 'Μέθοδος κρυπτογράφησης κωδικού χρήστη';
+$lang['defaultgroup'] = 'Προεπιλεγμένη ομάδα χρηστών';
+$lang['superuser'] = 'Υπερ-χρήστης - μία ομάδα ή ένας χρήστης με πλήρη δικαιώματα πρόσβασης σε όλες τις σελίδες και όλες τις λειτουργίες ανεξάρτητα από τις ρυθμίσεις των Λιστών Δικαιωμάτων Πρόσβασης (ACL)';
+$lang['manager'] = 'Διαχειριστής - μία ομάδα ή ένας χρήστης με δικαιώματα πρόσβασης σε ορισμένες από τις λειτουργίες της εφαρμογής';
+$lang['profileconfirm'] = 'Να απαιτείται ο κωδικός χρήστη για την επιβεβαίωση αλλαγών στο προφίλ χρήστη';
+$lang['disableactions'] = 'Απενεργοποίηση λειτουργιών DokuWiki';
+$lang['disableactions_check'] = 'Έλεγχος';
+$lang['disableactions_subscription'] = 'Εγγραφή/Διαγραφή χρήστη';
+$lang['disableactions_wikicode'] = 'Προβολή κώδικα σελίδας';
+$lang['disableactions_other'] = 'Άλλες λειτουργίες (διαχωρίστε τις με κόμμα)';
+$lang['sneaky_index'] = 'Εξ ορισμού, η εφαρμογή DokuWiki δείχνει όλους τους φακέλους στην προβολή Καταλόγου. Ενεργοποιώντας αυτή την επιλογή, δεν θα εμφανίζονται οι φάκελοι για τους οποίους ο χρήστης δεν έχει δικαιώματα ανάγνωσης αλλά και οι υπο-φάκελοί τους ανεξαρτήτως δικαιωμάτων πρόσβασης.';
+$lang['auth_security_timeout'] = 'Διάρκεια χρόνου για ασφάλεια πιστοποίησης (δευτερόλεπτα)';
+$lang['securecookie'] = 'Τα cookies που έχουν οριστεί μέσω HTTPS πρέπει επίσης να αποστέλλονται μόνο μέσω HTTPS από τον φυλλομετρητή? Απενεργοποιήστε αυτή την επιλογή όταν μόνο η είσοδος στο wiki σας διασφαλίζεται μέσω SSL αλλά η περιήγηση γίνεται και χωρίς αυτό.';
+$lang['xmlrpc'] = 'Ενεργοποίηση/Απενεργοποίηση της διασύνδεσης XML-RPC ';
+$lang['xmlrpcuser'] = 'Περιορισμός XML-RPC πρόσβασης στις ομάδες η τους χρήστες (διαχωριζόμενοι με κόμμα). Αφήστε το κενό για πρόσβαση από όλους.';
+$lang['updatecheck'] = 'Έλεγχος για ύπαρξη νέων εκδόσεων και ενημερώσεων ασφαλείας της εφαρμογής? Απαιτείται η σύνδεση με το update.dokuwiki.org για να λειτουργήσει σωστά αυτή η επιλογή.';
+$lang['userewrite'] = 'Χρήση ωραίων URLs';
+$lang['useslash'] = 'Χρήση slash σαν διαχωριστικό φακέλων στα URLs';
+$lang['usedraft'] = 'Αυτόματη αποθήκευση αντιγράφων κατά την τροποποίηση σελίδων';
+$lang['sepchar'] = 'Διαχωριστικός χαρακτήρας για κανονικοποίηση ονόματος σελίδας';
+$lang['canonical'] = 'Πλήρη και κανονικοποιημένα URLs';
+$lang['fnencode'] = 'Μέθοδος κωδικοποίησης για ονόματα αρχείων μη-ASCII';
+$lang['autoplural'] = 'Ταίριασμα πληθυντικού στους συνδέσμους';
+$lang['compression'] = 'Μέθοδος συμπίεσης για αρχεία attic';
+$lang['cachetime'] = 'Μέγιστη ηλικία cache (sec)';
+$lang['locktime'] = 'Μέγιστος χρόνος κλειδώματος αρχείου υπό τροποποίηση (sec)';
+$lang['fetchsize'] = 'Μέγιστο μέγεθος (σε bytes) εξωτερικού αρχείου που επιτρέπεται να μεταφέρει η fetch.php';
+$lang['notify'] = 'Αποστολή ενημέρωσης για αλλαγές σε αυτή την e-mail διεύθυνση';
+$lang['registernotify'] = 'Αποστολή ενημερωτικών μηνυμάτων σε αυτή την e-mail διεύθυνση κατά την εγγραφή νέων χρηστών';
+$lang['mailfrom'] = 'e-mail διεύθυνση αποστολέα για μηνύματα από την εφαρμογή';
+$lang['mailprefix'] = 'Πρόθεμα θέματος που να χρησιμοποιείται για τα αυτόματα μηνύματα ηλεκτρονικού ταχυδρομείου.';
+$lang['gzip_output'] = 'Χρήση gzip Content-Encoding για την xhtml';
+$lang['gdlib'] = 'Έκδοση βιβλιοθήκης GD';
+$lang['im_convert'] = 'Διαδρομή προς το εργαλείο μετατροπής εικόνων του ImageMagick';
+$lang['jpg_quality'] = 'Ποιότητα συμπίεσης JPG (0-100)';
+$lang['subscribers'] = 'Να επιτρέπεται η εγγραφή στην ενημέρωση αλλαγών σελίδας';
+$lang['subscribe_time'] = 'Χρόνος μετά τον οποίο οι λίστες ειδοποιήσεων και τα συνοπτικά θα αποστέλλονται (δευτερόλεπτα). Αυτό θα πρέπει να είναι μικρότερο από τον χρόνο που έχει η ρύθμιση recent_days.';
+$lang['compress'] = 'Συμπίεση αρχείων CSS και javascript';
+$lang['cssdatauri'] = 'Το μέγεθος σε bytes στο οποίο οι εικόνες που αναφέρονται σε CSS αρχεία θα πρέπει να είναι ενσωματωμένες για τη μείωση των απαιτήσεων μιας κεφαλίδας αίτησης HTTP . Αυτή η τεχνική δεν θα λειτουργήσει σε IE <8! <code> 400 </ code> με <code> 600 </ code> bytes είναι μια καλή τιμή. Ορίστε την τιμή <code> 0 </ code> για να το απενεργοποιήσετε.';
+$lang['hidepages'] = 'Φίλτρο απόκρυψης σελίδων (regular expressions)';
+$lang['send404'] = 'Αποστολή "HTTP 404/Page Not Found" για σελίδες που δεν υπάρχουν';
+$lang['sitemap'] = 'Δημιουργία Google sitemap (ημέρες)';
+$lang['broken_iua'] = 'Η συνάρτηση ignore_user_abort δεν λειτουργεί σωστά στο σύστημά σας? Σε αυτή την περίπτωση μπορεί να μην δουλεύει σωστά η λειτουργία Καταλόγου. Ο συνδυασμός IIS+PHP/CGI είναι γνωστό ότι έχει τέτοιο πρόβλημα. Δείτε και <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> για λεπτομέρειες.';
+$lang['xsendfile'] = 'Χρήση της κεφαλίδας X-Sendfile από τον εξυπηρετητή κατά την φόρτωση στατικών αρχείων? Ο εξυπηρετητής σας πρέπει να υποστηρίζει αυτή την δυνατότητα.';
+$lang['renderer_xhtml'] = 'Πρόγραμμα δημιουργίας βασικής (xhtml) εξόδου wiki.';
+$lang['renderer__core'] = '%s (βασικός κώδικας dokuwiki)';
+$lang['renderer__plugin'] = '%s (επέκταση)';
+$lang['rememberme'] = 'Να επιτρέπονται τα cookies λογαρισμού χρήστη αορίστου χρόνου (Απομνημόνευση στοιχείων λογαριασμού)';
+$lang['rss_type'] = 'Τύπος XML feed';
+$lang['rss_linkto'] = 'Τύπος συνδέσμων στο XML feed';
+$lang['rss_content'] = 'Τι να εμφανίζεται στα XML feed items?';
+$lang['rss_update'] = 'Χρόνος ανανέωσης XML feed (sec)';
+$lang['recent_days'] = 'Πόσο παλιές αλλαγές να εμφανίζονται (ημέρες)';
+$lang['rss_show_summary'] = 'Να εμφανίζεται σύνοψη του XML feed στον τίτλο';
+$lang['target____wiki'] = 'Παράθυρο-στόχος για εσωτερικούς συνδέσμους';
+$lang['target____interwiki'] = 'Παράθυρο-στόχος για συνδέσμους interwiki';
+$lang['target____extern'] = 'Παράθυρο-στόχος για εξωτερικούς σθνδέσμους';
+$lang['target____media'] = 'Παράθυρο-στόχος για συνδέσμους αρχείων';
+$lang['target____windows'] = 'Παράθυρο-στόχος για συνδέσμους σε Windows shares';
+$lang['proxy____host'] = 'Διακομιστής Proxy';
+$lang['proxy____port'] = 'Θύρα Proxy';
+$lang['proxy____user'] = 'Όνομα χρήστη Proxy';
+$lang['proxy____pass'] = 'Κωδικός χρήστη Proxy';
+$lang['proxy____ssl'] = 'Χρήση ssl για σύνδεση με διακομιστή Proxy';
+$lang['proxy____except'] = 'Regular expression για να πιάνει τα URLs για τα οποία θα παρακάμπτεται το proxy.';
+$lang['safemodehack'] = 'Ενεργοποίηση safemode hack';
+$lang['ftp____host'] = 'Διακομιστής FTP για safemode hack';
+$lang['ftp____port'] = 'Θύρα FTP για safemode hack';
+$lang['ftp____user'] = 'Όνομα χρήστη FTP για safemode hack';
+$lang['ftp____pass'] = 'Κωδικός χρήστη FTP για safemode hack';
+$lang['ftp____root'] = 'Αρχικός φάκελος FTP για safemode hack';
+$lang['license_o_'] = 'Δεν επελέγει άδεια';
+$lang['typography_o_0'] = 'κανένα';
+$lang['typography_o_1'] = 'μόνο διπλά εισαγωγικά';
+$lang['typography_o_2'] = 'όλα τα εισαγωγικά (μπορεί να μην λειτουργεί πάντα)';
+$lang['userewrite_o_0'] = 'κανένα';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'από DokuWiki';
+$lang['deaccent_o_0'] = 'όχι';
+$lang['deaccent_o_1'] = 'αφαίρεση σημείων στίξης';
+$lang['deaccent_o_2'] = 'λατινοποίηση';
+$lang['gdlib_o_0'] = 'Δεν υπάρχει βιβλιοθήκη GD στο σύστημα';
+$lang['gdlib_o_1'] = 'Έκδοση 1.x';
+$lang['gdlib_o_2'] = 'Αυτόματος εντοπισμός';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Περίληψη';
+$lang['rss_content_o_diff'] = 'Ενοποιημένο Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML διαμορφωμένος πίνακας diff';
+$lang['rss_content_o_html'] = 'Περιεχόμενο Σελίδας μόνο με HTML';
+$lang['rss_linkto_o_diff'] = 'προβολή αλλαγών';
+$lang['rss_linkto_o_page'] = 'τροποποιημένη σελίδα';
+$lang['rss_linkto_o_rev'] = 'εκδόσεις σελίδας';
+$lang['rss_linkto_o_current'] = 'τρέχουσα σελίδα';
+$lang['compression_o_0'] = 'none';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'να μην χρησιμοποιείται';
+$lang['xsendfile_o_1'] = 'Ιδιοταγής κεφαλίδα lighttpd (πριν από την έκδοση 1.5)';
+$lang['xsendfile_o_2'] = 'Τυπική κεφαλίδα X-Sendfile';
+$lang['xsendfile_o_3'] = 'Ιδιοταγής κεφαλίδα Nginx X-Accel-Redirect ';
+$lang['showuseras_o_loginname'] = 'Όνομα χρήστη';
+$lang['showuseras_o_username'] = 'Ονοματεπώνυμο χρήστη';
+$lang['showuseras_o_email'] = 'e-mail διεύθυνση χρήστη (εμφανίζεται σύμφωνα με την ρύθμιση για την κωδικοποίηση e-mail διευθύνσεων)';
+$lang['showuseras_o_email_link'] = 'Εμφάνιση e-mail διεύθυνσης χρήστη σαν σύνδεσμος mailto:';
+$lang['useheading_o_0'] = 'Ποτέ';
+$lang['useheading_o_navigation'] = 'Μόνο κατά την πλοήγηση';
+$lang['useheading_o_content'] = 'Μόνο για τα περιεχόμενα του wiki';
+$lang['useheading_o_1'] = 'Πάντα';
+$lang['readdircache'] = 'Μέγιστος χρόνος διατήρησης για το cache του readdir (δευτερόλεπτα)';
diff --git a/lib/plugins/config/lang/en/intro.txt b/lib/plugins/config/lang/en/intro.txt
new file mode 100644
index 000000000..c83a80205
--- /dev/null
+++ b/lib/plugins/config/lang/en/intro.txt
@@ -0,0 +1,9 @@
+====== Configuration Manager ======
+
+Use this page to control the settings of your DokuWiki installation. For help on individual settings refer to [[doku>config]]. For more details about this plugin see [[doku>plugin:config]].
+
+Settings shown with a light red background are protected and can not be altered with this plugin. Settings shown with a blue background are the default values and settings shown with a white background have been set locally for this particular installation. Both blue and white settings can be altered.
+
+Remember to press the **SAVE** button before leaving this page otherwise your changes will be lost.
+
+
diff --git a/lib/plugins/config/lang/en/lang.php b/lib/plugins/config/lang/en/lang.php
new file mode 100644
index 000000000..74ec56345
--- /dev/null
+++ b/lib/plugins/config/lang/en/lang.php
@@ -0,0 +1,245 @@
+<?php
+/**
+ * english language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+
+// for admin plugins, the menu prompt to be displayed in the admin menu
+// if set here, the plugin doesn't need to override the getMenuText() method
+$lang['menu'] = 'Configuration Settings';
+
+$lang['error'] = 'Settings not updated due to an invalid value, please review your changes and resubmit.
+ <br />The incorrect value(s) will be shown surrounded by a red border.';
+$lang['updated'] = 'Settings updated successfully.';
+$lang['nochoice'] = '(no other choices available)';
+$lang['locked'] = 'The settings file can not be updated, if this is unintentional, <br />
+ ensure the local settings file name and permissions are correct.';
+
+$lang['danger'] = 'Danger: Changing this option could make your wiki and the configuration menu inaccessible.';
+$lang['warning'] = 'Warning: Changing this option could cause unintended behaviour.';
+$lang['security'] = 'Security Warning: Changing this option could present a security risk.';
+
+/* --- Config Setting Headers --- */
+$lang['_configuration_manager'] = 'Configuration Manager'; //same as heading in intro.txt
+$lang['_header_dokuwiki'] = 'DokuWiki Settings';
+$lang['_header_plugin'] = 'Plugin Settings';
+$lang['_header_template'] = 'Template Settings';
+$lang['_header_undefined'] = 'Undefined Settings';
+
+/* --- Config Setting Groups --- */
+$lang['_basic'] = 'Basic Settings';
+$lang['_display'] = 'Display Settings';
+$lang['_authentication'] = 'Authentication Settings';
+$lang['_anti_spam'] = 'Anti-Spam Settings';
+$lang['_editing'] = 'Editing Settings';
+$lang['_links'] = 'Link Settings';
+$lang['_media'] = 'Media Settings';
+$lang['_advanced'] = 'Advanced Settings';
+$lang['_network'] = 'Network Settings';
+// The settings group name for plugins and templates can be set with
+// plugin_settings_name and template_settings_name respectively. If one
+// of these lang properties is not set, the group name will be generated
+// from the plugin or template name and the localized suffix.
+$lang['_plugin_sufix'] = 'Plugin Settings';
+$lang['_template_sufix'] = 'Template Settings';
+
+/* --- Undefined Setting Messages --- */
+$lang['_msg_setting_undefined'] = 'No setting metadata.';
+$lang['_msg_setting_no_class'] = 'No setting class.';
+$lang['_msg_setting_no_default'] = 'No default value.';
+
+/* -------------------- Config Options --------------------------- */
+
+$lang['fmode'] = 'File creation mode';
+$lang['dmode'] = 'Directory creation mode';
+$lang['lang'] = 'Interface language';
+$lang['basedir'] = 'Server path (eg. <code>/dokuwiki/</code>). Leave blank for autodetection.';
+$lang['baseurl'] = 'Server URL (eg. <code>http://www.yourserver.com</code>). Leave blank for autodetection.';
+$lang['savedir'] = 'Directory for saving data';
+$lang['cookiedir'] = 'Cookie path. Leave blank for using baseurl.';
+$lang['start'] = 'Start page name';
+$lang['title'] = 'Wiki title';
+$lang['template'] = 'Template';
+$lang['tagline'] = 'Tagline (if template supports it)';
+$lang['sidebar'] = 'Sidebar page name (if template supports it), empty field disables the sidebar';
+$lang['license'] = 'Under which license should your content be released?';
+$lang['fullpath'] = 'Reveal full path of pages in the footer';
+$lang['recent'] = 'Recent changes';
+$lang['breadcrumbs'] = 'Number of breadcrumbs';
+$lang['youarehere'] = 'Hierarchical breadcrumbs';
+$lang['typography'] = 'Do typographical replacements';
+$lang['htmlok'] = 'Allow embedded HTML';
+$lang['phpok'] = 'Allow embedded PHP';
+$lang['dformat'] = 'Date format (see PHP\'s <a href="http://www.php.net/strftime">strftime</a> function)';
+$lang['signature'] = 'Signature';
+$lang['toptoclevel'] = 'Top level for table of contents';
+$lang['tocminheads'] = 'Minimum amount of headlines that determines whether the TOC is built';
+$lang['maxtoclevel'] = 'Maximum level for table of contents';
+$lang['maxseclevel'] = 'Maximum section edit level';
+$lang['camelcase'] = 'Use CamelCase for links';
+$lang['deaccent'] = 'Clean pagenames';
+$lang['useheading'] = 'Use first heading for pagenames';
+$lang['refcheck'] = 'Media reference check';
+$lang['refshow'] = 'Number of media references to show';
+$lang['allowdebug'] = 'Allow debug <b>disable if not needed!</b>';
+$lang['mediarevisions'] = 'Enable Mediarevisions?';
+
+$lang['usewordblock']= 'Block spam based on wordlist';
+$lang['indexdelay'] = 'Time delay before indexing (sec)';
+$lang['relnofollow'] = 'Use rel="nofollow" on external links';
+$lang['mailguard'] = 'Obfuscate email addresses';
+$lang['iexssprotect']= 'Check uploaded files for possibly malicious JavaScript or HTML code';
+$lang['showuseras'] = 'What to display when showing the user that last edited a page';
+
+/* Authentication Options */
+$lang['useacl'] = 'Use access control lists';
+$lang['autopasswd'] = 'Autogenerate passwords';
+$lang['authtype'] = 'Authentication backend';
+$lang['passcrypt'] = 'Password encryption method';
+$lang['defaultgroup']= 'Default group';
+$lang['superuser'] = 'Superuser - group, user or comma separated list user1,@group1,user2 with full access to all pages and functions regardless of the ACL settings';
+$lang['manager'] = 'Manager - group, user or comma separated list user1,@group1,user2 with access to certain management functions';
+$lang['profileconfirm'] = 'Confirm profile changes with password';
+$lang['disableactions'] = 'Disable DokuWiki actions';
+$lang['disableactions_check'] = 'Check';
+$lang['disableactions_subscription'] = 'Subscribe/Unsubscribe';
+$lang['disableactions_wikicode'] = 'View source/Export Raw';
+$lang['disableactions_other'] = 'Other actions (comma separated)';
+$lang['sneaky_index'] = 'By default, DokuWiki will show all namespaces in the index view. Enabling this option will hide those where the user doesn\'t have read permissions. This might result in hiding of accessable subnamespaces. This may make the index unusable with certain ACL setups.';
+$lang['auth_security_timeout'] = 'Authentication Security Timeout (seconds)';
+$lang['securecookie'] = 'Should cookies set via HTTPS only be sent via HTTPS by the browser? Disable this option when only the login of your wiki is secured with SSL but browsing the wiki is done unsecured.';
+$lang['xmlrpc'] = 'Enable/disable XML-RPC interface.';
+$lang['xmlrpcuser'] = 'Restrict XML-RPC access to the comma separated groups or users given here. Leave empty to give access to everyone.';
+
+/* Advanced Options */
+$lang['updatecheck'] = 'Check for updates and security warnings? DokuWiki needs to contact update.dokuwiki.org for this feature.';
+$lang['userewrite'] = 'Use nice URLs';
+$lang['useslash'] = 'Use slash as namespace separator in URLs';
+$lang['usedraft'] = 'Automatically save a draft while editing';
+$lang['sepchar'] = 'Page name word separator';
+$lang['canonical'] = 'Use fully canonical URLs';
+$lang['fnencode'] = 'Method for encoding non-ASCII filenames.';
+$lang['autoplural'] = 'Check for plural forms in links';
+$lang['compression'] = 'Compression method for attic files';
+$lang['cachetime'] = 'Maximum age for cache (sec)';
+$lang['locktime'] = 'Maximum age for lock files (sec)';
+$lang['fetchsize'] = 'Maximum size (bytes) fetch.php may download from extern';
+$lang['notify'] = 'Send change notifications to this email address';
+$lang['registernotify'] = 'Send info on newly registered users to this email address';
+$lang['mailfrom'] = 'Email address to use for automatic mails';
+$lang['mailprefix'] = 'Email subject prefix to use for automatic mails';
+$lang['gzip_output'] = 'Use gzip Content-Encoding for xhtml';
+$lang['gdlib'] = 'GD Lib version';
+$lang['im_convert'] = 'Path to ImageMagick\'s convert tool';
+$lang['jpg_quality'] = 'JPG compression quality (0-100)';
+$lang['subscribers'] = 'Enable page subscription support';
+$lang['subscribe_time'] = 'Time after which subscription lists and digests are sent (sec); This should be smaller than the time specified in recent_days.';
+$lang['compress'] = 'Compact CSS and javascript output';
+$lang['cssdatauri'] = 'Size in bytes up to which images referenced in CSS files should be embedded right into the stylesheet to reduce HTTP request header overhead. This technique won\'t work in IE 7 and below! <code>400</code> to <code>600</code> bytes is a good value. Set <code>0</code> to disable.';
+$lang['hidepages'] = 'Hide matching pages (regular expressions)';
+$lang['send404'] = 'Send "HTTP 404/Page Not Found" for non existing pages';
+$lang['sitemap'] = 'Generate Google sitemap (days)';
+$lang['broken_iua'] = 'Is the ignore_user_abort function broken on your system? This could cause a non working search index. IIS+PHP/CGI is known to be broken. See <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> for more info.';
+$lang['xsendfile'] = 'Use the X-Sendfile header to let the webserver deliver static files? Your webserver needs to support this.';
+$lang['renderer_xhtml'] = 'Renderer to use for main (xhtml) wiki output';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Allow permanent login cookies (remember me)';
+
+$lang['rss_type'] = 'XML feed type';
+$lang['rss_linkto'] = 'XML feed links to';
+$lang['rss_content'] = 'What to display in the XML feed items?';
+$lang['rss_update'] = 'XML feed update interval (sec)';
+$lang['recent_days'] = 'How many recent changes to keep (days)';
+$lang['rss_show_summary'] = 'XML feed show summary in title';
+
+/* Target options */
+$lang['target____wiki'] = 'Target window for internal links';
+$lang['target____interwiki'] = 'Target window for interwiki links';
+$lang['target____extern'] = 'Target window for external links';
+$lang['target____media'] = 'Target window for media links';
+$lang['target____windows'] = 'Target window for windows links';
+
+/* Proxy Options */
+$lang['proxy____host'] = 'Proxy servername';
+$lang['proxy____port'] = 'Proxy port';
+$lang['proxy____user'] = 'Proxy user name';
+$lang['proxy____pass'] = 'Proxy password';
+$lang['proxy____ssl'] = 'Use SSL to connect to proxy';
+$lang['proxy____except'] = 'Regular expression to match URLs for which the proxy should be skipped for.';
+
+/* Safemode Hack */
+$lang['safemodehack'] = 'Enable safemode hack';
+$lang['ftp____host'] = 'FTP server for safemode hack';
+$lang['ftp____port'] = 'FTP port for safemode hack';
+$lang['ftp____user'] = 'FTP user name for safemode hack';
+$lang['ftp____pass'] = 'FTP password for safemode hack';
+$lang['ftp____root'] = 'FTP root directory for safemode hack';
+
+$lang['license_o_'] = 'None chosen';
+
+/* typography options */
+$lang['typography_o_0'] = 'none';
+$lang['typography_o_1'] = 'excluding single quotes';
+$lang['typography_o_2'] = 'including single quotes (might not always work)';
+
+/* userewrite options */
+$lang['userewrite_o_0'] = 'none';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki internal';
+
+/* deaccent options */
+$lang['deaccent_o_0'] = 'off';
+$lang['deaccent_o_1'] = 'remove accents';
+$lang['deaccent_o_2'] = 'romanize';
+
+/* gdlib options */
+$lang['gdlib_o_0'] = 'GD Lib not available';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Autodetection';
+
+/* rss_type options */
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+
+/* rss_content options */
+$lang['rss_content_o_abstract'] = 'Abstract';
+$lang['rss_content_o_diff'] = 'Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML formatted diff table';
+$lang['rss_content_o_html'] = 'Full HTML page content';
+
+/* rss_linkto options */
+$lang['rss_linkto_o_diff'] = 'difference view';
+$lang['rss_linkto_o_page'] = 'the revised page';
+$lang['rss_linkto_o_rev'] = 'list of revisions';
+$lang['rss_linkto_o_current'] = 'the current page';
+
+/* compression options */
+$lang['compression_o_0'] = 'none';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+
+/* xsendfile header */
+$lang['xsendfile_o_0'] = "don't use";
+$lang['xsendfile_o_1'] = 'Proprietary lighttpd header (before release 1.5)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile header';
+$lang['xsendfile_o_3'] = 'Proprietary Nginx X-Accel-Redirect header';
+
+/* Display user info */
+$lang['showuseras_o_loginname'] = 'Login name';
+$lang['showuseras_o_username'] = "User's full name";
+$lang['showuseras_o_email'] = "User's e-mail addresss (obfuscated according to mailguard setting)";
+$lang['showuseras_o_email_link'] = "User's e-mail addresss as a mailto: link";
+
+/* useheading options */
+$lang['useheading_o_0'] = 'Never';
+$lang['useheading_o_navigation'] = 'Navigation Only';
+$lang['useheading_o_content'] = 'Wiki Content Only';
+$lang['useheading_o_1'] = 'Always';
+
+$lang['readdircache'] = 'Maximum age for readdir cache (sec)';
diff --git a/lib/plugins/config/lang/eo/intro.txt b/lib/plugins/config/lang/eo/intro.txt
new file mode 100644
index 000000000..c717d9a4d
--- /dev/null
+++ b/lib/plugins/config/lang/eo/intro.txt
@@ -0,0 +1,7 @@
+====== Administrilo de Agordoj ======
+
+Uzu tiun ĉi paĝon por kontroli la difinojn de via DokuWiki-instalo. Por helpo pri specifaj difinoj aliru al [[doku&gt;config]]. Por pli detaloj pri tiu ĉi kromaĵo, vidu [[doku&gt;plugin:config]].
+
+Difinoj montrataj kun hela ruĝa fono estas protektitaj kaj ne povas esti modifataj per tiu ĉi kromaĵo. Difinoj kun blua fono estas aprioraj valoroj kaj difinoj montrataj kun blanka fono estis iam difinataj por tiu ĉi specifa instalo. Ambaŭ blua kaj blanka difinoj povas esti modifataj.
+
+Memoru premi la butonon **Registri** antaŭ ol eliri tiun ĉi paĝon, male viaj modifoj perdiĝus.
diff --git a/lib/plugins/config/lang/eo/lang.php b/lib/plugins/config/lang/eo/lang.php
new file mode 100644
index 000000000..b0411ec14
--- /dev/null
+++ b/lib/plugins/config/lang/eo/lang.php
@@ -0,0 +1,196 @@
+<?php
+/**
+ * Esperantolanguage file
+ *
+ * @author Felipe Castro <fefcas@uol.com.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Felipe Castro <fefcas (cxe) gmail (punkto) com>
+ * @author Felipo Kastro <fefcas@gmail.com>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Erik Pedersen <erik pedersen@shaw.ca>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert BOGENSCHNEIDER <robog@gmx.de>
+ * @author Robert BOGENSCHNEIDER <bogi@UEA.org>
+ */
+$lang['menu'] = 'Agordaj Difinoj';
+$lang['error'] = 'La difinoj ne estas ĝisdatigitaj pro malvalida valoro: bonvolu revizii viajn ŝanĝojn kaj resubmeti ilin.
+&lt;br /&gt;La malkorekta(j) valoro(j) estas ĉirkaŭita(j) de ruĝa kadro.';
+$lang['updated'] = 'La difinoj estis sukcese ĝisdatigitaj.';
+$lang['nochoice'] = '(neniu alia elekto disponeblas)';
+$lang['locked'] = 'La difin-dosiero ne povas esti ĝisdatigita; se tio ne estas intenca, &lt;br /&gt; certiĝu, ke la dosieroj de lokaj difinoj havas korektajn nomojn kaj permesojn.';
+$lang['danger'] = 'Danĝero: ŝanĝo tiun opcion povus igi vian vikion kaj la agordan menuon neatingebla.';
+$lang['warning'] = 'Averto: ŝanĝi tiun opcion povus rezulti en neatendita konduto.';
+$lang['security'] = 'Sekureca averto: ŝanĝi tiun opcion povus krei sekurecan riskon.';
+$lang['_configuration_manager'] = 'Administrilo de agordoj';
+$lang['_header_dokuwiki'] = 'Difinoj por DokuWiki';
+$lang['_header_plugin'] = 'Difinoj por kromaĵoj';
+$lang['_header_template'] = 'Difinoj por ŝablonoj';
+$lang['_header_undefined'] = 'Ceteraj difinoj';
+$lang['_basic'] = 'Bazaj difinoj';
+$lang['_display'] = 'Difinoj por montrado';
+$lang['_authentication'] = 'Difinoj por identiĝo';
+$lang['_anti_spam'] = 'Kontraŭ-spamaj difinoj';
+$lang['_editing'] = 'Difinoj por redakto';
+$lang['_links'] = 'Difinoj por ligiloj';
+$lang['_media'] = 'Difinoj por aŭdvidaĵoj';
+$lang['_advanced'] = 'Fakaj difinoj';
+$lang['_network'] = 'Difinoj por reto';
+$lang['_plugin_sufix'] = 'Difinoj por kromaĵoj';
+$lang['_template_sufix'] = 'Difinoj por ŝablonoj';
+$lang['_msg_setting_undefined'] = 'Neniu difinanta metadatenaro.';
+$lang['_msg_setting_no_class'] = 'Neniu difinanta klaso.';
+$lang['_msg_setting_no_default'] = 'Neniu apriora valoro.';
+$lang['fmode'] = 'Reĝimo de dosiero-kreado';
+$lang['dmode'] = 'Reĝimo de dosierujo-kreado';
+$lang['lang'] = 'Lingvo';
+$lang['basedir'] = 'Baza dosierujo';
+$lang['baseurl'] = 'Baza URL';
+$lang['savedir'] = 'Dosierujo por konservi datenaron';
+$lang['cookiedir'] = 'Kuketopado. Lasu malplena por uzi baseurl.';
+$lang['start'] = 'Nomo de la hejmpaĝo';
+$lang['title'] = 'Titolo de la vikio';
+$lang['template'] = 'Ŝablono';
+$lang['license'] = 'Laŭ kiu permesilo via enhavo devus esti publikigita?';
+$lang['fullpath'] = 'Montri la kompletan padon de la paĝoj en la piedlinio';
+$lang['recent'] = 'Freŝaj ŝanĝoj';
+$lang['breadcrumbs'] = 'Nombro da paderoj';
+$lang['youarehere'] = 'Hierarkiaj paderoj';
+$lang['typography'] = 'Fari tipografiajn anstataŭigojn';
+$lang['htmlok'] = 'Ebligi enmeton de HTML-aĵoj';
+$lang['phpok'] = 'Ebligi enmeton de PHP-aĵoj';
+$lang['dformat'] = 'Formato de datoj (vidu la PHP-an funkcion &lt;a href=&quot;http://www.php.net/strftime&quot;&gt;strftime&lt;/a&gt;)';
+$lang['signature'] = 'Subskribo';
+$lang['toptoclevel'] = 'Supera nivelo por la enhavtabelo';
+$lang['tocminheads'] = 'Minimuma kvanto da ĉeftitoloj, kiu difinas ĉu la TOC estas kreita.';
+$lang['maxtoclevel'] = 'Maksimuma nivelo por la enhavtabelo';
+$lang['maxseclevel'] = 'Maksimuma nivelo por redakti sekciojn';
+$lang['camelcase'] = 'Uzi KamelUsklecon por ligiloj';
+$lang['deaccent'] = 'Netaj paĝnomoj';
+$lang['useheading'] = 'Uzi unuan titolon por paĝnomoj';
+$lang['refcheck'] = 'Kontrolo por referencoj al aŭdvidaĵoj';
+$lang['refshow'] = 'Nombro da referencoj al aŭdvidaĵoj por montri';
+$lang['allowdebug'] = 'Ebligi kodumpurigadon &lt;b&gt;malebligu se ne necese!&lt;/b&gt;';
+$lang['usewordblock'] = 'Bloki spamon surbaze de vortlisto';
+$lang['indexdelay'] = 'Prokrasto antaŭ ol indeksi (en sekundoj)';
+$lang['relnofollow'] = 'Uzi rel=&quot;nofollow&quot; kun eksteraj ligiloj';
+$lang['mailguard'] = 'Nebuligi retadresojn';
+$lang['iexssprotect'] = 'Ekzameni elŝutaĵojn kontraŭ eblaj malicaj ĴavaSkripto aŭ HTML-a kodumaĵo';
+$lang['showuseras'] = 'Kion montrigi dum indiko al la uzanto kiu laste redaktis paĝon.';
+$lang['useacl'] = 'Uzi alirkontrolajn listojn';
+$lang['autopasswd'] = 'Aŭtomate krei pasvortojn';
+$lang['authtype'] = 'Tipo de identiĝo';
+$lang['passcrypt'] = 'Metodo por ĉifri pasvortojn';
+$lang['defaultgroup'] = 'Antaŭdifinita grupo';
+$lang['superuser'] = 'Superanto - grupo, uzanto aŭ listo (apartite per komoj), kiu plene alireblas al ĉiuj paĝoj kaj funkcioj, sendepende de la reguloj ACL';
+$lang['manager'] = 'Administranto - grupo, uzanto aŭ listo (apartite per komoj), kiu havas alirpermeson al kelkaj administraj funkcioj';
+$lang['profileconfirm'] = 'Konfirmi ŝanĝojn en la trajtaro per pasvorto';
+$lang['disableactions'] = 'Malebligi DokuWiki-ajn agojn';
+$lang['disableactions_check'] = 'Kontroli';
+$lang['disableactions_subscription'] = 'Aliĝi/Malaliĝi';
+$lang['disableactions_wikicode'] = 'Rigardi vikitekston/Eksporti krudaĵon';
+$lang['disableactions_other'] = 'Aliaj agoj (apartite per komoj)';
+$lang['sneaky_index'] = 'Apriore, DokuWiki montras ĉiujn nomspacojn en la indeksa modo. Ebligi tiun ĉi elekteblon kaŝus tion, kion la uzanto ne rajtas legi laŭ ACL. Tio povus rezulti ankaŭan kaŝon de alireblaj subnomspacoj. Kaj tiel la indekso estus neuzebla por kelkaj agordoj de ACL.';
+$lang['auth_security_timeout'] = 'Sekureca Templimo por aŭtentigo (sekundoj)';
+$lang['securecookie'] = 'Ĉu kuketoj difinitaj per HTTPS nur estu senditaj de la foliumilo per HTTPS? Malebligu tiun ĉi opcion kiam nur la ensaluto al via vikio estas sekurigita per SSL, sed foliumado de la vikio estas farita malsekure.';
+$lang['xmlrpc'] = 'Ebligi/malebligi la interfacon XML-RPC.';
+$lang['xmlrpcuser'] = 'Permesi XML-RPC-an aliron al certaj grupoj aŭ uzantoj, bonvolu meti iliajn komoseparitajn nomojn tie ĉi. Alirebli de ĉiu, ĝin lasu malplena.';
+$lang['updatecheck'] = 'Ĉu kontroli aktualigojn kaj sekurecajn avizojn? DokuWiki bezonas kontakti update.dokuwiki.org por tiu ĉi trajto.';
+$lang['userewrite'] = 'Uzi netajn URL-ojn';
+$lang['useslash'] = 'Uzi frakcistrekon kiel apartigsignaĵo por nomspacoj en URL-oj';
+$lang['usedraft'] = 'Aŭtomate konservi skizon dum redaktado';
+$lang['sepchar'] = 'Apartigsignaĵo de vortoj en paĝnomoj';
+$lang['canonical'] = 'Uzi tute evidentajn URL-ojn';
+$lang['fnencode'] = 'Kodiga metodo por ne-ASCII-aj dosiernomoj.';
+$lang['autoplural'] = 'Kontroli pluralajn formojn en ligiloj';
+$lang['compression'] = 'Kompaktigmetodo por arkivaj dosieroj';
+$lang['cachetime'] = 'Maksimuma aĝo por provizmemoro (sek.)';
+$lang['locktime'] = 'Maksimuma aĝo por serurdosieroj (sek.)';
+$lang['fetchsize'] = 'Maksimuma grandeco (bitokoj), kiun fetch.php rajtas elŝuti el ekstere';
+$lang['notify'] = 'Sendi avizojn pri ŝanĝoj al tiu ĉi retadreso';
+$lang['registernotify'] = 'Sendi informon pri ĵusaj aliĝintoj al tiu ĉi retadreso';
+$lang['mailfrom'] = 'Retadreso uzota por aŭtomataj retmesaĝoj ';
+$lang['mailprefix'] = 'Retpoŝta temo-prefikso por uzi en aŭtomataj mesaĝoj';
+$lang['gzip_output'] = 'Uzi gzip-an enhav-enkodigon por XHTML';
+$lang['gdlib'] = 'Versio de GD-Lib';
+$lang['im_convert'] = 'Pado al la konvertilo de ImageMagick';
+$lang['jpg_quality'] = 'Kompaktiga kvalito de JPG (0-100)';
+$lang['subscribers'] = 'Ebligi subtenon de avizoj pri ŝanĝoj sur paĝoj';
+$lang['subscribe_time'] = 'Tempo, post kiu abonlistoj kaj kolektaĵoj sendiĝas (sek); Tio estu pli malgranda ol la tempo indikita en recent_days.';
+$lang['compress'] = 'Kompaktigi CSS-ajn kaj ĵavaskriptajn elmetojn';
+$lang['cssdatauri'] = 'Grandeco en bitokoj, ĝis kiom en CSS-dosieroj referencitaj bildoj estu enmetataj rekte en la stilfolion por malgrandigi vanan HTTP-kapan trafikon. Tiu tekniko ne funkcias en IE 7 aŭ pli frua!
+&lt;code&gt;400&lt;/code&gt; ĝis &lt;code&gt;600&lt;/code&gt; bitokoj estas bona grandeco. Indiku &lt;code&gt;0&lt;/code&gt; por malebligi enmeton.';
+$lang['hidepages'] = 'Kaŝi kongruantajn paĝojn (laŭ regulaj esprimoj)';
+$lang['send404'] = 'Sendi la mesaĝon &quot;HTTP 404/Paĝo ne trovita&quot; por ne ekzistantaj paĝoj';
+$lang['sitemap'] = 'Krei Guglan paĝarmapon &quot;sitemap&quot; (po kiom tagoj)';
+$lang['broken_iua'] = 'Ĉu la funkcio &quot;ignore_user_abort&quot; difektas en via sistemo? Tio povus misfunkciigi la serĉindekson. IIS+PHP/CGI estas konata kiel fuŝaĵo. Vidu &lt;a href=&quot;http://bugs.splitbrain.org/?do=details&amp;task_id=852&quot;&gt;Cimon 852&lt;/a&gt; por pli da informoj.';
+$lang['xsendfile'] = 'Ĉu uzi la kaplinion X-Sendfile por ebligi al la retservilo liveri fiksajn dosierojn? Via retservilo bezonus subteni tion.';
+$lang['renderer_xhtml'] = 'Prezentilo por la ĉefa vikia rezulto (xhtml)';
+$lang['renderer__core'] = '%s (DokuWiki-a kerno)';
+$lang['renderer__plugin'] = '%s (kromaĵo)';
+$lang['rememberme'] = 'Permesi longdaŭran ensalutajn kuketojn (rememoru min)';
+$lang['rss_type'] = 'XML-a tipo de novaĵ-fluo';
+$lang['rss_linkto'] = 'La novaĵ-fluo de XML ligiĝas al';
+$lang['rss_content'] = 'Kion montri en la XML-aj novaĵ-flueroj?';
+$lang['rss_update'] = 'Intertempo por ĝisdatigi XML-an novaĵ-fluon (sek.)';
+$lang['recent_days'] = 'Kiom da freŝaj ŝanĝoj por teni (tagoj)';
+$lang['rss_show_summary'] = 'XML-a novaĵ-fluo montras resumon en la titolo';
+$lang['target____wiki'] = 'Parametro &quot;target&quot; (celo) por internaj ligiloj';
+$lang['target____interwiki'] = 'Parametro &quot;target&quot; (celo) por intervikiaj ligiloj';
+$lang['target____extern'] = 'Parametro &quot;target&quot; (celo) por eksteraj ligiloj';
+$lang['target____media'] = 'Parametro &quot;target&quot; (celo) por aŭdvidaĵaj ligiloj';
+$lang['target____windows'] = 'Parametro &quot;target&quot; (celo) por Vindozaj ligiloj';
+$lang['proxy____host'] = 'Retservilnomo de la &quot;Proxy&quot;';
+$lang['proxy____port'] = 'Pordo ĉe la &quot;Proxy&quot;';
+$lang['proxy____user'] = 'Uzantonomo ĉe la &quot;Proxy&quot;';
+$lang['proxy____pass'] = 'Pasvorto ĉe la &quot;Proxy&quot;';
+$lang['proxy____ssl'] = 'Uzi SSL por konekti al la &quot;Proxy&quot;';
+$lang['proxy____except'] = 'Regula esprimo por URL-oj, kiujn la servilo preterrigardu.';
+$lang['safemodehack'] = 'Ebligi sekuran modon';
+$lang['ftp____host'] = 'FTP-a servilo por sekura modo';
+$lang['ftp____port'] = 'FTP-a pordo por sekura modo';
+$lang['ftp____user'] = 'FTP-a uzantonomo por sekura modo';
+$lang['ftp____pass'] = 'FTP-a pasvorto por sekura modo';
+$lang['ftp____root'] = 'FTP-a superuzanta (root) subdosierujo por sekura modo';
+$lang['license_o_'] = 'Nenio elektite';
+$lang['typography_o_0'] = 'nenio';
+$lang['typography_o_1'] = 'Nur duoblaj citiloj';
+$lang['typography_o_2'] = 'Ĉiaj citiloj (eble ne ĉiam funkcios)';
+$lang['userewrite_o_0'] = 'nenio';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Interne de DokuWiki';
+$lang['deaccent_o_0'] = 'ne';
+$lang['deaccent_o_1'] = 'forigi supersignojn';
+$lang['deaccent_o_2'] = 'latinigi';
+$lang['gdlib_o_0'] = 'GD-Lib ne disponeblas';
+$lang['gdlib_o_1'] = 'Versio 1.x';
+$lang['gdlib_o_2'] = 'Aŭtomata detekto';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Resumo';
+$lang['rss_content_o_diff'] = 'Unuigita &quot;Diff&quot;';
+$lang['rss_content_o_htmldiff'] = '&quot;Diff&quot;-tabelo formatita laŭ HTML';
+$lang['rss_content_o_html'] = 'Enhavo laŭ kompleta HTML-paĝo';
+$lang['rss_linkto_o_diff'] = 'diferenca rigardo';
+$lang['rss_linkto_o_page'] = 'la reviziita paĝo';
+$lang['rss_linkto_o_rev'] = 'listo de revizioj';
+$lang['rss_linkto_o_current'] = 'la aktuala paĝo';
+$lang['compression_o_0'] = 'nenio';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ne uzi';
+$lang['xsendfile_o_1'] = 'Propra kaplinio &quot;lighttpd&quot; (antaŭ versio 1.5)';
+$lang['xsendfile_o_2'] = 'Ordinara kaplinio X-Sendfile';
+$lang['xsendfile_o_3'] = 'Propra kaplinio Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Ensalut-nomo';
+$lang['showuseras_o_username'] = 'Kompleta nomo de uzanto';
+$lang['showuseras_o_email'] = 'Retadreso de uzanto (sekur-montrita laŭ agordo de mailguard)';
+$lang['showuseras_o_email_link'] = 'Retadreso de uzanto kiel mailto:-ligilo';
+$lang['useheading_o_0'] = 'Neniam';
+$lang['useheading_o_navigation'] = 'Nur foliumado';
+$lang['useheading_o_content'] = 'Nur vikia enhavo';
+$lang['useheading_o_1'] = 'Ĉiam';
+$lang['readdircache'] = 'Maksimuma daŭro de la dosieruja kaŝmemoro (sekundoj)';
diff --git a/lib/plugins/config/lang/es/intro.txt b/lib/plugins/config/lang/es/intro.txt
new file mode 100644
index 000000000..0b42c6ba9
--- /dev/null
+++ b/lib/plugins/config/lang/es/intro.txt
@@ -0,0 +1,7 @@
+====== Administrador de configuración ======
+
+Usa esta página para controlar los parámetros de tu instalación de Dokuwiki. Ayuda sobre [[doku>config|parámetros individuales]]. Más detalles sobre este [[doku>plugin:config|plugin]].
+
+Los parámetros que se muestran sobre un fondo rosado están protegidos y no pueden ser modificados usando este plugin. Los parámetros que se muestran sobre un fondo azul tienen los valores por defecto, y los parámetros mostrados sobre un fondo blanco han sido establecidos para esta instalación en particular. Tanto los parámetros sobre fondo azul y los que están sobre fondo blanco pueden ser modificados.
+
+Recuerda cliquear el boton **Guardar** antes de abandonar la página, sino se perderán los cambios que hayas hecho.
diff --git a/lib/plugins/config/lang/es/lang.php b/lib/plugins/config/lang/es/lang.php
new file mode 100644
index 000000000..9146633cf
--- /dev/null
+++ b/lib/plugins/config/lang/es/lang.php
@@ -0,0 +1,205 @@
+<?php
+/**
+ * spanish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Miguel Pagano <miguel.pagano@gmail.com>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ * @author Gabriel Castillo <gch@pumas.ii.unam.mx>
+ * @author oliver@samera.com.py
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Manuel Meco <manuel.meco@gmail.com>
+ * @author VictorCastelan <victorcastelan@gmail.com>
+ * @author Jordan Mero hack.jord@gmail.com
+ * @author Felipe Martinez <metalmartinez@gmail.com>
+ * @author Javier Aranda <internet@javierav.com>
+ * @author Zerial <fernando@zerial.org>
+ * @author Marvin Ortega <maty1206@maryanlinux.com>
+ * @author Daniel Castro Alvarado <dancas2@gmail.com>
+ * @author Fernando J. Gómez <fjgomez@gmail.com>
+ * @author Victor Castelan <victorcastelan@gmail.com>
+ * @author Mauro Javier Giamberardino <mgiamberardino@gmail.com>
+ * @author emezeta <emezeta@infoprimo.com>
+ * @author Oscar Ciudad <oscar@jacho.net>
+ * @author Ruben Figols <ruben.figols@gmail.com>
+ */
+$lang['menu'] = 'Parámetros de configuración';
+$lang['error'] = 'Los parámetros no han sido actualizados a causa de un valor inválido, por favor revise los cambios y re-envíe el formulario. <br /> Los valores incorrectos se mostrarán con un marco rojo alrededor.';
+$lang['updated'] = 'Los parámetros se actualizaron con éxito.';
+$lang['nochoice'] = '(no hay otras alternativas disponibles)';
+$lang['locked'] = 'El archivo de configuración no ha podido ser actualizado, si esto no es lo deseado, <br /> asegúrese que el nombre del archivo local de configuraciones y los permisos sean los correctos.';
+$lang['danger'] = 'Atención: Cambiar esta opción podría hacer inaccesible el wiki y su menú de configuración.';
+$lang['warning'] = 'Advertencia: Cambiar esta opción podría causar comportamientos no deseados.';
+$lang['security'] = 'Advertencia de Seguridad: Cambiar esta opción podría representar un riesgo de seguridad.';
+$lang['_configuration_manager'] = 'Administrador de configuración';
+$lang['_header_dokuwiki'] = 'Parámetros de DokuWiki';
+$lang['_header_plugin'] = 'Parámetros de Plugin';
+$lang['_header_template'] = 'Parámetros de Plantillas';
+$lang['_header_undefined'] = 'Parámetros sin categoría';
+$lang['_basic'] = 'Parámetros Básicos';
+$lang['_display'] = 'Parámetros de Presentación';
+$lang['_authentication'] = 'Parámetros de Autenticación';
+$lang['_anti_spam'] = 'Parámetros Anti-Spam';
+$lang['_editing'] = 'Parámetros de Edición';
+$lang['_links'] = 'Parámetros de Enlaces';
+$lang['_media'] = 'Parámetros de Medios';
+$lang['_advanced'] = 'Parámetros Avanzados';
+$lang['_network'] = 'Parámetros de Red';
+$lang['_plugin_sufix'] = 'Parámetros de Plugins';
+$lang['_template_sufix'] = 'Parámetros de Plantillas';
+$lang['_msg_setting_undefined'] = 'Sin parámetros de metadata.';
+$lang['_msg_setting_no_class'] = 'Sin clase establecida.';
+$lang['_msg_setting_no_default'] = 'Sin valor por defecto.';
+$lang['fmode'] = 'Modo de creación de ficheros';
+$lang['dmode'] = 'Modo de creación de directorios';
+$lang['lang'] = 'Idioma';
+$lang['basedir'] = 'Directorio de base';
+$lang['baseurl'] = 'URL de base';
+$lang['savedir'] = 'Directorio para guardar los datos';
+$lang['cookiedir'] = 'Ruta para las Cookie. Dejar en blanco para usar la ruta básica.';
+$lang['start'] = 'Nombre de la página inicial';
+$lang['title'] = 'Título del wiki';
+$lang['template'] = 'Plantilla';
+$lang['license'] = '¿Bajo qué licencia será liberado tu contenido?';
+$lang['fullpath'] = 'Mostrar ruta completa en el pie de página';
+$lang['recent'] = 'Cambios recientes';
+$lang['breadcrumbs'] = 'Número de pasos de traza';
+$lang['youarehere'] = 'Traza jerárquica';
+$lang['typography'] = 'Realizar reemplazos tipográficos';
+$lang['htmlok'] = 'Permitir HTML embebido';
+$lang['phpok'] = 'Permitir PHP embebido';
+$lang['dformat'] = 'Formato de fecha (ver la función de PHP <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Firma';
+$lang['toptoclevel'] = 'Nivel superior para la tabla de contenidos';
+$lang['tocminheads'] = 'La cantidad mínima de titulares que determina si el TOC es construido';
+$lang['maxtoclevel'] = 'Máximo nivel para la tabla de contenidos';
+$lang['maxseclevel'] = 'Máximo nivel para edición de sección';
+$lang['camelcase'] = 'Usar CamelCase para enlaces';
+$lang['deaccent'] = 'Nombres de páginas "limpios"';
+$lang['useheading'] = 'Usar el primer encabezado para nombres de páginas';
+$lang['refcheck'] = 'Control de referencia a medios';
+$lang['refshow'] = 'Número de referencias a medios a mostrar';
+$lang['allowdebug'] = 'Permitir debug <b>deshabilítelo si no lo necesita!</b>';
+$lang['mediarevisions'] = '¿Habilitar Mediarevisions?';
+$lang['usewordblock'] = 'Bloquear spam usando una lista de palabras';
+$lang['indexdelay'] = 'Intervalo de tiempo antes de indexar (segundos)';
+$lang['relnofollow'] = 'Usar rel="nofollow" en enlaces externos';
+$lang['mailguard'] = 'Ofuscar direcciones de correo electrónico';
+$lang['iexssprotect'] = 'Comprobar posible código malicioso (JavaScript ó HTML) en archivos subidos';
+$lang['showuseras'] = 'Qué ver al mostrar el último usuario que editó una página';
+$lang['useacl'] = 'Usar listas de control de acceso (ACL)';
+$lang['autopasswd'] = 'Autogenerar contraseñas';
+$lang['authtype'] = 'Método de Autenticación';
+$lang['passcrypt'] = 'Método de cifrado de contraseñas';
+$lang['defaultgroup'] = 'Grupo por defecto';
+$lang['superuser'] = 'Super-usuario - grupo ó usuario con acceso total a todas las páginas y funciones, configuraciones ACL';
+$lang['manager'] = 'Manager - grupo o usuario con acceso a ciertas tareas de mantenimiento';
+$lang['profileconfirm'] = 'Confirmar cambios en perfil con contraseña';
+$lang['disableactions'] = 'Deshabilitar acciones DokuWiki';
+$lang['disableactions_check'] = 'Controlar';
+$lang['disableactions_subscription'] = 'Suscribirse/Cancelar suscripción';
+$lang['disableactions_wikicode'] = 'Ver la fuente/Exportar en formato raw';
+$lang['disableactions_other'] = 'Otras acciones (separadas por coma)';
+$lang['sneaky_index'] = 'Por defecto, DokuWiki mostrará todos los namespaces en el index. Habilitando esta opción los ocultará si el usuario no tiene permisos de lectura. Los sub-namespaces pueden resultar inaccesibles. El index puede hacerse poco usable dependiendo de las configuraciones ACL.';
+$lang['auth_security_timeout'] = 'Tiempo de Autenticación (en segundos), por motivos de seguridad';
+$lang['securecookie'] = 'Las cookies establecidas por HTTPS, ¿el naveagdor solo puede enviarlas por HTTPS? Inhabilite esta opción cuando solo se asegure con SSL la entrada, pero no la navegación de su wiki.';
+$lang['xmlrpc'] = 'Habilitar/Deshabilitar interfaz XML-RPC';
+$lang['xmlrpcuser'] = 'Restringir el acceso XML-RPC a los grupos o usuarios separados por coma mencionados aquí. Dejar en blanco para dar acceso a todo el mundo. ';
+$lang['updatecheck'] = '¿Comprobar actualizaciones y advertencias de seguridad? Esta característica requiere que DokuWiki se conecte a update.dokuwiki.org.';
+$lang['userewrite'] = 'Usar URLs bonitas';
+$lang['useslash'] = 'Usar barra (/) como separador de espacios de nombres en las URLs';
+$lang['usedraft'] = 'Guardar automáticamente un borrador mientras se edita';
+$lang['sepchar'] = 'Separador de palabras en nombres de páginas';
+$lang['canonical'] = 'Usar URLs totalmente canónicas';
+$lang['fnencode'] = 'Método para codificar nombres de archivo no-ASCII.';
+$lang['autoplural'] = 'Controlar plurales en enlaces';
+$lang['compression'] = 'Método de compresión para archivos en el ático';
+$lang['cachetime'] = 'Edad máxima para caché (segundos)';
+$lang['locktime'] = 'Edad máxima para archivos de bloqueo (segundos)';
+$lang['fetchsize'] = 'Tamaño máximo (bytes) que fetch.php puede descargar de sitios externos';
+$lang['notify'] = 'Enviar notificación de cambios a esta dirección de correo electrónico';
+$lang['registernotify'] = 'Enviar información cuando se registran nuevos usuarios a esta dirección de correo electrónico';
+$lang['mailfrom'] = 'Dirección de correo electrónico para emails automáticos';
+$lang['mailprefix'] = 'Asunto por defecto que se utilizará en mails automáticos.';
+$lang['gzip_output'] = 'Usar gzip Content-Encoding para xhtml';
+$lang['gdlib'] = 'Versión de GD Lib';
+$lang['im_convert'] = 'Ruta a la herramienta de conversión de ImageMagick';
+$lang['jpg_quality'] = 'Calidad de compresión de JPG (0-100)';
+$lang['subscribers'] = 'Habilitar soporte para suscripción a páginas';
+$lang['subscribe_time'] = 'Tiempo después que alguna lista de suscripción fue enviada (seg); Debe ser menor que el tiempo especificado en días recientes.';
+$lang['compress'] = 'Compactar la salida de CSS y javascript';
+$lang['cssdatauri'] = 'Tamaño en bytes hasta el cual las imágenes referenciadas en archivos CSS deberían ir incrustadas en la hoja de estilos para reducir el número de cabeceras de petición HTTP. ¡Esta técnica no funcionará en IE < 8! De <code>400</code> a <code>600</code> bytes es un valor adecuado. Establezca <code>0</code> para deshabilitarlo.';
+$lang['hidepages'] = 'Ocultar páginas con coincidencias (expresiones regulares)';
+$lang['send404'] = 'Enviar "HTTP 404/Page Not Found" para páginas no existentes';
+$lang['sitemap'] = 'Generar sitemap de Google (días)';
+$lang['broken_iua'] = '¿Se ha roto (broken) la función ignore_user_abort en su sistema? Esto puede causar que no funcione el index de búsqueda. Se sabe que IIS+PHP/CGI está roto. Vea <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>para más información.';
+$lang['xsendfile'] = '¿Utilizar la cabecera X-Sendfile para permitirle al servidor web enviar archivos estáticos? Su servidor web necesita tener la capacidad para hacerlo.';
+$lang['renderer_xhtml'] = 'Visualizador a usar para salida (xhtml) principal del wiki';
+$lang['renderer__core'] = '%s (núcleo dokuwiki)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Permitir cookies para acceso permanente (recordarme)';
+$lang['rss_type'] = 'Tipo de resumen (feed) XML';
+$lang['rss_linkto'] = 'Feed XML enlaza a';
+$lang['rss_content'] = '¿Qué mostrar en los items del archivo XML?';
+$lang['rss_update'] = 'Intervalo de actualización de feed XML (segundos)';
+$lang['recent_days'] = 'Cuántos cambios recientes mantener (días)';
+$lang['rss_show_summary'] = 'Feed XML muestra el resumen en el título';
+$lang['target____wiki'] = 'Ventana para enlaces internos';
+$lang['target____interwiki'] = 'Ventana para enlaces interwikis';
+$lang['target____extern'] = 'Ventana para enlaces externos';
+$lang['target____media'] = 'Ventana para enlaces a medios';
+$lang['target____windows'] = 'Ventana para enlaces a ventanas';
+$lang['proxy____host'] = 'Nombre del servidor Proxy';
+$lang['proxy____port'] = 'Puerto del servidor Proxy';
+$lang['proxy____user'] = 'Nombre de usuario para el servidor Proxy';
+$lang['proxy____pass'] = 'Contraseña para el servidor Proxy';
+$lang['proxy____ssl'] = 'Usar ssl para conectarse al servidor Proxy';
+$lang['proxy____except'] = 'Expresiones regulares para encontrar URLs que el proxy debería omitir.';
+$lang['safemodehack'] = 'Habilitar edición (hack) de modo seguro';
+$lang['ftp____host'] = 'Nombre del servidor FTP para modo seguro';
+$lang['ftp____port'] = 'Puerto del servidor FTP para modo seguro';
+$lang['ftp____user'] = 'Nombre de usuario para el servidor FTP para modo seguro';
+$lang['ftp____pass'] = 'Contraseña para el servidor FTP para modo seguro';
+$lang['ftp____root'] = 'Directorio raiz para el servidor FTP para modo seguro';
+$lang['license_o_'] = 'No se eligió ninguna';
+$lang['typography_o_0'] = 'ninguno';
+$lang['typography_o_1'] = 'Dobles comillas solamente';
+$lang['typography_o_2'] = 'Todas las comillas (puede ser que no siempre funcione)';
+$lang['userewrite_o_0'] = 'ninguno';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Interno de DokuWiki';
+$lang['deaccent_o_0'] = 'apagado';
+$lang['deaccent_o_1'] = 'eliminar tildes';
+$lang['deaccent_o_2'] = 'romanizar';
+$lang['gdlib_o_0'] = 'GD Lib no está disponible';
+$lang['gdlib_o_1'] = 'Versión 1.x';
+$lang['gdlib_o_2'] = 'Autodetección';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Resumen';
+$lang['rss_content_o_diff'] = 'Diferencias unificadas';
+$lang['rss_content_o_htmldiff'] = 'Tabla de diferencias en formato HTML';
+$lang['rss_content_o_html'] = 'Página que solo contiene código HTML';
+$lang['rss_linkto_o_diff'] = 'ver las diferencias';
+$lang['rss_linkto_o_page'] = 'la página revisada';
+$lang['rss_linkto_o_rev'] = 'lista de revisiones';
+$lang['rss_linkto_o_current'] = 'la página actual';
+$lang['compression_o_0'] = 'ninguna';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'no utilizar';
+$lang['xsendfile_o_1'] = 'Encabezado propietario de lighttpd (antes de la versión 1.5)';
+$lang['xsendfile_o_2'] = 'Encabezado X-Sendfile estándar';
+$lang['xsendfile_o_3'] = 'Encabezado propietario Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Nombre de entrada';
+$lang['showuseras_o_username'] = 'Nombre completo del usuario';
+$lang['showuseras_o_email'] = 'Dirección de correo electrónico del usuario (ofuscada según la configuración de "mailguard")';
+$lang['showuseras_o_email_link'] = 'Dirección de correo de usuario como enlace de envío de correo';
+$lang['useheading_o_0'] = 'Nunca';
+$lang['useheading_o_navigation'] = 'Solamente Navegación';
+$lang['useheading_o_content'] = 'Contenido wiki solamente';
+$lang['useheading_o_1'] = 'Siempre';
+$lang['readdircache'] = 'Tiempo máximo para la cache readdir (en segundos)';
diff --git a/lib/plugins/config/lang/et/lang.php b/lib/plugins/config/lang/et/lang.php
new file mode 100644
index 000000000..27f2e87ac
--- /dev/null
+++ b/lib/plugins/config/lang/et/lang.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Estonian language file
+ *
+ * @author kristian.kankainen@kuu.la
+ * @author Rivo Zängov <eraser@eraser.ee>
+ */
+$lang['menu'] = 'Seadete haldamine';
+$lang['_configuration_manager'] = 'Seadete haldamine';
+$lang['_basic'] = 'Peamised seaded';
+$lang['_display'] = 'Näitamise seaded';
+$lang['_authentication'] = 'Audentimise seaded';
+$lang['_anti_spam'] = 'Spämmitõrje seaded';
+$lang['_editing'] = 'Muutmise seaded';
+$lang['_links'] = 'Lingi seaded';
+$lang['_media'] = 'Meedia seaded';
+$lang['_advanced'] = 'Laiendatud seaded';
+$lang['_network'] = 'Võrgu seaded';
+$lang['_plugin_sufix'] = 'Plugina seaded';
+$lang['_template_sufix'] = 'Kujunduse seaded';
+$lang['title'] = 'Wiki pealkiri';
+$lang['template'] = 'Kujundus';
+$lang['recent'] = 'Viimased muudatused';
+$lang['signature'] = 'Allkiri';
+$lang['defaultgroup'] = 'Vaikimisi grupp';
+$lang['disableactions_check'] = 'Kontrolli';
+$lang['compression_o_0'] = 'pole';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ära kasuta';
+$lang['useheading_o_0'] = 'Mitte kunagi';
+$lang['useheading_o_1'] = 'Alati';
diff --git a/lib/plugins/config/lang/eu/intro.txt b/lib/plugins/config/lang/eu/intro.txt
new file mode 100644
index 000000000..17edb3e3e
--- /dev/null
+++ b/lib/plugins/config/lang/eu/intro.txt
@@ -0,0 +1,7 @@
+====== Konfigurazio Kudeatzailea ======
+
+Erabili orri hau zure DokiWiki instalazioaren aukerak kontrolatzeko. Aukera zehatzei buruz laguntza eskuratzeko ikusi [[doku>config]]. Plugin honi buruzko xehetasun gehiago eskuratzeko ikusi [[doku>plugin:config]].
+
+Atzealde gorri argi batez erakusten diren aukerak babestuak daude eta ezin dira plugin honekin aldatu. Atzealde urdin batez erakusten diren aukerak balio lehenetsiak dira eta atzealde zuriz erakutsiak modu lokalean ezarriak izan dira instalazio honentzat. Aukera urdin eta zuriak aldatuak izan daitezke.
+
+Gogoratu **GORDE** botoia sakatzeaz orri hau utzi baino lehen, bestela zure aldaketak galdu egingo baitira.
diff --git a/lib/plugins/config/lang/eu/lang.php b/lib/plugins/config/lang/eu/lang.php
new file mode 100644
index 000000000..9d001d494
--- /dev/null
+++ b/lib/plugins/config/lang/eu/lang.php
@@ -0,0 +1,184 @@
+<?php
+/**
+ * Basque language file
+ *
+ * @author Inko Illarramendi <inko.i.a@gmail.com>
+ */
+$lang['menu'] = 'Konfigurazio Ezarpenak';
+$lang['error'] = 'Ezarpenak ez dira eguneratu balio oker bat dela eta, mesedez errepasatu aldaketak eta berriz bidali. <br />Balio okerra(k) ertz gorriz inguratuak erakutsiko dira. ';
+$lang['updated'] = 'Ezarpenak arrakastaz eguneratuak.';
+$lang['nochoice'] = '(ez dago beste aukerarik)';
+$lang['locked'] = 'Ezarpenen fitxategia ezin da eguneratu, eta intentzioa hau ez bada, <br />
+ziurtatu ezarpen lokalen izena eta baimenak zuzenak direla.';
+$lang['danger'] = 'Kontuz: Aukera hau aldatzeak zure wikia eta konfigurazio menua eskuraezin utzi dezake.';
+$lang['warning'] = 'Oharra: Aukera hau aldatzeak ustekabeko portaera bat sortu dezake.';
+$lang['security'] = 'Segurtasun Oharra: Aukera hau aldatzeak segurtasun arrisku bat sortu dezake.';
+$lang['_configuration_manager'] = 'Konfigurazio Kudeatzailea';
+$lang['_header_dokuwiki'] = 'DokuWiki Ezarpenak';
+$lang['_header_plugin'] = 'Plugin Ezarpenak';
+$lang['_header_template'] = 'Txantiloi Ezarpenak';
+$lang['_header_undefined'] = 'Zehaztu gabeko Ezarpenak';
+$lang['_basic'] = 'Oinarrizko Ezarpenak';
+$lang['_display'] = 'Aurkezpen Ezarpenak';
+$lang['_authentication'] = 'Kautotze Ezarpenak';
+$lang['_anti_spam'] = 'Anti-Spam Ezarpenak';
+$lang['_editing'] = 'Edizio Ezarpenak';
+$lang['_links'] = 'Esteken Ezarpenak';
+$lang['_media'] = 'Multimedia Ezarpenak';
+$lang['_advanced'] = 'Ezarpen Aurreratuak';
+$lang['_network'] = 'Sare Ezarpenak';
+$lang['_plugin_sufix'] = 'Plugin Ezarpenak';
+$lang['_template_sufix'] = 'Txantiloi Ezarpenak';
+$lang['_msg_setting_undefined'] = 'Ezarpen metadaturik ez.';
+$lang['_msg_setting_no_class'] = 'Ezarpen klaserik ez.';
+$lang['_msg_setting_no_default'] = 'Balio lehenetsirik ez.';
+$lang['fmode'] = 'Fitxategi sortze modua';
+$lang['dmode'] = 'Direktorio sortze modua';
+$lang['lang'] = 'Hizkuntza';
+$lang['basedir'] = 'Oinarri direktorioa';
+$lang['baseurl'] = 'Oinarri URLa';
+$lang['savedir'] = 'Datuak gordetzeko direktorioa';
+$lang['start'] = 'Hasiera orriaren izena';
+$lang['title'] = 'Wiki-aren izenburua';
+$lang['template'] = 'Txantiloia';
+$lang['license'] = 'Zein lizentziapean argitaratu beharko lirateke edukiak?';
+$lang['fullpath'] = 'Orri oinean orrien bide osoa erakutsi';
+$lang['recent'] = 'Azken aldaketak';
+$lang['breadcrumbs'] = 'Arrasto pauso kopurua';
+$lang['youarehere'] = 'Arrasto pauso hierarkikoak';
+$lang['typography'] = 'Ordezkapen tipografikoak egin';
+$lang['htmlok'] = 'Enbotatutako HTMLa baimendu';
+$lang['phpok'] = 'Enbotatutako PHPa baimendu';
+$lang['dformat'] = 'Data formatua (ikusi PHPren <a href="http://www.php.net/strftime">strftime</a> funtzioa)';
+$lang['signature'] = 'Sinadura';
+$lang['toptoclevel'] = 'Eduki taularen goiko maila';
+$lang['tocminheads'] = 'Gutxiengo izenburu kopuru minimoa Edukien Taula-ren sortu dadin.';
+$lang['maxtoclevel'] = 'Eduki taularen maila maximoa';
+$lang['maxseclevel'] = 'Sekzio edizio mailaren maximoa';
+$lang['camelcase'] = 'Estekentzat CamelCase erabili';
+$lang['deaccent'] = 'Orri izen garbiak';
+$lang['useheading'] = 'Erabili lehen izenburua orri izen moduan';
+$lang['refcheck'] = 'Multimedia erreferentzia kontrolatu';
+$lang['refshow'] = 'Erakusteko multimedia erreferentzia kopurua';
+$lang['allowdebug'] = 'Baimendu debug-a <b>ezgaitu behar ez bada!</b>';
+$lang['usewordblock'] = 'Blokeatu spam-a hitz zerrenda batean oinarrituta';
+$lang['indexdelay'] = 'Denbora atzerapena indexatu baino lehen (seg)';
+$lang['relnofollow'] = 'Erabili rel="nofollow" kanpo esteketan';
+$lang['mailguard'] = 'Ezkutatu posta-e helbidea';
+$lang['iexssprotect'] = 'Egiaztatu igotako fitxategiak JavaScript edo HTML kode maltzurra detektatzeko';
+$lang['showuseras'] = 'Zer azaldu orri bat editatu duen azken erabiltzailea erakusterakoan';
+$lang['useacl'] = 'Erabili atzipen kontrol listak';
+$lang['autopasswd'] = 'Pasahitzak automatikoki sortu';
+$lang['authtype'] = 'Kautotze backend-a';
+$lang['passcrypt'] = 'Pasahitz enkriptatze metodoa';
+$lang['defaultgroup'] = 'Talde lehenetsia';
+$lang['superuser'] = 'Supererabiltzailea - taldea, erabiltzailea edo komaz bereiztutako zerrenda user1,@group1,user2 orri eta funtzio guztietara atzipen osoarekin, AKL-ren ezarpenetan zehaztutakoa kontutan hartu gabe';
+$lang['manager'] = 'Kudeatzailea - talde, erabiltzaile edo komaz bereiztutako zerrenda user1,@group1,user2 kudeatze funtzio zehatz batzuetara atzipenarekin';
+$lang['profileconfirm'] = 'Profil aldaketak pasahitzaz berretsi';
+$lang['disableactions'] = 'DokuWiki ekintzak ezgaitu';
+$lang['disableactions_check'] = 'Egiaztatu';
+$lang['disableactions_subscription'] = 'Harpidetu/Harpidetza utzi';
+$lang['disableactions_wikicode'] = 'Ikusi iturburua/Esportatu Raw';
+$lang['disableactions_other'] = 'Beste ekintzak (komaz bereiztuak)';
+$lang['sneaky_index'] = 'Lehenespenez, DokuWiki-k izen-espazio guztiak indize bistan erakutsiko ditu. Aukera hau gaituta, erabiltzaieak irakurtzeko baimenik ez dituen izen-espazioak ezkutatuko dira. Honek atzigarriak diren azpi izen-espazioak ezkutatzen ditu. Agian honek indizea erabili ezin ahal izatea eragingo du AKL ezarpen batzuetan.';
+$lang['auth_security_timeout'] = 'Kautotze Segurtasun Denbora-Muga (segunduak)';
+$lang['securecookie'] = 'HTTPS bidez ezarritako cookie-ak HTTPS bidez bakarrik bidali beharko lituzke nabigatzaileak? Ezgaitu aukera hau bakarrik saio hasierak SSL bidezko segurtasuna badu baina wiki-areb nabigazioa modu ez seguruan egiten bada. ';
+$lang['xmlrpc'] = 'Gaitu/ezgaitu XML-RPC interfazea.';
+$lang['xmlrpcuser'] = 'XML-RPC atzipena mugatu hemen emandako komaz bereiztutako talde eta erabiltzaileei. Utzi hutsik atzipena guztiei emateko.';
+$lang['updatecheck'] = 'Konprobatu eguneratze eta segurtasun oharrak? DokuWiki-k honetarako update.dokuwiki.org kontaktatu behar du.';
+$lang['userewrite'] = 'Erabili URL politak';
+$lang['useslash'] = 'Erabili barra (/) izen-espazio banatzaile moduan URLetan';
+$lang['usedraft'] = 'Automatikoki zirriborroa gorde editatze garaian';
+$lang['sepchar'] = 'Orri izenaren hitz banatzailea';
+$lang['canonical'] = 'Erabili URL erabat kanonikoak';
+$lang['fnencode'] = 'Non-ASCII fitxategi izenak kodetzeko metodoa.';
+$lang['autoplural'] = 'Kontrolatu forma pluralak esteketan';
+$lang['compression'] = 'Trinkotze metodoa attic fitxategientzat';
+$lang['cachetime'] = 'Adin maximoa cachearentzat (seg)';
+$lang['locktime'] = 'Adin maximoa lock fitxategientzat (seg)';
+$lang['fetchsize'] = 'Kanpo esteketatik fetch.php-k deskargatu dezakeen tamaina maximoa (byteak)';
+$lang['notify'] = 'Aldaketen jakinarazpenak posta-e helbide honetara bidali';
+$lang['registernotify'] = 'Erregistratu berri diren erabiltzaileei buruzko informazioa post-e helbide honetara bidali';
+$lang['mailfrom'] = 'Posta automatikoentzat erabiliko den posta-e helbidea';
+$lang['mailprefix'] = 'Posta automatikoen gaientzat erabili beharreko aurrizkia';
+$lang['gzip_output'] = 'Gzip Eduki-Kodeketa erabili xhtml-rentzat';
+$lang['gdlib'] = 'GD Lib bertsioa';
+$lang['im_convert'] = 'ImageMagick-en aldaketa tresnara bidea';
+$lang['jpg_quality'] = 'JPG konprimitze kalitatea (0-100)';
+$lang['subscribers'] = 'Gaitu orri harpidetza euskarria';
+$lang['subscribe_time'] = 'Harpidetza zerrendak eta laburpenak bidali aurretik pasa beharreko denbora (seg); Denbora honek, recent_days-en ezarritakoa baino txikiagoa behar luke.';
+$lang['compress'] = 'Trinkotu CSS eta javascript irteera';
+$lang['hidepages'] = 'Ezkutatu kointzidentziak dituzten orriak (espresio erregularrak)';
+$lang['send404'] = 'Bidali "HTTP 404/Ez Da Orria Aurkitu" existitzen ez diren orrientzat';
+$lang['sitemap'] = 'Sortu Google gune-mapa (egunak)';
+$lang['broken_iua'] = 'Zure sisteman ignore_user_abort (erabiltzailearen bertan behera uztea kontuan ez hartu) funtzioa hautsia al dago? Honek funtzionatzen ez duen bilaketa indize bat eragin dezake. ISS+PHP/CGI hautsiak daude. Ikusi <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> informazio gehiago jasotzeko.';
+$lang['xsendfile'] = 'X-Sendfile goiburua erabili web zerbitzariari fitxategi estatikoak bidaltzen uzteko? Zure web zerbitzariak hau ahalbidetuta eduki beharko du.';
+$lang['renderer_xhtml'] = 'Erabiliko den errenderizatzailea wiki irteera (xhtml) nagusiarentzat';
+$lang['renderer__core'] = '%s (dokuwiki-ren nukleoa)';
+$lang['renderer__plugin'] = '%s (plugina)';
+$lang['rememberme'] = 'Baimendu saio hasiera cookie iraunkorrak (gogoratu iezaidazu)';
+$lang['rss_type'] = 'XML jario mota';
+$lang['rss_linkto'] = 'XML jarioak hona estekatzen du';
+$lang['rss_content'] = 'Zer erakutsi XML jarioetan?';
+$lang['rss_update'] = 'XML jarioaren eguneratze tartea (seg)';
+$lang['recent_days'] = 'Zenbat azken aldaketa gordeko dira (egunak)';
+$lang['rss_show_summary'] = 'XML jarioak laburpena erakusten du izenburuan';
+$lang['target____wiki'] = 'Barne estekentzat helburu leihoa';
+$lang['target____interwiki'] = 'Interwiki estekentzat helburu leihoa';
+$lang['target____extern'] = 'Kanpo estekentzat helburu leihoa';
+$lang['target____media'] = 'Multimedia estekentzat helburu leihoa';
+$lang['target____windows'] = 'Leihoen estekentzat helburu leihoa';
+$lang['proxy____host'] = 'Proxy zerbitzari izena';
+$lang['proxy____port'] = 'Proxy portua';
+$lang['proxy____user'] = 'Proxyaren erabiltzaile izena';
+$lang['proxy____pass'] = 'Proxyaren pasahitza ';
+$lang['proxy____ssl'] = 'Erabili SSL Proxyra konektatzeko';
+$lang['proxy____except'] = 'URLak detektatzeko espresio erregularra, zeinentzat Proxy-a sahiestu beharko litzatekeen.';
+$lang['safemodehack'] = 'Gaitu modu segurua hack-a';
+$lang['ftp____host'] = 'FTP zerbitzaria modu seguruarentzat';
+$lang['ftp____port'] = 'FTP portua modu seguruarentzat';
+$lang['ftp____user'] = 'FTP erabiltzailea modu seguruarentzat';
+$lang['ftp____pass'] = 'FTP pasahitza modu seguruarentzat';
+$lang['ftp____root'] = 'FTP erro direktorioa modu seguruarentzat';
+$lang['license_o_'] = 'Bat ere ez hautaturik';
+$lang['typography_o_0'] = 'ezer';
+$lang['typography_o_1'] = 'Komatxo bikoitzak bakarrik';
+$lang['typography_o_2'] = 'Komatxo guztiak (gerta daiteke beti ez funtzionatzea)';
+$lang['userewrite_o_0'] = 'ezer';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWikiren barnekoa';
+$lang['deaccent_o_0'] = 'Izalita';
+$lang['deaccent_o_1'] = 'azentu-markak kendu';
+$lang['deaccent_o_2'] = 'erromanizatu ';
+$lang['gdlib_o_0'] = 'GD Lib ez dago eskuragarri';
+$lang['gdlib_o_1'] = '1.x bertsioa';
+$lang['gdlib_o_2'] = 'Automatikoki detektatu';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Laburpena';
+$lang['rss_content_o_diff'] = 'Bateratutako Diferentziak';
+$lang['rss_content_o_htmldiff'] = 'HTML formatuko diferentzia taula';
+$lang['rss_content_o_html'] = 'Orri edukia guztiz HTML';
+$lang['rss_linkto_o_diff'] = 'Desberdintasunak ikusi';
+$lang['rss_linkto_o_page'] = 'Berrikusitako orria';
+$lang['rss_linkto_o_rev'] = 'Berrikuspen zerrenda';
+$lang['rss_linkto_o_current'] = 'Uneko orria';
+$lang['compression_o_0'] = 'ezer';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ez erabili';
+$lang['xsendfile_o_1'] = 'Jabegodun lighttpd goiburua (1.5 bertsioa baino lehen)';
+$lang['xsendfile_o_2'] = 'X-Sendfile goiburu estandarra';
+$lang['xsendfile_o_3'] = 'Jabegodun Nginx X-Accel-Redirect goiburua';
+$lang['showuseras_o_loginname'] = 'Saio izena';
+$lang['showuseras_o_username'] = 'Erabiltzailearen izen osoa';
+$lang['showuseras_o_email'] = 'Erabiltzailearen posta-e helbidea (ezkutatua posta babeslearen aukeren arabera)';
+$lang['showuseras_o_email_link'] = 'Erabiltzailearen posta-e helbidea mailto: esteka moduan';
+$lang['useheading_o_0'] = 'Inoiz';
+$lang['useheading_o_navigation'] = 'Nabigazioa Bakarrik';
+$lang['useheading_o_content'] = 'Wiki Edukia Bakarrik';
+$lang['useheading_o_1'] = 'Beti';
+$lang['readdircache'] = 'Aintzintasun maximoa readdir cache-rentzat (seg)';
diff --git a/lib/plugins/config/lang/fa/intro.txt b/lib/plugins/config/lang/fa/intro.txt
new file mode 100644
index 000000000..f5b6ba235
--- /dev/null
+++ b/lib/plugins/config/lang/fa/intro.txt
@@ -0,0 +1,8 @@
+====== تنظیمات پیکربندی ======
+
+از این صفحه برای مدیریت تنظیمات DokuWiki استفاده کنید. برای راهنمایی بیش‌تر به [[doku>config]] مراجعه نماید.
+برای جزییات در مورد این افزونه نیز می‌توانید به [[doku>plugin:config]] مراجعه کنید.
+
+تنظیماتی که با پیش‌زمینه‌ی قرمز مشخص شده‌اند، غیرقابل تغییر می‌باشند. تنظیماتی که به پیش‌زمینه‌ی آبی مشخص شده‌اند نیز حامل مقادیر پیش‌فرض می‌باشند و تنظیماتی که پیش‌زمینه‌ی سفید دارند به طور محلی برای این سیستم تنظیم شده‌اند. تمامی مقادیر آبی و سفید قابلیت تغییر دارند.
+
+به یاد داشته باشید که قبل از ترک صفحه، دکمه‌ی **ذخیره** را بفشارید، در غیر این صورت تنظیمات شما از بین خواهد رفت. \ No newline at end of file
diff --git a/lib/plugins/config/lang/fa/lang.php b/lib/plugins/config/lang/fa/lang.php
new file mode 100644
index 000000000..42cc3ed05
--- /dev/null
+++ b/lib/plugins/config/lang/fa/lang.php
@@ -0,0 +1,187 @@
+<?php
+/**
+ * Persian language file
+ *
+ * @author behrad eslamifar <behrad_es@yahoo.com)
+ * @author Mohsen Firoozmandan <info@mambolearn.com>
+ * @author omidmr@gmail.com
+ * @author Omid Mottaghi <omidmr@gmail.com>
+ * @author Mohammad Reza Shoaei <shoaei@gmail.com>
+ */
+$lang['menu'] = 'تنظیمات پیکر‌بندی';
+$lang['error'] = 'به دلیل ایراد در مقادیر وارد شده، تنظیمات اعمال نشد، خواهشمندیم تغییرات را مجددن کنترل نمایید و دوباره ارسال کنید.<br/> مقادیر مشکل‌دار با کادر قرمز مشخص شده‌اند.';
+$lang['updated'] = 'تنظیمات با موفقیت به روز رسانی شد.';
+$lang['nochoice'] = '(گزینه‌های دیگری موجود نیست)';
+$lang['locked'] = 'تنظیمات قابلیت به روز رسانی ندارند، اگر نباید چنین باشد، <br/> نام فایل تنظیمات و دسترسی‌های آن را بررسی کنید.';
+$lang['danger'] = 'خطر: ممکن است با تغییر این گزینه دسترسی به منوی تنظیمات قطع شود.';
+$lang['warning'] = 'هشدار: ممکن است با تغییر این گزینه رفتارهای غیرمترقبه‌ای مشاهده کنید.';
+$lang['security'] = 'هشدار امنیتی: تغییر این گزینه ممکن است با خطرات امنیتی همراه باشد.';
+$lang['_configuration_manager'] = 'مدیریت تنظیمات';
+$lang['_header_dokuwiki'] = 'تنظیمات DokuWiki';
+$lang['_header_plugin'] = 'تنظیمات افزونه';
+$lang['_header_template'] = 'تنظیمات قالب';
+$lang['_header_undefined'] = 'تنظیمات تعریف نشده';
+$lang['_basic'] = 'تنظیمات مقدماتی';
+$lang['_display'] = 'تنظیمات نمایش';
+$lang['_authentication'] = 'تنظیمات معتبرسازی';
+$lang['_anti_spam'] = 'تنظیمات ضد-اسپم';
+$lang['_editing'] = 'تنظیمات ویرایش';
+$lang['_links'] = 'تنظیمات پیوند';
+$lang['_media'] = 'تنظیمات رسانه‌ها (فایل‌ها)';
+$lang['_advanced'] = 'تنظیمات پیشرفته';
+$lang['_network'] = 'تنظیمات شبکه';
+$lang['_plugin_sufix'] = 'تنظیمات افزونه';
+$lang['_template_sufix'] = 'تنظیمات قالب';
+$lang['_msg_setting_undefined'] = 'داده‌نمایی برای تنظیمات وجود ندارد';
+$lang['_msg_setting_no_class'] = 'هیچ دسته‌ای برای تنظیمات وجود ندارد.';
+$lang['_msg_setting_no_default'] = 'بدون مقدار پیش‌فرض';
+$lang['fmode'] = 'دسترسی پیش‌فرض فایل‌ها در زمان ایجاد';
+$lang['dmode'] = 'زبان';
+$lang['lang'] = 'زبان';
+$lang['basedir'] = 'شاخه‌ی اصلی';
+$lang['baseurl'] = 'آدرس اصلی';
+$lang['savedir'] = 'شاخه‌ی ذخیره‌سازی داده‌ها';
+$lang['start'] = 'نام صفحه‌ی آغازین';
+$lang['title'] = 'عنوان ویکی';
+$lang['template'] = 'قالب';
+$lang['license'] = 'لایسنس مطالب ویکی';
+$lang['fullpath'] = 'نمایش دادن مسیر کامل صفحات در پایین صفحه';
+$lang['recent'] = 'تغییرات اخیر';
+$lang['breadcrumbs'] = 'تعداد ردپاها';
+$lang['youarehere'] = 'ردپای درختی';
+$lang['typography'] = 'جای‌گزاری متن‌ها انجام شود';
+$lang['htmlok'] = 'امکان افزودن HTML باشد';
+$lang['phpok'] = 'امکان افزودن PHP باشد';
+$lang['dformat'] = 'فرمت تاریخ (راهنمای تابع <a href="http://www.php.net/strftime">strftime</a> را مشاهده کنید)';
+$lang['signature'] = 'امضا';
+$lang['toptoclevel'] = 'بیشترین عمق برای «فهرست مطالب»';
+$lang['tocminheads'] = 'حداقل مقدار عنوان‌های یک صفحه، برای تشخیص این‌که «فهرست مطالب» (TOC) ایجاد شود';
+$lang['maxtoclevel'] = 'حداکثر عمق «فهرست مطالب»';
+$lang['maxseclevel'] = 'بیش‌ترین سطح ویرایش بخش‌ها';
+$lang['camelcase'] = 'از «حالت شتری» (CamelCase) برای پیوندها استفاده شود';
+$lang['deaccent'] = 'تمیز کردن نام صفحات';
+$lang['useheading'] = 'استفاده از اولین عنوان برای نام صفحه';
+$lang['refcheck'] = 'بررسی کردن مرجع رسانه‌ها';
+$lang['refshow'] = 'تعداد مراجعی که برای یک رسانه نمایش داده شود';
+$lang['allowdebug'] = 'امکان کرم‌زدایی (debug) <b>اگر نیازی ندارید، غیرفعال کنید</b>';
+$lang['usewordblock'] = 'اسپم‌ها را براساس لیست کلمات مسدود کن';
+$lang['indexdelay'] = 'مقدار تاخیر پیش از فهرست‌بندی (ثانیه)';
+$lang['relnofollow'] = 'از «rel=nofollow» در پیوندهای خروجی استفاده شود';
+$lang['mailguard'] = 'مبهم کردن آدرس‌های ایمیل';
+$lang['iexssprotect'] = 'بررسی کردن فایل‌های ارسال شده را برای کدهای HTML یا JavaScript مخرب';
+$lang['showuseras'] = 'چگونه آخرین کاربر ویرایش کننده، یک صفحه نمایش داده شود';
+$lang['useacl'] = 'استفاده از مدیریت دسترسی‌ها';
+$lang['autopasswd'] = 'ایجاد خودکار گذرواژه‌ها';
+$lang['authtype'] = 'روش معتبرسازی';
+$lang['passcrypt'] = 'روش کد کردن گذرواژه';
+$lang['defaultgroup'] = 'گروه پیش‌فرض';
+$lang['superuser'] = 'کاربر اصلی - گروه، کاربر یا لیستی که توسط ویرگول جدا شده از کاربرها و گروه‌ها (مثل user1,@group1,user2) با دسترسی کامل به همه‌ی صفحات و امکانات سیستم، فارغ از دسترسی‌های آن کاربر.';
+$lang['manager'] = 'مدیر - گروه، کاربر یا لیستی که توسط ویرگول جدا شده از کاربرها و گروه‌ها (مثل user1,@group1,user2) با دسترسی‌های خاص به بخش‌های متفاوت';
+$lang['profileconfirm'] = 'تغییرات پروفایل با وارد کردن گذرواژه تایید شود';
+$lang['disableactions'] = 'غیرفعال کردن فعالیت‌های DokuWiki';
+$lang['disableactions_check'] = 'بررسی';
+$lang['disableactions_subscription'] = 'عضویت/عدم عضویت';
+$lang['disableactions_wikicode'] = 'نمایش سورس/برون‌بری خام';
+$lang['disableactions_other'] = 'فعالیت‌های دیگر (با ویرگول انگلیسی «,» از هم جدا کنید)';
+$lang['sneaky_index'] = 'به طور پیش‌فرض، DokuWiki در فهرست تمامی فضای‌نام‌ها را نمایش می‌دهد. فعال کردن این گزینه، مواردی را که کاربر حق خواندنشان را ندارد مخفی می‌کند. این گزینه ممکن است باعث دیده نشدن زیرفضای‌نام‌هایی شود که دسترسی خواندن به آن‌ها وجود دارد. و ممکن است باعث شود که فهرست در حالاتی از دسترسی‌ها، غیرقابل استفاده شود.';
+$lang['auth_security_timeout'] = 'زمان انقضای معتبرسازی به ثانیه';
+$lang['securecookie'] = 'آیا کوکی‌ها باید با قرارداد HTTPS ارسال شوند؟ این گزینه را زمانی که فقط صفحه‌ی ورود ویکی‌تان با SSL امن شده است، اما ویکی را ناامن مرور می‌کنید، غیرفعال نمایید.';
+$lang['xmlrpc'] = 'فعال/غیرفعال کردن XML-RPC';
+$lang['xmlrpcuser'] = 'محمدود کردن دسترسی به XML-RPC توسط گروه های جدا شده توسط ویرگول ویا اعضای داده شده در اینجا. این مکان را خالی بگزارید تا به همه دسترسی داده شود.';
+$lang['updatecheck'] = 'هشدارهای به روز رسانی و امنیتی بررسی شود؟ برای این‌کار DokuWiki با سرور update.dokuwiki.org تماس خواهد گرفت.';
+$lang['userewrite'] = 'از زیباکننده‌ی آدرس‌ها استفاده شود';
+$lang['useslash'] = 'از اسلش «/» برای جداکننده‌ی آدرس فضای‌نام‌ها استفاده شود';
+$lang['usedraft'] = 'ایجاد خودکار چرک‌نویس در زمان نگارش';
+$lang['sepchar'] = 'کلمه‌ی جداکننده‌ی نام صفحات';
+$lang['canonical'] = 'استفاده از آدرس‌های استاندارد';
+$lang['fnencode'] = 'روش تغییر نام فایل‌هایی با فرمتی غیر از اسکی';
+$lang['autoplural'] = 'بررسی جمع بودن در پیوندها';
+$lang['compression'] = 'روش فشرده‌سازی برای فایل‌های خُرد';
+$lang['cachetime'] = 'بیشینه‌ی زمان حافظه‌ی موقت (cache) به ثانیه';
+$lang['locktime'] = 'بیشینه‌ی زمان قفل شدن فایل‌ها به ثانیه';
+$lang['fetchsize'] = 'بیشینه‌ی حجمی که فایل fetch.php می‌تواند دریافت کند (به بایت)';
+$lang['notify'] = 'تغییرات به این ایمیل ارسال شود';
+$lang['registernotify'] = 'اطلاعات کاربران تازه وارد به این ایمیل ارسال شود';
+$lang['mailfrom'] = 'آدرس ایمیلی که برای ایمیل‌های خودکار استفاده می‌شود';
+$lang['mailprefix'] = 'پیشوند تیتر ایمیل (جهت ایمیل های خودکار)';
+$lang['gzip_output'] = 'استفاده از gzip برای xhtmlها';
+$lang['gdlib'] = 'نگارش کتاب‌خانه‌ی GD';
+$lang['im_convert'] = 'مسیر ابزار convert از برنامه‌ی ImageMagick';
+$lang['jpg_quality'] = 'کیفیت فشرده سازی JPEG (از 0 تا 100)';
+$lang['subscribers'] = 'توانایی عضویت در صفحات باشد';
+$lang['subscribe_time'] = 'زمان مورد نیاز برای ارسال خبر نامه ها (ثانیه); این مقدار می بایست کمتر زمانی باشد که در recent_days تعریف شده است.';
+$lang['compress'] = 'فشرده‌سازی کد‌های CSS و JavaScript';
+$lang['hidepages'] = 'مخفی کردن صفحات با فرمت زیر (از عبارات منظم استفاده شود)';
+$lang['send404'] = 'ارسال «HTTP 404/Page Not Found» برای صفحاتی که وجود ندارند';
+$lang['sitemap'] = 'تولید کردن نقشه‌ی سایت توسط گوگل (روز)';
+$lang['broken_iua'] = 'آیا تابع ignore_user_about در ویکی شما کار نمی‌کند؟ ممکن است فهرست جستجوی شما کار نکند. IIS به همراه PHP/CGI باعث خراب شدن این گزینه می‌شود. برای اطلاعات بیشتر <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">باگ ۸۵۲</a> را مشاهده کنید.';
+$lang['xsendfile'] = 'استفاده از هدر X-Sendfile، تا به وب‌سرور توانایی ارسال فایل‌های ثابت را بدهد. وب‌سرور شما باید این مورد را پشتیبانی کند.';
+$lang['renderer_xhtml'] = 'مفسری که برای خروجی اصلی ویکی استفاده شود';
+$lang['renderer__core'] = '%s (هسته‌ی dokuwiki)';
+$lang['renderer__plugin'] = '%s (افزونه)';
+$lang['rememberme'] = 'امکان ورود دایم، توسط کوکی، وجود داشته باشد (مرا به خاطر بسپار)';
+$lang['rss_type'] = 'نوع خوراک';
+$lang['rss_linkto'] = 'خوراک به کجا لینک شود';
+$lang['rss_content'] = 'چه چیزی در تکه‌های خوراک نمایش داده شود؟';
+$lang['rss_update'] = 'زمان به روز رسانی خوراک به ثانیه';
+$lang['recent_days'] = 'چند تغییر در خوراک نمایش داده شود به روز';
+$lang['rss_show_summary'] = 'خوراک مختصری از مطلب را در عنوان نمایش دهد';
+$lang['target____wiki'] = 'پنجره‌ی هدف در پیوند‌های داخلی';
+$lang['target____interwiki'] = 'پنجره‌ی هدف در پیوند‌های داخل ویکی';
+$lang['target____extern'] = 'پنجره‌ی هدف در پیوند‌های خارجی';
+$lang['target____media'] = 'پنجره‌ی هدف در پیوند‌های رسانه‌ها';
+$lang['target____windows'] = 'پنجره‌ی هدف در پیوند‌های پنجره‌ای';
+$lang['proxy____host'] = 'آدرس سرور پروکسی';
+$lang['proxy____port'] = 'پورت پروکسی';
+$lang['proxy____user'] = 'نام کاربری پروکسی';
+$lang['proxy____pass'] = 'گذرواژهي پروکسی';
+$lang['proxy____ssl'] = 'استفاده از SSL برای اتصال به پروکسی';
+$lang['proxy____except'] = 'عبارت منظم برای تطبیق با URLها برای این‌که دریابیم که از روی چه پروکسی‌ای باید بپریم!';
+$lang['safemodehack'] = 'فعال کردن safemode hack';
+$lang['ftp____host'] = 'آدرس FTP برای safemode hack';
+$lang['ftp____port'] = 'پورت FTP برای safemode hack';
+$lang['ftp____user'] = 'نام کاربری FTP برای safemode hack';
+$lang['ftp____pass'] = 'گذرواژه‌ی FTP برای safemode hack';
+$lang['ftp____root'] = 'شاخه‌ی FTP برای safemode hack';
+$lang['license_o_'] = 'هیچ کدام';
+$lang['typography_o_0'] = 'هیچ';
+$lang['typography_o_1'] = 'حذف کردن single-quote';
+$lang['typography_o_2'] = 'به همراه داشتن single-quote (ممکن است همیشه کار نکند)';
+$lang['userewrite_o_0'] = 'هیچ';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'از طریق DokuWiki';
+$lang['deaccent_o_0'] = 'خاموش';
+$lang['deaccent_o_1'] = 'برداشتن تلفظ‌ها';
+$lang['deaccent_o_2'] = 'لاتین کردن (romanize)';
+$lang['gdlib_o_0'] = 'کتاب‌خانه‌ی GD موجود نیست';
+$lang['gdlib_o_1'] = 'نسخه‌ی 1.X';
+$lang['gdlib_o_2'] = 'انتخاب خودکار';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'انتزاعی';
+$lang['rss_content_o_diff'] = 'یکی کردن تفاوت‌ها';
+$lang['rss_content_o_htmldiff'] = 'جدول تفاوت‌ها با ساختار HTML';
+$lang['rss_content_o_html'] = 'تمامی محتویات صفحه، با ساختار HTML';
+$lang['rss_linkto_o_diff'] = 'نمایه‌های متفاوت';
+$lang['rss_linkto_o_page'] = 'صفحه‌ی تجدید نظر شده';
+$lang['rss_linkto_o_rev'] = 'لیست نگارش‌ها';
+$lang['rss_linkto_o_current'] = 'صفحه‌ی کنونی';
+$lang['compression_o_0'] = 'هیچ';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'استفاده نکنید';
+$lang['xsendfile_o_1'] = 'هدر اختصاصی lighttpd (پیش از نگارش ۱.۵)';
+$lang['xsendfile_o_2'] = 'هدر استاندارد X-Sendfile';
+$lang['xsendfile_o_3'] = 'هدر اختصاصی X-Accel-Redirect در وب سرور Nginx';
+$lang['showuseras_o_loginname'] = 'نام کاربری';
+$lang['showuseras_o_username'] = 'نام کامل کاربران';
+$lang['showuseras_o_email'] = 'آدرس ایمیل کاربران (با تنظیمات «نگهبان ایمیل» مبهم می‌شود)';
+$lang['showuseras_o_email_link'] = 'نمایش ایمیل کاربران با افزودن mailto';
+$lang['useheading_o_0'] = 'هرگز';
+$lang['useheading_o_navigation'] = 'فقط ناوبری (navigation)';
+$lang['useheading_o_content'] = 'فقط محتویات ویکی';
+$lang['useheading_o_1'] = 'همیشه';
+$lang['readdircache'] = 'بیش‌ترین عمر برای حافظه‌ی موقت readdir (ثانیه)';
diff --git a/lib/plugins/config/lang/fi/intro.txt b/lib/plugins/config/lang/fi/intro.txt
new file mode 100644
index 000000000..f6eedb50c
--- /dev/null
+++ b/lib/plugins/config/lang/fi/intro.txt
@@ -0,0 +1,7 @@
+====== Asetusten hallinta ======
+
+Käytä tätä sivua hallitaksesi DokuWikisi asetuksia. Apua yksittäisiin asetuksiin löytyy sivulta [[doku>config]]. Lisätietoa tästä liitännäisestä löytyy sivulta [[doku>plugin:config]].
+
+Asetukset, jotka näkyvät vaaleanpunaisella taustalla ovat suojattuja, eikä niitä voi muutta tämän liitännäisen avulla. Asetukset, jotka näkyvät sinisellä taustalla ovat oletusasetuksia. Asetukset valkoisella taustalla ovat asetettu paikallisesti tätä asennusta varten. Sekä sinisiä että valkoisia asetuksia voi muokata.
+
+Muista painaa **TALLENNA**-nappia ennen kuin poistut sivulta. Muuten muutoksesi häviävät. \ No newline at end of file
diff --git a/lib/plugins/config/lang/fi/lang.php b/lib/plugins/config/lang/fi/lang.php
new file mode 100644
index 000000000..9598a0d93
--- /dev/null
+++ b/lib/plugins/config/lang/fi/lang.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * Finnish language file
+ *
+ * @author otto@valjakko.net
+ * @author Otto Vainio <otto@valjakko.net>
+ * @author Teemu Mattila <ghcsystems@gmail.com>
+ * @author Sami Olmari <sami@olmari.fi>
+ */
+$lang['menu'] = 'Asetukset';
+$lang['error'] = 'Asetuksia ei päivitetty väärän arvon vuoksi. Tarkista muutokset ja lähetä sivu uudestaan.
+<br />Väärät arvot on merkitty punaisella reunuksella.';
+$lang['updated'] = 'Asetukset päivitetty onnistuneesti.';
+$lang['nochoice'] = '(ei muita valintoja saatavilla)';
+$lang['locked'] = 'Asetustiedosta ei voi päivittää. Jos tämä ei ole tarkoitus <br />
+niin varmista, että paikallisten asetusten tiedoston nimi ja oikeudet ovat kunnossa.';
+$lang['danger'] = 'Vaara: tämän asetuksen muuttaminen saattaa estää wikisi ja asetusvalikon toimimisen.';
+$lang['warning'] = 'Varoitus: tämän asetuksen muuttaminen saattaa aiheuttaa olettamattomia toimintoja.';
+$lang['security'] = 'Turvallisuusvaroitus: tämän asetuksen muuttaminen saattaa aiheuttaa tietoturva-aukon.';
+$lang['_configuration_manager'] = 'Asetusten hallinta';
+$lang['_header_dokuwiki'] = 'DokuWikin asetukset';
+$lang['_header_plugin'] = 'Liitännäisten asetukset';
+$lang['_header_template'] = 'Sivumallin asetukset';
+$lang['_header_undefined'] = 'Määritetelettömät asetukset';
+$lang['_basic'] = 'Perusasetukset';
+$lang['_display'] = 'Näyttöasetukset';
+$lang['_authentication'] = 'Sisäänkirjoittautumisen asetukset';
+$lang['_anti_spam'] = 'Anti-Spam asetukset';
+$lang['_editing'] = 'Sivumuokkauksen asetukset';
+$lang['_links'] = 'Linkkien asetukset';
+$lang['_media'] = 'Media-asetukset';
+$lang['_advanced'] = 'Lisäasetukset';
+$lang['_network'] = 'Verkkoasetukset';
+$lang['_plugin_sufix'] = 'liitännäisen asetukset';
+$lang['_template_sufix'] = 'Sivumallin asetukset';
+$lang['_msg_setting_undefined'] = 'Ei asetusten metadataa.';
+$lang['_msg_setting_no_class'] = 'Ei asetusluokkaa.';
+$lang['_msg_setting_no_default'] = 'Ei oletusarvoa';
+$lang['fmode'] = 'Tiedoston luontioikeudet';
+$lang['dmode'] = 'Hakemiston luontioikeudet';
+$lang['lang'] = 'Kieli';
+$lang['basedir'] = 'Perushakemisto';
+$lang['baseurl'] = 'Perus URL';
+$lang['savedir'] = 'Hakemisto tietojen tallennukseen.';
+$lang['cookiedir'] = 'Cookien path. Jätä tyhjäksi käyttääksesi baseurl arvoa';
+$lang['start'] = 'Alkusivun nimi';
+$lang['title'] = 'Wikin nimi';
+$lang['template'] = 'Sivumalli';
+$lang['license'] = 'Millä lisenssillä sisältö pitäisi julkaista?';
+$lang['fullpath'] = 'Näytä sivun koko polku sivun alareunassa';
+$lang['recent'] = 'Viime muutokset';
+$lang['breadcrumbs'] = 'Leivänmurujen määrä';
+$lang['youarehere'] = 'Hierarkkiset leivänmurut';
+$lang['typography'] = 'Tee typografiset korvaukset';
+$lang['htmlok'] = 'Salli upotettu HTML';
+$lang['phpok'] = 'Salli upotettu PHP';
+$lang['dformat'] = 'Päivämäärän muoto (katso PHPn <a href="http://www.php.net/strftime">strftime</a> funktiota)';
+$lang['signature'] = 'Allekirjoitus';
+$lang['toptoclevel'] = 'Ylätason sisällysluettelo';
+$lang['tocminheads'] = 'Pienin otsikkorivien määrä, jotta sisällysluettelo tehdään';
+$lang['maxtoclevel'] = 'Sisällysluettelon suurin syvyys';
+$lang['maxseclevel'] = 'Kappale-editoinnin suurin syvyys.';
+$lang['camelcase'] = 'Käytä CamelCase linkkejä';
+$lang['deaccent'] = 'Siivoa sivun nimet';
+$lang['useheading'] = 'Käytä ensimmäistä otsikkoriviä sivun nimenä.';
+$lang['refcheck'] = 'Mediaviitteen tarkistus';
+$lang['refshow'] = 'Montako mediaviitettä näytetään';
+$lang['allowdebug'] = 'Salli debuggaus <b>pois, jos ei tarvita!</b>';
+$lang['usewordblock'] = 'Estä spam sanalistan avulla';
+$lang['indexdelay'] = 'Aikaraja indeksoinnille (sek)';
+$lang['relnofollow'] = 'Käytä rel="nofollow" ulkoisille linkeille';
+$lang['mailguard'] = 'Häivytä email osoite';
+$lang['iexssprotect'] = 'Tarkista lähetetyt tiedostot pahojen javascript- ja html-koodien varalta';
+$lang['showuseras'] = 'Mitä näytetään, kun kerrotaan viimeisen editoijan tiedot';
+$lang['useacl'] = 'Käytä käyttöoikeuksien hallintaa';
+$lang['autopasswd'] = 'Luo salasana automaattisesti';
+$lang['authtype'] = 'Autentikointijärjestelmä';
+$lang['passcrypt'] = 'Salasanan suojausmenetelmä';
+$lang['defaultgroup'] = 'Oletusryhmä';
+$lang['superuser'] = 'Pääkäyttäjä. Ryhmä tai käyttäjä, jolla on täysi oikeus kaikkiin sivuihin ja toimintoihin käyttöoikeuksista huolimatta';
+$lang['manager'] = 'Ylläpitäjä. Ryhmä tai käyttäjä, jolla on pääsy joihinkin ylläpitotoimintoihin';
+$lang['profileconfirm'] = 'Vahvista profiilin päivitys salasanan avulla';
+$lang['disableactions'] = 'Estä DokuWiki-toimintojen käyttö';
+$lang['disableactions_check'] = 'Tarkista';
+$lang['disableactions_subscription'] = 'Tilaa/Peruuta tilaus';
+$lang['disableactions_wikicode'] = 'Näytä lähdekoodi/Vie raakana';
+$lang['disableactions_other'] = 'Muut toiminnot (pilkulla erotettuna)';
+$lang['sneaky_index'] = 'Oletuksena DokuWiki näyttää kaikki nimiavaruudet index-näkymäsä. Tämä asetus piilottaa ne, joihin käyttäjällä ei ole lukuoikeuksia. Tämä voi piilottaa joitakin sallittuja alinimiavaruuksia. Tästä johtuen index-näkymä voi olla käyttökelvoton joillakin ACL-asetuksilla';
+$lang['auth_security_timeout'] = 'Autentikoinnin aikakatkaisu (sekunteja)';
+$lang['securecookie'] = 'Lähetetäänkö HTTPS:n kautta asetetut evästetiedot HTTPS-yhteydellä? Kytke pois, jos vain wikisi kirjautuminen on suojattu SSL:n avulla, mutta muuten wikiä käytetään ilman suojausta.';
+$lang['xmlrpc'] = 'Käytä/poista XML-RPC liityntää';
+$lang['xmlrpcuser'] = 'Estä XML-RPC:n käyttö pilkulla erotetun listan ryhmille tai käyttäjille. Jätä tyhjäksi salliaksesi käyttö kaikille.';
+$lang['updatecheck'] = 'Tarkista päivityksiä ja turvavaroituksia? Tätä varten DokuWikin pitää ottaa yhteys update.dokuwiki.orgiin.';
+$lang['userewrite'] = 'Käytä siivottuja URLeja';
+$lang['useslash'] = 'Käytä kauttaviivaa nimiavaruuksien erottimena URL-osoitteissa';
+$lang['usedraft'] = 'Tallenna vedos muokkaustilassa automaattisesti ';
+$lang['sepchar'] = 'Sivunimen sanaerotin';
+$lang['canonical'] = 'Käytä kanonisoituja URLeja';
+$lang['fnencode'] = 'Muita kuin ASCII merkkejä sisältävien tiedostonimien koodaustapa.';
+$lang['autoplural'] = 'Etsi monikkomuotoja linkeistä';
+$lang['compression'] = 'Attic-tiedostojen pakkausmenetelmä';
+$lang['cachetime'] = 'Välimuisti-tiedostojen maksimi-ikä (sek)';
+$lang['locktime'] = 'Lukitustiedostojen maksimi-ikä (sek)';
+$lang['fetchsize'] = 'Suurin koko (bytejä), jonka fetch.php voi ladata ulkopuolisesta lähteestä';
+$lang['notify'] = 'Lähetä muutosilmoitukset tähän osoitteeseen';
+$lang['registernotify'] = 'Lähetä ilmoitus uusista rekisteröitymisistä tähän osoitteeseen';
+$lang['mailfrom'] = 'Sähköpostiosoite automaattisia postituksia varten';
+$lang['mailprefix'] = 'Etuliite automaattisesti lähetettyihin dähköposteihin';
+$lang['gzip_output'] = 'Käytä gzip "Content-Encoding"-otsaketta xhtml-tiedostojen lähettämiseen';
+$lang['gdlib'] = 'GD Lib versio';
+$lang['im_convert'] = 'ImageMagick-muunnostyökalun polku';
+$lang['jpg_quality'] = 'JPG pakkauslaatu (0-100)';
+$lang['subscribers'] = 'Salli tuki sivujen tilaamiselle';
+$lang['subscribe_time'] = 'Aika jonka jälkeen tilauslinkit ja yhteenveto lähetetään (sek). Tämän pitäisi olla pienempi, kuin recent_days aika.';
+$lang['compress'] = 'Pakkaa CSS ja javascript';
+$lang['cssdatauri'] = 'Maksimikoko tavuina jossa kuvat joihin viitataan CSS-tiedostoista olisi sisällytettynä suoraan tyylitiedostoon jotta HTTP-kyselyjen kaistaa saataisiin kutistettua. Tämä tekniikka ei toimi IE versiossa aikasempi kuin 8! <code>400:sta</code> <code>600:aan</code> tavua on hyvä arvo. Aseta <code>0</code> kytkeäksesi ominaisuuden pois.';
+$lang['hidepages'] = 'Piilota seuraavat sivut (säännönmukainen lauseke)';
+$lang['send404'] = 'Lähetä "HTTP 404/Page Not Found" puuttuvista sivuista';
+$lang['sitemap'] = 'Luo Google sitemap (päiviä)';
+$lang['broken_iua'] = 'Onko "ignore_user_abort" toiminto rikki järjestelmässäsi? Tämä voi aiheuttaa toimimattoman index-näkymän.
+IIS+PHP/CGI on tunnetusti rikki. Katso <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> lisätietoja varten.';
+$lang['xsendfile'] = 'Käytä X-Sendfile otsikkoa, kun web-palvelin lähettää staattisia tiedostoja? Palvelimesi pitää tukea tätä.';
+$lang['renderer_xhtml'] = 'Renderöinti, jota käytetään wikin pääasialliseen (xhtml) tulostukseen';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (liitännäinen)';
+$lang['rememberme'] = 'Salli pysyvät kirjautumis-cookiet (muista minut)';
+$lang['rss_type'] = 'XML-syötteen tyyppi';
+$lang['rss_linkto'] = 'XML-syöte kytkeytyy';
+$lang['rss_content'] = 'Mitä XML-syöte näyttää?';
+$lang['rss_update'] = 'XML-syötteen päivitystahti (sek)';
+$lang['recent_days'] = 'Montako edellistä muutosta säilytetään (päiviä)';
+$lang['rss_show_summary'] = 'XML-syöte näyttää yhteenvedon otsikossa';
+$lang['target____wiki'] = 'Kohdeikkuna sisäisissä linkeissä';
+$lang['target____interwiki'] = 'Kohdeikkuna interwiki-linkeissä';
+$lang['target____extern'] = 'Kohdeikkuna ulkoisissa linkeissä';
+$lang['target____media'] = 'Kohdeikkuna media-linkeissä';
+$lang['target____windows'] = 'Kohdeikkuna Windows-linkeissä';
+$lang['proxy____host'] = 'Proxy-palvelimen nimi';
+$lang['proxy____port'] = 'Proxy portti';
+$lang['proxy____user'] = 'Proxy käyttäjän nimi';
+$lang['proxy____pass'] = 'Proxy salasana';
+$lang['proxy____ssl'] = 'Käytä ssl-yhteyttä kytkeytyäksesi proxy-palvelimeen';
+$lang['proxy____except'] = 'Säännönmukainen lause, URLiin, jolle proxy ohitetaan.';
+$lang['safemodehack'] = 'Käytä safemode kiertoa';
+$lang['ftp____host'] = 'FTP-palvelin safemode kiertoa varten';
+$lang['ftp____port'] = 'FTP-portti safemode kiertoa varten';
+$lang['ftp____user'] = 'FTP-käyttäjä safemode kiertoa varten';
+$lang['ftp____pass'] = 'FTP-salasana safemode kiertoa varten';
+$lang['ftp____root'] = 'FTP-juurihakemisto safemode kiertoa varten';
+$lang['license_o_'] = 'ei mitään valittuna';
+$lang['typography_o_0'] = 'ei mitään';
+$lang['typography_o_1'] = 'ilman yksinkertaisia lainausmerkkejä';
+$lang['typography_o_2'] = 'myös yksinkertaiset lainausmerkit (ei aina toimi)';
+$lang['userewrite_o_0'] = 'ei mitään';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWikin sisäinen';
+$lang['deaccent_o_0'] = 'pois';
+$lang['deaccent_o_1'] = 'Poista aksenttimerkit';
+$lang['deaccent_o_2'] = 'translitteroi';
+$lang['gdlib_o_0'] = 'GD Lib ei ole saatavilla';
+$lang['gdlib_o_1'] = 'Versio 1.x';
+$lang['gdlib_o_2'] = 'Automaattitunnistus';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Yhteenveto';
+$lang['rss_content_o_diff'] = 'Yhdistetty erot';
+$lang['rss_content_o_htmldiff'] = 'HTML-muotoiltu eroavuuslista';
+$lang['rss_content_o_html'] = 'Täysi HTML-sivu';
+$lang['rss_linkto_o_diff'] = 'erot-näkymä';
+$lang['rss_linkto_o_page'] = 'muutettu sivu';
+$lang['rss_linkto_o_rev'] = 'versiolista';
+$lang['rss_linkto_o_current'] = 'nykyinen sivu';
+$lang['compression_o_0'] = 'ei mitään';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'älä käytä';
+$lang['xsendfile_o_1'] = 'Oma lighttpd otsikko (ennen 1.5 julkaisua)';
+$lang['xsendfile_o_2'] = 'Standardi X-sendfile header';
+$lang['xsendfile_o_3'] = 'Oma Nginx X-Accel-Redirect header';
+$lang['showuseras_o_loginname'] = 'Kirjautumisnimi';
+$lang['showuseras_o_username'] = 'Käyttäjän koko nimi';
+$lang['showuseras_o_email'] = 'Käyttäjän sähköpostiosoite (sumennettu mailguard-asetusten mukaisesti)';
+$lang['showuseras_o_email_link'] = 'Käyttäjän sähköpostiosoite mailto: linkkinä';
+$lang['useheading_o_0'] = 'Ei koskaan';
+$lang['useheading_o_navigation'] = 'Vain Navigointi';
+$lang['useheading_o_content'] = 'Vain Wiki-sisältö';
+$lang['useheading_o_1'] = 'Aina';
+$lang['readdircache'] = 'Maksimiaika readdir cachelle (sek)';
diff --git a/lib/plugins/config/lang/fr/intro.txt b/lib/plugins/config/lang/fr/intro.txt
new file mode 100644
index 000000000..2a59b34d1
--- /dev/null
+++ b/lib/plugins/config/lang/fr/intro.txt
@@ -0,0 +1,9 @@
+====== Gestionnaire de configuration ======
+
+Utilisez cette page pour contrôler les paramètres de votre installation de DokuWiki. Pour de l'aide sur chaque paramètre, reportez vous à [[doku>fr:config]]. Pour d'autres détails concernant ce module, reportez vous à [[doku>fr:plugin:config]].
+
+Les paramètres affichés sur un fond rouge sont protégés et ne peuvent être modifiés avec ce module. Les paramètres affichés sur un fond bleu sont les valeurs par défaut et les valeurs affectées à votre installation sont affichées sur un fond blanc. Les paramètres bleus et blancs peuvent être modifiés.
+
+N'oubliez pas d'utiliser le bouton **Enregistrer** avant de quitter cette page, sinon vos modifications seront perdues.
+
+
diff --git a/lib/plugins/config/lang/fr/lang.php b/lib/plugins/config/lang/fr/lang.php
new file mode 100644
index 000000000..8dcd21032
--- /dev/null
+++ b/lib/plugins/config/lang/fr/lang.php
@@ -0,0 +1,201 @@
+<?php
+/**
+ * french language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Guy Brand <gb@unistra.fr>
+ * @author Delassaux Julien <julien@delassaux.fr>
+ * @author Maurice A. LeBlanc <leblancma@cooptel.qc.ca>
+ * @author stephane.gully@gmail.com
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author olivier duperray <duperray.olivier@laposte.net>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author Philippe Bajoit <philippe.bajoit@gmail.com>
+ * @author Florian Gaub <floriang@floriang.net>
+ * @author Samuel Dorsaz samuel.dorsaz@novelion.net
+ * @author Johan Guilbaud <guilbaud.johan@gmail.com>
+ * @author schplurtz@laposte.net
+ * @author skimpax@gmail.com
+ */
+$lang['menu'] = 'Paramètres de configuration';
+$lang['error'] = 'Paramètres non modifiés en raison d\'une valeur non valide, vérifiez vos réglages et réessayez. <br />Les valeurs erronées sont entourées d\'une bordure rouge.';
+$lang['updated'] = 'Paramètres mis à jour avec succès.';
+$lang['nochoice'] = '(aucun autre choix possible)';
+$lang['locked'] = 'Le fichier des paramètres ne peut être modifié, si ceci n\'est pas intentionnel, <br /> vérifiez que le nom et les droits du fichier sont corrects.';
+$lang['danger'] = 'Danger : Modifier cette option pourrait rendre inaccessible votre wiki et son menu de configuration.';
+$lang['warning'] = 'Attention : Modifier cette option pourrait engendrer un comportement indésirable.';
+$lang['security'] = 'Avertissement de sécurité : Modifier cette option pourrait induire un risque de sécurité.';
+$lang['_configuration_manager'] = 'Gestionnaire de configuration';
+$lang['_header_dokuwiki'] = 'Paramètres de DokuWiki';
+$lang['_header_plugin'] = 'Paramètres des modules externes';
+$lang['_header_template'] = 'Paramètres des modèles';
+$lang['_header_undefined'] = 'Paramètres indéfinis';
+$lang['_basic'] = 'Paramètres de base';
+$lang['_display'] = 'Paramètres d\'affichage';
+$lang['_authentication'] = 'Paramètres d\'authentification';
+$lang['_anti_spam'] = 'Paramètres anti-spam';
+$lang['_editing'] = 'Paramètres d\'édition';
+$lang['_links'] = 'Paramètres des liens';
+$lang['_media'] = 'Paramètres média';
+$lang['_advanced'] = 'Paramètres avancés';
+$lang['_network'] = 'Paramètres réseaux';
+$lang['_plugin_sufix'] = 'Paramètres de module';
+$lang['_template_sufix'] = 'Paramètres de modèle';
+$lang['_msg_setting_undefined'] = 'Pas de métadonnée de paramètres.';
+$lang['_msg_setting_no_class'] = 'Pas de classe de paramètres.';
+$lang['_msg_setting_no_default'] = 'Pas de valeur par défaut.';
+$lang['fmode'] = 'Mode de création des fichiers';
+$lang['dmode'] = 'Mode de création des répertoires';
+$lang['lang'] = 'Langue';
+$lang['basedir'] = 'Répertoire de base (ex. : <code>/dokuwiki/</code>). Laisser vide pour une détection automatique.';
+$lang['baseurl'] = 'URL de base. Laisser vide pour une détection automatique.';
+$lang['savedir'] = 'Répertoire de stockage';
+$lang['cookiedir'] = 'Chemin des cookies. Laissez vide pour utiliser l\'URL de base.';
+$lang['start'] = 'Nom de la page d\'accueil';
+$lang['title'] = 'Titre du wiki';
+$lang['template'] = 'Modèle';
+$lang['license'] = 'Sous quelle licence doit être placé le contenu ?';
+$lang['fullpath'] = 'Utiliser le chemin complet dans le pied de page';
+$lang['recent'] = 'Nombre de derniers changements à afficher';
+$lang['breadcrumbs'] = 'Nombre de traces à afficher';
+$lang['youarehere'] = 'Traces hiérarchiques';
+$lang['typography'] = 'Effectuer des améliorations typographiques';
+$lang['htmlok'] = 'Permettre HTML dans les pages';
+$lang['phpok'] = 'Permettre PHP dans les pages';
+$lang['dformat'] = 'Format de date (cf. fonction <a href="http://fr.php.net/strftime">strftime</a> de PHP)';
+$lang['signature'] = 'Signature';
+$lang['toptoclevel'] = 'Niveau le plus haut à afficher dans la table des matières';
+$lang['tocminheads'] = 'Nombre minimum de titres pour qu\'une table des matières soit construite';
+$lang['maxtoclevel'] = 'Niveau maximum pour figurer dans la table des matières';
+$lang['maxseclevel'] = 'Niveau maximum pour modifier des sections';
+$lang['camelcase'] = 'Utiliser CamelCase pour les liens';
+$lang['deaccent'] = 'Retirer les accents dans les noms de pages';
+$lang['useheading'] = 'Utiliser le titre de premier niveau';
+$lang['refcheck'] = 'Vérifier les références de média';
+$lang['refshow'] = 'Nombre de références de média à montrer';
+$lang['allowdebug'] = 'Debug (<strong>Ne l\'activez que si vous en avez besoin !</strong>)';
+$lang['mediarevisions'] = 'Activer les révisions (gestion de versions) des médias';
+$lang['usewordblock'] = 'Bloquer le spam selon les mots utilisés';
+$lang['indexdelay'] = 'Délai avant l\'indexation (en secondes)';
+$lang['relnofollow'] = 'Utiliser rel="nofollow" sur les liens extérieurs';
+$lang['mailguard'] = 'Brouiller les adresses de courriel';
+$lang['iexssprotect'] = 'Vérifier la présence de code JavaScript ou HTML malveillant dans les fichiers envoyés';
+$lang['showuseras'] = 'Qu\'afficher en montrant les utilisateurs qui ont récemment modifié la page';
+$lang['useacl'] = 'Utiliser les listes de contrôle d\'accès (ACL)';
+$lang['autopasswd'] = 'Auto-générer les mots de passe';
+$lang['authtype'] = 'Mécanisme d\'authentification';
+$lang['passcrypt'] = 'Méthode de chiffrement des mots de passe';
+$lang['defaultgroup'] = 'Groupe par défaut';
+$lang['superuser'] = 'Superuser - groupe, utilisateur ou liste séparée par des virgules user1,@group1,user2 ayant un accès complet à toutes les pages quelque soit le paramétrage des ACL';
+$lang['manager'] = 'Manager - groupe, utilisateur ou liste séparée par des virgules user1,@group1,user2 ayant accès à certaines fonctions de gestion';
+$lang['profileconfirm'] = 'Confirmer par mot de passe les modifications de profil';
+$lang['disableactions'] = 'Actions à désactiver dans DokuWiki';
+$lang['disableactions_check'] = 'Vérifier';
+$lang['disableactions_subscription'] = 'Abonnement aux pages';
+$lang['disableactions_wikicode'] = 'Afficher le texte source';
+$lang['disableactions_other'] = 'Autres actions (séparées par des virgules)';
+$lang['sneaky_index'] = 'Par défaut, DokuWiki affichera toutes les catégories dans la vue par index. Activer cette option permet de cacher celles pour lesquelles l\'utilisateur n\'a pas la permission de lecture. Il peut en résulter le masquage de sous-catégories accessibles. Ceci peut rendre l\'index inutilisable avec certaines ACL.';
+$lang['auth_security_timeout'] = 'Délai d\'expiration de sécurité (secondes)';
+$lang['securecookie'] = 'Les cookies mis via HTTPS doivent-ils n\'être envoyé par le navigateur que via HTTPS ? Ne désactivez cette option que si la connexion à votre wiki est sécurisée avec SSL mais que la navigation sur le wiki n\'est pas sécurisée.';
+$lang['xmlrpc'] = 'Activer l\'interface XML-RPC.';
+$lang['xmlrpcuser'] = 'Restreindre l\'accès à XML-RPC aux groupes et utilisateurs indiqués ici. Laisser vide afin que tout le monde y ait accès.';
+$lang['updatecheck'] = 'Vérifier les mises à jour ? DokuWiki doit pouvoir contacter update.dokuwiki.org.';
+$lang['userewrite'] = 'URL esthétiques';
+$lang['useslash'] = 'Utiliser « / » comme séparateur de catégorie dans les URL';
+$lang['usedraft'] = 'Enregistrer automatiquement un brouillon pendant l\'édition';
+$lang['sepchar'] = 'Séparateur de mots dans les noms de page';
+$lang['canonical'] = 'Utiliser des URL canoniques';
+$lang['fnencode'] = 'Méthode pour l\'encodage des fichiers non-ASCII';
+$lang['autoplural'] = 'Rechercher les formes plurielles dans les liens';
+$lang['compression'] = 'Méthode de compression pour les fichiers dans attic';
+$lang['cachetime'] = 'Âge maximum d\'un fichier en cache (en secondes)';
+$lang['locktime'] = 'Âge maximum des fichiers verrous (en secondes)';
+$lang['fetchsize'] = 'Taille maximale (en octets) du fichier que fetch.php peut télécharger';
+$lang['notify'] = 'Notifier les modifications à cette adresse de courriel';
+$lang['registernotify'] = 'Envoyer un courriel annonçant les nouveaux utilisateurs enregistrés à cette adresse';
+$lang['mailfrom'] = 'Expéditeur des notifications par courriel du wiki';
+$lang['mailprefix'] = 'Préfixe à utiliser dans les objets des courriels automatiques';
+$lang['gzip_output'] = 'Utiliser Content-Encoding gzip pour XHTML';
+$lang['gdlib'] = 'Version de GD Lib';
+$lang['im_convert'] = 'Chemin vers l\'outil de conversion d\'ImageMagick';
+$lang['jpg_quality'] = 'Qualité de la compression JPEG (0-100)';
+$lang['subscribers'] = 'Activer l\'abonnement aux pages';
+$lang['subscribe_time'] = 'Délai après lequel les listes d\'abonnement et résumés sont envoyés (en secondes). Devrait être plus petit que le délai précisé dans recent_days.';
+$lang['compress'] = 'Compresser CSS et JavaScript';
+$lang['cssdatauri'] = 'Taille maximale en octets pour inclure dans les feuilles de styles CSS, les images qui y sont référencées. Cette technique minimise les requêtes HTTP. Pour IE, ceci ne fonctionne qu\'à partir de la version 8 ! Valeurs correctes entre <code>400</code> et <code>600</code>. <code>0</code> pour désactiver.';
+$lang['hidepages'] = 'Cacher les pages correspondant à (expression régulière)';
+$lang['send404'] = 'Renvoyer "HTTP 404/Page Non Trouvée" pour les pages introuvables';
+$lang['sitemap'] = 'Fréquence de génération une carte Google du site (en jours)';
+$lang['broken_iua'] = 'La fonction ignore_user_abort est-elle opérationnelle sur votre système ? Ceci peut empêcher le fonctionnement de l\'index de recherche. IIS+PHP/
+CGI dysfonctionne. Voir le <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">bug 852</a> pour plus d\'info.';
+$lang['xsendfile'] = 'Utiliser l\'en-tête X-Sendfile pour permettre au serveur Web de délivrer des fichiers statiques ? Votre serveur Web doit supporter cette fonctionnalité.';
+$lang['renderer_xhtml'] = 'Moteur de rendu du format de sortie principal (XHTML)';
+$lang['renderer__core'] = '%s (cœur de dokuwiki)';
+$lang['renderer__plugin'] = '%s (module externe)';
+$lang['rememberme'] = 'Permettre de conserver de manière permanente les cookies de connexion (mémoriser)';
+$lang['rss_type'] = 'Type de flux RSS';
+$lang['rss_linkto'] = 'Lien du flux RSS vers';
+$lang['rss_content'] = 'Quel contenu afficher dans le flux RSS ?';
+$lang['rss_update'] = 'Fréquence de mise à jour du flux RSS (en secondes)';
+$lang['recent_days'] = 'Signaler les pages modifiées depuis (en jours)';
+$lang['rss_show_summary'] = 'Le flux XML affiche le résumé dans le titre';
+$lang['target____wiki'] = 'Cible pour liens internes';
+$lang['target____interwiki'] = 'Cible pour liens interwiki';
+$lang['target____extern'] = 'Cible pour liens externes';
+$lang['target____media'] = 'Cible pour liens média';
+$lang['target____windows'] = 'Cible pour liens vers partages Windows';
+$lang['proxy____host'] = 'Proxy - Serveur hôte';
+$lang['proxy____port'] = 'Proxy - Numéro de port';
+$lang['proxy____user'] = 'Proxy - Identifiant';
+$lang['proxy____pass'] = 'Proxy - Mot de passe';
+$lang['proxy____ssl'] = 'Proxy - Utilisation de SSL';
+$lang['proxy____except'] = 'Expression régulière de test des URLs pour lesquelles le proxy ne devrait pas être utilisé.';
+$lang['safemodehack'] = 'Activer l\'option Mode sans échec';
+$lang['ftp____host'] = 'FTP - Serveur hôte pour Mode sans échec';
+$lang['ftp____port'] = 'FTP - Numéro de port pour Mode sans échec';
+$lang['ftp____user'] = 'FTP - Identifiant pour Mode sans échec';
+$lang['ftp____pass'] = 'FTP - Mot de passe pour Mode sans échec';
+$lang['ftp____root'] = 'FTP - Répertoire racine pour Mode sans échec';
+$lang['license_o_'] = 'Aucune choisie';
+$lang['typography_o_0'] = 'aucun';
+$lang['typography_o_1'] = 'guillemets uniquement';
+$lang['typography_o_2'] = 'tout signe typographique (peut ne pas fonctionner)';
+$lang['userewrite_o_0'] = 'aucun';
+$lang['userewrite_o_1'] = 'Fichier .htaccess';
+$lang['userewrite_o_2'] = 'Interne à DokuWiki';
+$lang['deaccent_o_0'] = 'off';
+$lang['deaccent_o_1'] = 'supprimer les accents';
+$lang['deaccent_o_2'] = 'convertir en roman';
+$lang['gdlib_o_0'] = 'Librairie GD non disponible';
+$lang['gdlib_o_1'] = 'version 1.x';
+$lang['gdlib_o_2'] = 'auto-détectée';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Résumé';
+$lang['rss_content_o_diff'] = 'Diff. unifié';
+$lang['rss_content_o_htmldiff'] = 'Diff. formaté en table HTML';
+$lang['rss_content_o_html'] = 'page complète au format HTML';
+$lang['rss_linkto_o_diff'] = 'liste des différences';
+$lang['rss_linkto_o_page'] = 'page révisée';
+$lang['rss_linkto_o_rev'] = 'liste des révisions';
+$lang['rss_linkto_o_current'] = 'page actuelle';
+$lang['compression_o_0'] = 'aucune';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ne pas utiliser';
+$lang['xsendfile_o_1'] = 'Entête propriétaire lighttpd (avant la version 1.5)';
+$lang['xsendfile_o_2'] = 'Entête standard X-Sendfile';
+$lang['xsendfile_o_3'] = 'En-tête propriétaire Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Identifiant de l\'utilisateur';
+$lang['showuseras_o_username'] = 'Nom de l\'utilisateur';
+$lang['showuseras_o_email'] = 'Courriel de l\'utilisateur (brouillé suivant les paramètres de brouillage sélectionnés)';
+$lang['showuseras_o_email_link'] = 'Courriel de l\'utilisateur en tant que lien mailto:';
+$lang['useheading_o_0'] = 'Jamais';
+$lang['useheading_o_navigation'] = 'Navigation seulement';
+$lang['useheading_o_content'] = 'Contenu du wiki seulement';
+$lang['useheading_o_1'] = 'Toujours';
+$lang['readdircache'] = 'Durée de vie maximale du cache pour readdir (sec)';
diff --git a/lib/plugins/config/lang/gl/intro.txt b/lib/plugins/config/lang/gl/intro.txt
new file mode 100644
index 000000000..cafe28e13
--- /dev/null
+++ b/lib/plugins/config/lang/gl/intro.txt
@@ -0,0 +1,7 @@
+====== Xestor de Configuración ======
+
+Usa esta páxina para controlares a configuración da túa instalación do Dokuwiki. Para atopares axuda verbo de cada opción da configuración vai a [[doku>config]]. Para obteres pormenores desta extensión bota un ollo a [[doku>plugin:config]].
+
+As opcións que amosan un fondo de cor vermella clara están protexidas e non poden ser alteradas con esta extensión. As opcións que amosan un fondo de cor azul son valores predeterminados e as opcións que teñen fondo branco foron configuradas de xeito local para esta instalación en concreto. Ámbalas dúas, as opcións azuis e brancas, poden ser alteradas.
+
+Lembra premer no boton **GARDAR** denantes de saíres desta páxina ou, en caso contrario, os teus trocos perderanse.
diff --git a/lib/plugins/config/lang/gl/lang.php b/lib/plugins/config/lang/gl/lang.php
new file mode 100644
index 000000000..da40b44e6
--- /dev/null
+++ b/lib/plugins/config/lang/gl/lang.php
@@ -0,0 +1,188 @@
+<?php
+/**
+ * Galicianlanguage file
+ *
+ * @author Medúlio <medulio@ciberirmandade.org>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ */
+$lang['menu'] = 'Opcións de Configuración';
+$lang['error'] = 'Configuración non actualizada debido a un valor inválido, por favor revisa os teus trocos e volta envialos de novo.
+<br />O(s) valor(es) incorrecto(s) amosanse cinguidos por un borde vermello.';
+$lang['updated'] = 'Configuración actualizada correctamente.';
+$lang['nochoice'] = '(non hai outras escollas dispoñibles)';
+$lang['locked'] = 'Non se puido actualizar o arquivo de configuración, se non ocorre como debería ser, <br />
+asegúrate de que o nome do arquivo de configuración local e os permisos son correctos.';
+$lang['danger'] = 'Perigo: mudando esta opción podes facer inaccesíbeis o teu wiki e máis o menú de configuración.';
+$lang['warning'] = 'Ollo: mudando esta opción poden aparecer comportamentos do aplicativo non agardados.';
+$lang['security'] = 'Aviso de seguranza: mudando esta opción poden aparecer riscos de seguranza.';
+$lang['_configuration_manager'] = 'Xestor de Configuración';
+$lang['_header_dokuwiki'] = 'Configuración do DokuWiki';
+$lang['_header_plugin'] = 'Configuración de Extensións';
+$lang['_header_template'] = 'Configuración de Sobreplanta';
+$lang['_header_undefined'] = 'Configuración Indefinida';
+$lang['_basic'] = 'Configuración Básica';
+$lang['_display'] = 'Configuración de Visualización';
+$lang['_authentication'] = 'Configuración de Autenticación';
+$lang['_anti_spam'] = 'Configuración de Anti-Correo-lixo';
+$lang['_editing'] = 'Configuración de Edición';
+$lang['_links'] = 'Configuración de Ligazóns';
+$lang['_media'] = 'Configuración de Media';
+$lang['_advanced'] = 'Configuración Avanzada';
+$lang['_network'] = 'Configuración de Rede';
+$lang['_plugin_sufix'] = 'Configuración de Extensións';
+$lang['_template_sufix'] = 'Configuración de Sobreplanta';
+$lang['_msg_setting_undefined'] = 'Non hai configuración de metadatos.';
+$lang['_msg_setting_no_class'] = 'Non hai configuración de clase.';
+$lang['_msg_setting_no_default'] = 'Non hai valor predeterminado.';
+$lang['fmode'] = 'Modo de creación de arquivos';
+$lang['dmode'] = 'Modo de creación de directorios';
+$lang['lang'] = 'Idioma';
+$lang['basedir'] = 'Directorio base';
+$lang['baseurl'] = 'URL base';
+$lang['savedir'] = 'Directorio no que se gardarán os datos';
+$lang['cookiedir'] = 'Ruta das cookies. Deixar en blanco para usar a url de base.';
+$lang['start'] = 'Nome da páxina inicial';
+$lang['title'] = 'Título do Wiki';
+$lang['template'] = 'Sobreplanta';
+$lang['license'] = 'Baixo de que licenza será ceibado o teu contido?';
+$lang['fullpath'] = 'Amosar a ruta completa das páxinas no pé das mesmas';
+$lang['recent'] = 'Trocos recentes';
+$lang['breadcrumbs'] = 'Número de niveis da estrutura de navegación';
+$lang['youarehere'] = 'Niveis xerárquicos da estrutura de navegación';
+$lang['typography'] = 'Facer substitucións tipográficas';
+$lang['htmlok'] = 'Permitir a inserción de HTML';
+$lang['phpok'] = 'Permitir a inserción de PHP';
+$lang['dformat'] = 'Formato de Data (bótalle un ollo á función <a href="http://www.php.net/strftime">strftime</a> do PHP)';
+$lang['signature'] = 'Sinatura';
+$lang['toptoclevel'] = 'Nivel superior para a táboa de contidos';
+$lang['tocminheads'] = 'Cantidade mínima de liñas de cabeceira que determinará se a TDC vai ser xerada';
+$lang['maxtoclevel'] = 'Nivel máximo para a táboa de contidos';
+$lang['maxseclevel'] = 'Nivel máximo de edición da sección';
+$lang['camelcase'] = 'Utilizar CamelCase para as ligazóns';
+$lang['deaccent'] = 'Limpar nomes de páxina';
+$lang['useheading'] = 'Utilizar a primeira cabeceira para os nomes de páxina';
+$lang['refcheck'] = 'Comprobar a referencia media';
+$lang['refshow'] = 'Número de referencias media a amosar';
+$lang['allowdebug'] = 'Permitir o depurado <b>desactívao se non o precisas!</b>';
+$lang['mediarevisions'] = 'Habilitar revisións dos arquivos-media?';
+$lang['usewordblock'] = 'Bloquear correo-lixo segundo unha lista de verbas';
+$lang['indexdelay'] = 'Retardo denantes de indexar (seg)';
+$lang['relnofollow'] = 'Utilizar rel="nofollow" nas ligazóns externas';
+$lang['mailguard'] = 'Ofuscar enderezos de correo-e';
+$lang['iexssprotect'] = 'Comprobar arquivos subidos na procura de posíbel código JavaScript ou HTML malicioso';
+$lang['showuseras'] = 'Que amosar cando se informe do usuario que fixo a última modificación dunha páxina';
+$lang['useacl'] = 'Utilizar lista de control de acceso';
+$lang['autopasswd'] = 'Xerar contrasinais automaticamente';
+$lang['authtype'] = 'Backend de autenticación';
+$lang['passcrypt'] = 'Método de encriptado do contrasinal';
+$lang['defaultgroup'] = 'Grupo por defecto';
+$lang['superuser'] = 'Super-usuario - un grupo ou usuario con acceso completo a todas as páxinas e funcións independentemente da configuración da ACL';
+$lang['manager'] = 'Xestor - un grupo ou usuario con acceso a certas funcións de xestión';
+$lang['profileconfirm'] = 'Confirmar trocos de perfil mediante contrasinal';
+$lang['disableactions'] = 'Desactivar accións do DokuWiki';
+$lang['disableactions_check'] = 'Comprobar';
+$lang['disableactions_subscription'] = 'Subscribir/Desubscribir';
+$lang['disableactions_wikicode'] = 'Ver fonte/Exportar Datos Raw';
+$lang['disableactions_other'] = 'Outras accións (separadas por comas)';
+$lang['sneaky_index'] = 'O DokuWiki amosará por defecto todos os nomes de espazo na vista de índice. Se activas isto agocharanse aqueles onde o usuario non teña permisos de lectura.';
+$lang['auth_security_timeout'] = 'Tempo Límite de Seguridade de Autenticación (segundos)';
+$lang['securecookie'] = 'Deben enviarse só vía HTTPS polo navegador as cookies configuradas vía HTTPS? Desactiva esta opción cando só o inicio de sesión do teu wiki estea asegurado con SSL pero a navegación do mesmo se faga de xeito inseguro.';
+$lang['xmlrpc'] = 'Activar/Desactivar interface XML-RPC';
+$lang['xmlrpcuser'] = 'Restrinxir o acceso mediante XML-RPC á lista separada por comas dos grupos e/ou usuarios proporcionados aquí. Déixao baleiro para darlle acceso a todas as persoas.';
+$lang['updatecheck'] = 'Comprobar se hai actualizacións e avisos de seguridade? O DokuWiki precisa contactar con update.dokuwiki.org para executar esta característica.';
+$lang['userewrite'] = 'Utilizar URLs amigábeis';
+$lang['useslash'] = 'Utilizar a barra inclinada (/) como separador de nome de espazo nos URLs';
+$lang['usedraft'] = 'Gardar un borrador automaticamente no tempo da edición';
+$lang['sepchar'] = 'Verba separadora do nome de páxina';
+$lang['canonical'] = 'Utilizar URLs completamente canónicos';
+$lang['fnencode'] = 'Método para codificar os nomes de arquivo non-ASCII.';
+$lang['autoplural'] = 'Comprobar formas plurais nas ligazóns';
+$lang['compression'] = 'Método de compresión para arquivos attic';
+$lang['cachetime'] = 'Tempo máximo para a caché (seg.)';
+$lang['locktime'] = 'Tempo máximo para o bloqueo de arquivos (seg.)';
+$lang['fetchsize'] = 'Tamaño máximo (en bytes) que pode descargar fetch.php dende fontes externas';
+$lang['notify'] = 'Enviar notificacións de trocos a este enderezo de correo-e';
+$lang['registernotify'] = 'Enviar información de novos usuarios rexistrados a este enderezo de correo-e';
+$lang['mailfrom'] = 'Enderezo de correo-e a usar para as mensaxes automáticas';
+$lang['mailprefix'] = 'Prefixo de asunto de correo-e para as mensaxes automáticas';
+$lang['gzip_output'] = 'Utilizar Contido-Codificación gzip para o xhtml';
+$lang['gdlib'] = 'Versión da Libraría GD';
+$lang['im_convert'] = 'Ruta deica a ferramenta de conversión ImageMagick';
+$lang['jpg_quality'] = 'Calidade de compresión dos JPG (0-100)';
+$lang['subscribers'] = 'Activar posibilidade de subscrición á páxina';
+$lang['subscribe_time'] = 'Tempo despois do cal se enviarán os resumos e listas de subscrición (seg.): isto debe ser inferior ao tempo especificado en recent_days.';
+$lang['compress'] = 'Saída compacta de CSS e Javascript';
+$lang['hidepages'] = 'Agochar páxinas que coincidan (expresións regulares)';
+$lang['send404'] = 'Enviar "HTTP 404/Páxina non atopada" para as páxinas inexistentes';
+$lang['sitemap'] = 'Xerar mapa do sitio co Google (días)';
+$lang['broken_iua'] = 'Rachou a función ignore_user_abort no teu sistema? Isto podería causar que o índice de procura non funcione. Coñécese que o IIS+PHP/CGI ráchaa. Bótalle un ollo ao <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> para obter máis información.';
+$lang['xsendfile'] = 'Empregar a cabeceira X-Sendfile para que o servidor web envie arquivos estáticos? O teu servidor web precisa soportar isto.';
+$lang['renderer_xhtml'] = 'Intérprete a empregar para a saída principal (XHTML) do Wiki';
+$lang['renderer__core'] = '%s (núcleo do Dokuwiki)';
+$lang['renderer__plugin'] = '%s (extensión)';
+$lang['rememberme'] = 'Permitir cookies permanentes de inicio de sesión (lembrarme)';
+$lang['rss_type'] = 'Tipo de corrente RSS XML';
+$lang['rss_linkto'] = 'A corrente XML liga para';
+$lang['rss_content'] = 'Que queres amosar nos elementos da corrente XML?';
+$lang['rss_update'] = 'Intervalo de actualización da corrente XML (seg.)';
+$lang['recent_days'] = 'Número de trocos recentes a manter (días)';
+$lang['rss_show_summary'] = 'Amosar sumario no título da corrente XML';
+$lang['target____wiki'] = 'Fiestra de destino para as ligazóns internas';
+$lang['target____interwiki'] = 'Fiestra de destino para as ligazóns interwiki';
+$lang['target____extern'] = 'Fiestra de destino para as ligazóns externas';
+$lang['target____media'] = 'Fiestra de destino para as ligazóns de media';
+$lang['target____windows'] = 'Fiestra de destino para as ligazóns de fiestras';
+$lang['proxy____host'] = 'Nome do servidor Proxy';
+$lang['proxy____port'] = 'Porto do Proxy';
+$lang['proxy____user'] = 'Nome de usuario do Proxy';
+$lang['proxy____pass'] = 'Contrasinal do Proxy';
+$lang['proxy____ssl'] = 'Utilizar ssl para conectar ao Proxy';
+$lang['proxy____except'] = 'Expresión regular para atopar URLs que deban ser omitidas polo Proxy.';
+$lang['safemodehack'] = 'Activar hack de modo seguro (safemode)';
+$lang['ftp____host'] = 'Servidor FTP para o hack de modo seguro (safemode)';
+$lang['ftp____port'] = 'Porto FTP para o hack de modo seguro(safemode)';
+$lang['ftp____user'] = 'Nome de usuario FTP para o hack de modo seguro(safemode)';
+$lang['ftp____pass'] = 'Contrasinal FTP para o hack de modo seguro(safemode)';
+$lang['ftp____root'] = 'Directorio raigaña do FTP para o hack de modo seguro(safemode)';
+$lang['license_o_'] = 'Non se escolleu nada';
+$lang['typography_o_0'] = 'ningunha';
+$lang['typography_o_1'] = 'Só dobres aspas';
+$lang['typography_o_2'] = 'Todas as aspas (pode que non funcione sempre)';
+$lang['userewrite_o_0'] = 'ningún';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Interno do DokuWiki';
+$lang['deaccent_o_0'] = 'desconectado';
+$lang['deaccent_o_1'] = 'Eliminar acentos';
+$lang['deaccent_o_2'] = 'romanizar';
+$lang['gdlib_o_0'] = 'Libraría GD non dispoñíbel';
+$lang['gdlib_o_1'] = 'Versión 1.x';
+$lang['gdlib_o_2'] = 'Detección automática';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Sumario';
+$lang['rss_content_o_diff'] = 'Formato Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'Táboa diff formatada en HTML';
+$lang['rss_content_o_html'] = 'Contido HTML completo da páxina';
+$lang['rss_linkto_o_diff'] = 'vista de diferenzas';
+$lang['rss_linkto_o_page'] = 'a páxina revisada';
+$lang['rss_linkto_o_rev'] = 'listaxe de revisións';
+$lang['rss_linkto_o_current'] = 'a páxina actual';
+$lang['compression_o_0'] = 'ningunha';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'non o empregues';
+$lang['xsendfile_o_1'] = 'Cabeceira lighttpd propietaria (denantes da versión 1.5)';
+$lang['xsendfile_o_2'] = 'Cabeceira X-Sendfile estándar';
+$lang['xsendfile_o_3'] = 'Cabeceira X-Accel-Redirect propia de Nginx';
+$lang['showuseras_o_loginname'] = 'Nome de inicio de sesión';
+$lang['showuseras_o_username'] = 'Nome completo do usuario';
+$lang['showuseras_o_email'] = 'Enderezo de correo-e do usuario (ofuscado segundo a configuración mailguard)';
+$lang['showuseras_o_email_link'] = 'Enderezo de correo-e do usuario como ligazón mailto:';
+$lang['useheading_o_0'] = 'Endexamais';
+$lang['useheading_o_navigation'] = 'Só Navegación';
+$lang['useheading_o_content'] = 'Só Contido do Wiki';
+$lang['useheading_o_1'] = 'Sempre';
+$lang['readdircache'] = 'Edad máxima para o directorio de caché (seg)';
diff --git a/lib/plugins/config/lang/he/intro.txt b/lib/plugins/config/lang/he/intro.txt
new file mode 100644
index 000000000..010c69018
--- /dev/null
+++ b/lib/plugins/config/lang/he/intro.txt
@@ -0,0 +1,9 @@
+====== מנהל תצורה ======
+
+ניתן להשתמש בדף זה לשליטה על הגדרות התקנת ה-Dokuwiki שלך. לעזרה בנוגע להגדרות ספציפיות ניתן לפנות אל [[doku>config]]. למידע נוסף אודות תוסף זה ניתן לפנות אל [[doku>plugin:config]].
+
+הגדרות עם רקע אדום-בהיר מוגנות ואין אפשרות לשנותן עם תוסף זה. הגדרות עם רקע כחול הן בעלות ערך ברירת המחדל והגדרות עם רקע לבן הוגדרו באופן מקומי עבור התקנה זו. ההגדרות בעלות הרקעים הכחול והלבן הן ברות שינוי.
+
+יש לזכור ללחוץ על כפתור ה**שמירה** טרם עזיבת דף זה פן יאבדו השינויים.
+
+
diff --git a/lib/plugins/config/lang/he/lang.php b/lib/plugins/config/lang/he/lang.php
new file mode 100644
index 000000000..e80a1bd7a
--- /dev/null
+++ b/lib/plugins/config/lang/he/lang.php
@@ -0,0 +1,169 @@
+<?php
+/**
+ * hebrew language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author DoK <kamberd@yahoo.com>
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ * @author Moshe Kaplan <mokplan@gmail.com>
+ * @author Yaron Yogev <yaronyogev@gmail.com>
+ * @author Yaron Shahrabani <sh.yaron@gmail.com>
+ */
+$lang['menu'] = 'הגדרות תצורה';
+$lang['error'] = 'ההגדרות לא עודכנו בגלל ערך לא תקף, נא לעיין בשינויים ולשלוח שנית.
+ <br />הערכים שאינם נכונים יסומנו בגבול אדום.';
+$lang['updated'] = 'ההגדרות עודכנו בהצלחה.';
+$lang['nochoice'] = '(אין אפשרויות זמינות נוספות)';
+$lang['locked'] = 'קובץ ההגדרות אינו בר עידכון, אם הדבר אינו מכוון, <br />
+ יש לודא כי קובץ ההגדרות המקומי וההרשאות נכונים.';
+$lang['_configuration_manager'] = 'מנהל תצורה';
+$lang['_header_dokuwiki'] = 'הגדרות DokuWiki';
+$lang['_header_plugin'] = 'הגדרות תוסף';
+$lang['_header_template'] = 'הגדרות תבנית';
+$lang['_header_undefined'] = 'הגדרות שונות';
+$lang['_basic'] = 'הגדרות בסיסיות';
+$lang['_display'] = 'הגדרות תצוגה';
+$lang['_authentication'] = 'הגדרות הזדהות';
+$lang['_anti_spam'] = 'הגדרות נגד דואר זבל';
+$lang['_editing'] = 'הגדרות עריכה';
+$lang['_links'] = 'הגדרות קישורים';
+$lang['_media'] = 'הגדרות מדיה';
+$lang['_advanced'] = 'הגדרות מתקדמות';
+$lang['_network'] = 'הגדרות רשת';
+$lang['_plugin_sufix'] = 'הגדרות תוסף';
+$lang['_template_sufix'] = 'הגדרות תבנית';
+$lang['_msg_setting_undefined'] = 'אין מידע-על להגדרה.';
+$lang['_msg_setting_no_class'] = 'אין קבוצה להגדרה.';
+$lang['_msg_setting_no_default'] = 'אין ערך ברירת מחדל.';
+$lang['fmode'] = 'מצב יצירת קובץ';
+$lang['dmode'] = 'מצב יצירת ספריה';
+$lang['lang'] = 'שפה';
+$lang['basedir'] = 'ספרית בסיס';
+$lang['baseurl'] = 'כתובת URL בסיסית';
+$lang['savedir'] = 'ספריה לשמירת מידע';
+$lang['start'] = 'שם דף הפתיחה';
+$lang['title'] = 'כותרת הויקי';
+$lang['template'] = 'תבנית';
+$lang['fullpath'] = 'הצגת נתיב מלא לדפים בתחתית';
+$lang['recent'] = 'שינויים אחרונים';
+$lang['breadcrumbs'] = 'מספר עקבות להיסטוריה';
+$lang['youarehere'] = 'עקבות היררכיות להיסטוריה';
+$lang['typography'] = 'שימוש בחלופות טיפוגרפיות';
+$lang['htmlok'] = 'אישור שיבוץ HTML';
+$lang['phpok'] = 'אישור שיבוץ PHP';
+$lang['dformat'] = 'תסדיר תאריך (נא לפנות לפונקציה <a href="http://www.php.net/strftime">strftime</a> של PHP)';
+$lang['signature'] = 'חתימה';
+$lang['toptoclevel'] = 'רמה עליונה בתוכן הענינים';
+$lang['maxtoclevel'] = 'רמה מירבית בתוכן הענינים';
+$lang['maxseclevel'] = 'רמה מירבית בעריכת קטעים';
+$lang['camelcase'] = 'השתמש בראשיות גדולות לקישורים';
+$lang['deaccent'] = 'נקה שמות דפים';
+$lang['useheading'] = 'השתמש בכותרת הראשונה לשם הדף';
+$lang['refcheck'] = 'בדוק שיוך מדיה';
+$lang['refshow'] = 'מספר שיוכי המדיה שיוצגו';
+$lang['allowdebug'] = 'אפשר דיבוג <b>יש לבטל אם אין צורך!</b>';
+$lang['usewordblock'] = 'חסימת דואר זבל לפי רשימת מילים';
+$lang['indexdelay'] = 'השהיה בטרם הכנסה לאינדקס (שניות)';
+$lang['relnofollow'] = 'השתמש ב- rel="nofollow" לקישורים חיצוניים';
+$lang['mailguard'] = 'הגן על כתובות דוא"ל';
+$lang['iexssprotect'] = 'בדוק את הדפים המועלים לחשד ל-JavaScript או קוד HTML זדוני';
+$lang['useacl'] = 'השתמש ברשימות בקרת גישה';
+$lang['autopasswd'] = 'צור סיסמאות באופן אוטומטי';
+$lang['authtype'] = 'מנוע הזדהות';
+$lang['passcrypt'] = 'שיטת הצפנת סיסמאות';
+$lang['defaultgroup'] = 'קבוצת ברירת המחדל';
+$lang['superuser'] = 'משתמש-על';
+$lang['manager'] = 'מנהל - קבוצה, משתמש או רשימה מופרדת בפסיקים משתמש1, @קבוצה1, משתמש2 עם גישה לפעולות ניהול מסוימות.';
+$lang['profileconfirm'] = 'אשר שינוי פרופילים עם סיסמה';
+$lang['disableactions'] = 'בטל פעולות DokuWiki';
+$lang['disableactions_check'] = 'בדיקה';
+$lang['disableactions_subscription'] = 'הרשמה/הסרה מרשימה';
+$lang['disableactions_wikicode'] = 'הצגת המקור/יצוא גולמי';
+$lang['disableactions_other'] = 'פעולות אחרות (מופרדות בפסיק)';
+$lang['sneaky_index'] = 'כברירת מחדל, דוקוויקי יציג את כל מרחבי השמות בתצוגת תוכן הענינים. בחירה באפשרות זאת תסתיר את אלו שבהם למשתמש אין הרשאות קריאה. התוצאה עלולה להיות הסתרת תת מרחבי שמות אליהם יש למשתמש גישה. באופן זה תוכן הענינים עלול להפוך לחסר תועלת עם הגדרות ACL מסוימות';
+$lang['auth_security_timeout'] = 'מגבלת אבטח פסק הזמן להזדהות (שניות)';
+$lang['xmlrpc'] = 'לאפשר.לחסום את מנשק XML-RPC';
+$lang['updatecheck'] = 'בדיקת עידכוני אבטחה והתראות? על DokuWiki להתקשר אל update.dokuwiki.org לצורך כך.';
+$lang['userewrite'] = 'השתמש בכתובות URL יפות';
+$lang['useslash'] = 'השתמש בלוכסן להגדרת מרחבי שמות בכתובות';
+$lang['usedraft'] = 'שמור טיוטות באופן אוטומטי בעת עריכה';
+$lang['sepchar'] = 'מפריד בין מילות שם-דף';
+$lang['canonical'] = 'השתמש בכתובות URL מלאות';
+$lang['autoplural'] = 'בדוק לצורת רבים בקישורים';
+$lang['compression'] = 'אופן דחיסת קבצים ב-attic';
+$lang['cachetime'] = 'גיל מירבי לזכרון מטמון (שניות)';
+$lang['locktime'] = 'גיל מירבי לקבצי נעילה (שניות)';
+$lang['fetchsize'] = 'גודל הקובץ המירבי (bytes) ש-fetch.php יכול להוריד מבחוץ';
+$lang['notify'] = 'שלח התראות על שינויים לכתובת דוא"ל זו';
+$lang['registernotify'] = 'שלח מידע על משתמשים רשומים חדשים לכתובת דוא"ל זו';
+$lang['mailfrom'] = 'כתובת הדוא"ל לשימוש בדברי דוא"ל אוטומטיים';
+$lang['gzip_output'] = 'השתמש בקידוד תוכן של gzip עבור xhtml';
+$lang['gdlib'] = 'גרסת ספרית ה-GD';
+$lang['im_convert'] = 'נתיב לכלי ה-convert של ImageMagick';
+$lang['jpg_quality'] = 'איכות הדחיסה של JPG (0-100)';
+$lang['subscribers'] = 'התר תמיכה ברישום לדפים';
+$lang['compress'] = 'פלט קומפקטי של CSS ו-javascript';
+$lang['hidepages'] = 'הסתר דפים תואמים (ביטויים רגולריים)';
+$lang['send404'] = 'שלח "HTTP 404/Page Not Found" עבור דפים שאינם קיימים';
+$lang['sitemap'] = 'צור מפת אתר של Google (ימים)';
+$lang['broken_iua'] = 'האם הפעולה ignore_user_abort תקולה במערכת שלך? הדבר עלול להביא לתוכן חיפוש שאינו תקין. IIS+PHP/CGI ידוע כתקול. ראה את <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">באג 852</a> למידע נוסף';
+$lang['xsendfile'] = 'להשתמש בכותר X-Sendfile כדי לאפשר לשרת לספק קבצים סטטיים? על השרת שלך לתמוך באפשרות זאת.';
+$lang['renderer_xhtml'] = 'מחולל לשימוש עבור פלט הויקי העיקרי (xhtml)';
+$lang['renderer__core'] = '%s (ליבת דוקוויקי)';
+$lang['renderer__plugin'] = '%s (הרחבות)';
+$lang['rss_type'] = 'סוג פלט XML';
+$lang['rss_linkto'] = 'פלט ה-XML מקשר אל';
+$lang['rss_content'] = 'מה להציג בפרטי פלט ה-XML';
+$lang['rss_update'] = 'פלט ה-XML מתעדכן כל (שניות)';
+$lang['recent_days'] = 'כמה שינויים אחרונים לשמור (ימים)';
+$lang['rss_show_summary'] = 'פלט ה-XML מציג תקציר בכותרת';
+$lang['target____wiki'] = 'חלון יעד לקישורים פנימיים';
+$lang['target____interwiki'] = 'חלון יעד לקישורים בין מערכות ויקי';
+$lang['target____extern'] = 'חלון יעד לקישורים חיצוניים';
+$lang['target____media'] = 'חלון יעד לקישור למדיה';
+$lang['target____windows'] = 'חלון יעד לתיקיות משותפות';
+$lang['proxy____host'] = 'שם השרת המתווך';
+$lang['proxy____port'] = 'שער השרת המתווך';
+$lang['proxy____user'] = 'שם המשתמש בשרת המתווך';
+$lang['proxy____pass'] = 'סיסמת ההשרת המתווך';
+$lang['proxy____ssl'] = 'השתמש ב-ssl כדי להתחבר לשרת המתווך';
+$lang['safemodehack'] = 'אפשר שימוש בפתרון ל-safemode';
+$lang['ftp____host'] = 'שרת FTP עבור פתרון ה-safemode';
+$lang['ftp____port'] = 'שער ה-FTP עבור פתרון ה-safemode';
+$lang['ftp____user'] = 'שם המשתמש ב-FTPעבור פתרון ה-safemode';
+$lang['ftp____pass'] = 'סיסמת ה-FTP לפתרון ה-safemode';
+$lang['ftp____root'] = 'ספרית השורש ב-FTP עבור פתרון ה-safemode';
+$lang['typography_o_0'] = 'ללא';
+$lang['typography_o_1'] = 'רק גרשיים כפולים';
+$lang['typography_o_2'] = 'כל הגרשים (עלול שלא לעבוד לעיתים)';
+$lang['userewrite_o_0'] = 'ללא';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'פנימי של DokuWiki';
+$lang['deaccent_o_0'] = 'כבוי';
+$lang['deaccent_o_1'] = 'הסר ניבים';
+$lang['deaccent_o_2'] = 'הסב ללטינית';
+$lang['gdlib_o_0'] = 'ספרית ה-GD אינה זמינה';
+$lang['gdlib_o_1'] = 'גרסה 1.x';
+$lang['gdlib_o_2'] = 'זיהוי אוטומטי';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'תקציר';
+$lang['rss_content_o_diff'] = 'הבדלים מאוחדים';
+$lang['rss_content_o_htmldiff'] = 'טבלת HTML של ההבדלים';
+$lang['rss_content_o_html'] = 'מלוא תוכן דף HTML';
+$lang['rss_linkto_o_diff'] = 'תצוגת הבדלים';
+$lang['rss_linkto_o_page'] = 'הדף שהשתנה';
+$lang['rss_linkto_o_rev'] = 'גרסאות קודמות';
+$lang['rss_linkto_o_current'] = 'הדף הנוכחי';
+$lang['compression_o_0'] = 'ללא';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'אל תשתמש';
+$lang['xsendfile_o_1'] = 'כותר lighttpd קנייני (לפני גרסה 1.5)';
+$lang['xsendfile_o_2'] = 'כותר X-Sendfile רגיל';
+$lang['xsendfile_o_3'] = 'כותר Nginx X-Accel-Redirect קנייני';
+$lang['useheading_o_navigation'] = 'ניווט בלבד';
+$lang['useheading_o_1'] = 'תמיד';
diff --git a/lib/plugins/config/lang/hi/lang.php b/lib/plugins/config/lang/hi/lang.php
new file mode 100644
index 000000000..a224fdf7c
--- /dev/null
+++ b/lib/plugins/config/lang/hi/lang.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Hindi language file
+ *
+ * @author Abhinav Tyagi <abhinavtyagi11@gmail.com>
+ * @author yndesai@gmail.com
+ */
+$lang['sepchar'] = 'पृष्ठ का नाम शब्द प्रथक्कर';
+$lang['sitemap'] = 'गूगल का सूचना पटल नक्शा बनायें (दिन)';
+$lang['license_o_'] = 'कुछ नहीं चुना';
+$lang['typography_o_0'] = 'कुछ नहीं';
+$lang['showuseras_o_username'] = 'उपयोगकर्ता का पूर्ण नाम';
+$lang['useheading_o_0'] = 'कभी नहीं';
+$lang['useheading_o_1'] = 'हमेशा';
diff --git a/lib/plugins/config/lang/hr/lang.php b/lib/plugins/config/lang/hr/lang.php
new file mode 100644
index 000000000..96f1d6afe
--- /dev/null
+++ b/lib/plugins/config/lang/hr/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Croatian language file
+ *
+ * @author Branko Rihtman <theney@gmail.com>
+ * @author Dražen Odobašić <dodobasic@gmail.com>
+ * @author Dejan Igrec dejan.igrec@gmail.com
+ */
diff --git a/lib/plugins/config/lang/hu/intro.txt b/lib/plugins/config/lang/hu/intro.txt
new file mode 100644
index 000000000..b6b914902
--- /dev/null
+++ b/lib/plugins/config/lang/hu/intro.txt
@@ -0,0 +1,9 @@
+====== Beállító központ ======
+
+Ezzel az oldallal finomhangolhatod a DokuWiki rendszeredet. Az egyes beállításokhoz [[doku>config|itt]] kaphatsz segítséget. A bővítmények (pluginek) beállításaihoz [[doku>plugin:config|ezt]] az oldalt látogasd meg.
+
+A világospiros hátterű beállítások védettek, ezzel a bővítménnyel nem módosíthatóak.
+
+A kék hátterű beállítások az alapértelmezett értékek, a fehér hátterűek módosítva lettek ebben a rendszerben. Mindkét hátterű beállítások módosíthatóak.
+
+Ne felejtsd a **Mentés** gombot megnyomni, mielőtt elhagyod az oldalt, különben a módosításaid elvesznek!
diff --git a/lib/plugins/config/lang/hu/lang.php b/lib/plugins/config/lang/hu/lang.php
new file mode 100644
index 000000000..f991b7c95
--- /dev/null
+++ b/lib/plugins/config/lang/hu/lang.php
@@ -0,0 +1,190 @@
+<?php
+/**
+ * Hungarian language file
+ *
+ * @author Sandor TIHANYI <stihanyi+dw@gmail.com>
+ * @author Siaynoq Mage <siaynoqmage@gmail.com>
+ * @author schilling.janos@gmail.com
+ * @author Szabó Dávid <szabo.david@gyumolcstarhely.hu>
+ * @author Sándor TIHANYI <stihanyi+dw@gmail.com>
+ * @author David Szabo <szabo.david@gyumolcstarhely.hu>
+ */
+$lang['menu'] = 'Beállító Központ';
+$lang['error'] = 'Helytelen érték miatt a módosítások nem mentődtek. Nézd át a módosításokat, és ments újra.
+<br />A helytelen érték(ek)et piros kerettel jelöljük.';
+$lang['updated'] = 'A módosítások sikeresen beállítva.';
+$lang['nochoice'] = '(nincs egyéb lehetőség)';
+$lang['locked'] = 'A beállításokat tartalmazó fájlt nem tudtam frissíteni.<br />
+Nézd meg, hogy a fájl neve és jogosultságai helyesen vannak-e beállítva!';
+$lang['danger'] = 'Figyelem: ezt a beállítást megváltoztatva a konfigurációs menü hozzáférhetetlenné válhat.';
+$lang['warning'] = 'Figyelmeztetés: a beállítás megváltoztatása nem kívánt viselkedést okozhat.';
+$lang['security'] = 'Biztonsági figyelmeztetés: a beállítás megváltoztatása biztonsági veszélyforrást okozhat.';
+$lang['_configuration_manager'] = 'Beállító Központ';
+$lang['_header_dokuwiki'] = 'DokuWiki beállítások';
+$lang['_header_plugin'] = 'Bővítmények beállításai';
+$lang['_header_template'] = 'Sablon beállítások';
+$lang['_header_undefined'] = 'Nem definiált értékek';
+$lang['_basic'] = 'Alap beállítások';
+$lang['_display'] = 'Megjelenítés beállításai';
+$lang['_authentication'] = 'Azonosítás beállításai';
+$lang['_anti_spam'] = 'Anti-Spam beállítások';
+$lang['_editing'] = 'Szerkesztési beállítások';
+$lang['_links'] = 'Link beállítások';
+$lang['_media'] = 'Media beállítások';
+$lang['_advanced'] = 'Haladó beállítások';
+$lang['_network'] = 'Hálózati beállítások';
+$lang['_plugin_sufix'] = 'Bővítmények beállításai';
+$lang['_template_sufix'] = 'Sablon beállítások';
+$lang['_msg_setting_undefined'] = 'Nincs beállított meta-adat.';
+$lang['_msg_setting_no_class'] = 'Nincs beállított osztály.';
+$lang['_msg_setting_no_default'] = 'Nincs alapértelmezett érték.';
+$lang['fmode'] = 'Fájl létrehozási maszk';
+$lang['dmode'] = 'Könyvtár létrehozási maszk';
+$lang['lang'] = 'Nyelv';
+$lang['basedir'] = 'Báziskönyvtár';
+$lang['baseurl'] = 'Alap URL';
+$lang['savedir'] = 'Könyvtár az adatok mentésére';
+$lang['start'] = 'Kezdőoldal neve';
+$lang['title'] = 'Wiki címe';
+$lang['template'] = 'Sablon';
+$lang['license'] = 'Milyen licenc alatt érhető el a tartalom?';
+$lang['fullpath'] = 'Az oldalak teljes útvonalának mutatása a láblécben';
+$lang['recent'] = 'Utolsó változatok száma';
+$lang['breadcrumbs'] = 'Nyomvonal elemszám';
+$lang['youarehere'] = 'Hierarchikus nyomvonal';
+$lang['typography'] = 'Legyen-e tipográfiai csere';
+$lang['htmlok'] = 'Beágyazott HTML engedélyezése';
+$lang['phpok'] = 'Beágyazott PHP engedélyezése';
+$lang['dformat'] = 'Dátum formázás (lásd a PHP <a href="http://www.php.net/strftime">strftime</a> függvényt)';
+$lang['signature'] = 'Aláírás';
+$lang['toptoclevel'] = 'A tartalomjegyzék felső szintje';
+$lang['tocminheads'] = 'Legalább ennyi címsor hatására generálódjon tartalomjegyzék';
+$lang['maxtoclevel'] = 'A tartalomjegyzék mélysége';
+$lang['maxseclevel'] = 'A szakasz-szerkesztés maximális szintje';
+$lang['camelcase'] = 'CamelCase használata hivatkozásként';
+$lang['deaccent'] = 'Oldalnevek ékezettelenítése';
+$lang['useheading'] = 'Az első fejléc legyen az oldalnév';
+$lang['refcheck'] = 'Médiafájlok hivatkozásainak ellenőrzése';
+$lang['refshow'] = 'Média-hivatkozások maximálisan mutatott szintje';
+$lang['allowdebug'] = 'Debug üzemmód <b>Kapcsold ki, hacsak biztos nem szükséges!</b>';
+$lang['usewordblock'] = 'Szólista alapú spam-szűrés';
+$lang['indexdelay'] = 'Várakozás indexelés előtt (másodperc)';
+$lang['relnofollow'] = 'rel="nofollow" beállítás használata külső hivatkozásokra';
+$lang['mailguard'] = 'Email címek olvashatatlanná tétele címgyűjtők számára';
+$lang['iexssprotect'] = 'Feltöltött fájlok ellenőrzése kártékony JavaScript vagy HTML kód elkerülésére';
+$lang['showuseras'] = 'A felhasználó melyik adatát mutassunk az utolsó változtatás adatainál?';
+$lang['useacl'] = 'Hozzáférési listák (ACL) használata';
+$lang['autopasswd'] = 'Jelszavak automatikus generálása';
+$lang['authtype'] = 'Authentikációs háttérrendszer';
+$lang['passcrypt'] = 'Jelszó titkosítási módszer';
+$lang['defaultgroup'] = 'Alapértelmezett csoport';
+$lang['superuser'] = 'Szuper-felhasználó (Wiki-gazda) - csoport vagy felhasználó, aki teljes hozzáférési joggal rendelkezik az oldalakhoz és funkciókhoz, a hozzáférési jogosultságoktól függetlenül';
+$lang['manager'] = 'Menedzser - csoport vagy felhasználó, aki bizonyos menedzsment funkciókhoz hozzáfér';
+$lang['profileconfirm'] = 'Beállítások változtatásának megerősítése jelszóval';
+$lang['disableactions'] = 'Bizonyos DokuWiki tevékenységek (action) tiltása';
+$lang['disableactions_check'] = 'Ellenőrzés';
+$lang['disableactions_subscription'] = 'Feliratkozás/Leiratkozás';
+$lang['disableactions_wikicode'] = 'Forrás megtekintése/Nyers adat exportja';
+$lang['disableactions_other'] = 'Egyéb tevékenységek (vesszővel elválasztva)';
+$lang['sneaky_index'] = 'Alapértelmezetten minden névtér látszik a DokuWiki áttekintő (index) oldalán. Ezen opció bekapcsolása után azok nem jelennek meg, melyekhez a felhasználónak nincs olvasás joga. De ezzel eltakarhatunk egyébként elérhető al-névtereket is, így bizonyos ACL beállításoknál használhatatlan indexet eredményez ez a beállítás.';
+$lang['auth_security_timeout'] = 'Authentikációs biztonsági időablak (másodperc)';
+$lang['securecookie'] = 'A böngészők a HTTPS felett beállított sütijüket csak HTTPS felett küldhetik? Kapcsoljuk ki ezt az opciót, ha csak a bejelentkezést védjük SSL-lel, a wiki tartalmának böngészése nyílt forgalommal történik.';
+$lang['xmlrpc'] = 'XML-RPC interfész engedélyezése/tiltása';
+$lang['xmlrpcuser'] = 'Korlátozza XML-RPC hozzáférést az itt megadott vesszővel elválasztott csoportok vagy felhasználók számára. Hagyja üresen, ha mindenki számára biztosítja a hozzáférést.';
+$lang['updatecheck'] = 'Frissítések és biztonsági figyelmeztetések figyelése. Ehhez a DokuWikinek kapcsolatba kell lépnie a update.dokuwiki.org-gal.';
+$lang['userewrite'] = 'Szép URL-ek használata';
+$lang['useslash'] = 'Per-jel használata névtér-elválasztóként az URL-ekben';
+$lang['usedraft'] = 'Piszkozat automatikus mentése szerkesztés alatt';
+$lang['sepchar'] = 'Szó elválasztó az oldalnevekben';
+$lang['canonical'] = 'Teljesen kanonikus URL-ek használata';
+$lang['fnencode'] = 'A nem ASCII fájlnevek dekódolási módja';
+$lang['autoplural'] = 'Többes szám ellenőrzés a hivatkozásokban (angol)';
+$lang['compression'] = 'Tömörítés használata a törölt lapokhoz';
+$lang['cachetime'] = 'A gyorsítótár maximális élettartama (másodperc)';
+$lang['locktime'] = 'Oldal-zárolás maximális időtartama (másodperc)';
+$lang['fetchsize'] = 'Maximális méret (bájtban), amit a fetch.php letölthet kívülről';
+$lang['notify'] = 'Az oldal-változásokat erre az e-mail címre küldje';
+$lang['registernotify'] = 'Értesítés egy újonnan regisztrált felhasználóról erre az e-mail címre';
+$lang['mailfrom'] = 'Az automatikusan küldött levelekben használt e-mail cím';
+$lang['mailprefix'] = 'Előtag az automatikus e-mailek tárgyában';
+$lang['gzip_output'] = 'gzip tömörítés használata xhtml-hez (Content-Encoding)';
+$lang['gdlib'] = 'GD Lib verzió';
+$lang['im_convert'] = 'Útvonal az ImageMagick csomag convert parancsához';
+$lang['jpg_quality'] = 'JPG tömörítés minősége (0-100)';
+$lang['subscribers'] = 'Oldalváltozás-listára feliratkozás engedélyezése';
+$lang['subscribe_time'] = 'Az értesítések kiküldésének késleltetése (másodperc); Érdemes kisebbet választani, mint a változások megőrzésének maximális ideje.';
+$lang['compress'] = 'CSS és JavaScript fájlok tömörítése';
+$lang['hidepages'] = 'Az itt megadott oldalak elrejtése (reguláris kifejezés)';
+$lang['send404'] = '"HTTP 404/Page Not Found" küldése nemlétező oldalak esetén';
+$lang['sitemap'] = 'Hány naponként generáljunk Google sitemap-ot?';
+$lang['broken_iua'] = 'Az ignore_user_abort függvény hibát dob a rendszereden? Ez nem működő keresési indexet eredményezhet. Az IIS+PHP/CGI összeállításról tudjuk, hogy hibát dob. Lásd a <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> oldalt a további infóért.';
+$lang['xsendfile'] = 'Használjuk az X-Sendfile fejlécet, hogy a webszerver statikus állományokat tudjon küldeni? A webszervernek is támogatnia kell ezt a funkciót.';
+$lang['renderer_xhtml'] = 'Az elsődleges (xhtml) wiki kimenet generálója';
+$lang['renderer__core'] = '%s (dokuwiki mag)';
+$lang['renderer__plugin'] = '%s (bővítmény)';
+$lang['rememberme'] = 'Állandó sütik engedélyezése (az "emlékezz rám" funkcióhoz)';
+$lang['rss_type'] = 'XML hírfolyam típus';
+$lang['rss_linkto'] = 'XML hírfolyam hivatkozás';
+$lang['rss_content'] = 'Mit mutassunk az XML hírfolyam elemekben?';
+$lang['rss_update'] = 'Hány másodpercenként frissítsük az XML hírfolyamot?';
+$lang['recent_days'] = 'Hány napig tartsuk meg a korábbi változatokat?';
+$lang['rss_show_summary'] = 'A hírfolyam címébe összefoglaló helyezése';
+$lang['target____wiki'] = 'Cél-ablak belső hivatkozásokhoz';
+$lang['target____interwiki'] = 'Cél-ablak interwiki hivatkozásokhoz';
+$lang['target____extern'] = 'Cél-ablak külső hivatkozásokhoz';
+$lang['target____media'] = 'Cél-ablak média-fájl hivatkozásokhoz';
+$lang['target____windows'] = 'Cél-ablak Windows hivatkozásokhoz';
+$lang['proxy____host'] = 'Proxy szerver neve';
+$lang['proxy____port'] = 'Proxy port';
+$lang['proxy____user'] = 'Proxy felhasználó név';
+$lang['proxy____pass'] = 'Proxy jelszó';
+$lang['proxy____ssl'] = 'SSL használata a proxyhoz csatlakozáskor';
+$lang['proxy____except'] = 'URL szabály azokra a webcímekre, amit szeretnél, hogy ne kezeljen a proxy.';
+$lang['safemodehack'] = 'A PHP safemode beállítás megkerülésének engedélyezése';
+$lang['ftp____host'] = 'FTP szerver a safemode megkerüléshez';
+$lang['ftp____port'] = 'FTP port a safemode megkerüléshez';
+$lang['ftp____user'] = 'FTP felhasználó név a safemode megkerüléshez';
+$lang['ftp____pass'] = 'FTP jelszó a safemode megkerüléshez';
+$lang['ftp____root'] = 'FTP gyökérkönyvtár a safemode megkerüléshez';
+$lang['license_o_'] = 'Nincs kiválasztva';
+$lang['typography_o_0'] = 'nem';
+$lang['typography_o_1'] = 'Csak a dupla idézőjelet';
+$lang['typography_o_2'] = 'Minden idézőjelet (előfordulhat, hogy nem mindig működik)';
+$lang['userewrite_o_0'] = 'nem';
+$lang['userewrite_o_1'] = '.htaccess-szel';
+$lang['userewrite_o_2'] = 'DokuWiki saját módszerével';
+$lang['deaccent_o_0'] = 'kikapcsolva';
+$lang['deaccent_o_1'] = 'ékezetek eltávolítása';
+$lang['deaccent_o_2'] = 'távirati stílus';
+$lang['gdlib_o_0'] = 'GD Lib nem elérhető';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Auto felismerés';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Kivonat';
+$lang['rss_content_o_diff'] = 'Unified diff formátum';
+$lang['rss_content_o_htmldiff'] = 'HTML formázott változás tábla';
+$lang['rss_content_o_html'] = 'Teljes HTML oldal tartalom';
+$lang['rss_linkto_o_diff'] = 'a változás nézetre';
+$lang['rss_linkto_o_page'] = 'az átdolgozott oldalra';
+$lang['rss_linkto_o_rev'] = 'a változatok listájára';
+$lang['rss_linkto_o_current'] = 'a jelenlegi oldalra';
+$lang['compression_o_0'] = 'nincs tömörítés';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nincs használatban';
+$lang['xsendfile_o_1'] = 'lighttpd saját fejléc (1.5-ös verzió előtti)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile fejléc';
+$lang['xsendfile_o_3'] = 'Nginx saját X-Accel-Redirect fejléce';
+$lang['showuseras_o_loginname'] = 'Azonosító';
+$lang['showuseras_o_username'] = 'Teljes név';
+$lang['showuseras_o_email'] = 'E-mail cím (olvashatatlanná téve az e-mailcím védelem beállítása szerint)';
+$lang['showuseras_o_email_link'] = 'E-mail cím mailto: linkként';
+$lang['useheading_o_0'] = 'Soha';
+$lang['useheading_o_navigation'] = 'Csak navigációhoz';
+$lang['useheading_o_content'] = 'Csak Wiki tartalomhoz';
+$lang['useheading_o_1'] = 'Mindig';
+$lang['readdircache'] = 'A könyvtár olvasás gyorsítótárának maximális tárolási ideje (másodperc)';
diff --git a/lib/plugins/config/lang/ia/intro.txt b/lib/plugins/config/lang/ia/intro.txt
new file mode 100644
index 000000000..37b970c4f
--- /dev/null
+++ b/lib/plugins/config/lang/ia/intro.txt
@@ -0,0 +1,7 @@
+====== Gestion de configurationes ======
+
+Usa iste pagina pro controlar le configurationes de tu installation de DokuWiki. Pro adjuta re configurationes individual, refere te a [[doku>config]].
+
+Le configurationes monstrate super un fundo rubie clar es protegite e non pote esser alterate con iste plug-in. Le configurationes monstrate super un fundo blau es le valores predefinite e le configurationes monstrate super un fundo blanc ha essite definite localmente pro iste particular installation. Le configurationes blau e blanc pote esser alterate.
+
+Rememora de premer le button **SALVEGUARDAR** ante de quitar iste pagina, alteremente tu modificationes essera perdite. \ No newline at end of file
diff --git a/lib/plugins/config/lang/ia/lang.php b/lib/plugins/config/lang/ia/lang.php
new file mode 100644
index 000000000..689869b89
--- /dev/null
+++ b/lib/plugins/config/lang/ia/lang.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ * Interlingua language file
+ *
+ * @author robocap <robocap1@gmail.com>
+ * @author Martijn Dekker <martijn@inlv.org>
+ */
+$lang['menu'] = 'Configurationes';
+$lang['error'] = 'Le configurationes non poteva esser actualisate a causa de un valor invalide; per favor revide tu cambiamentos e resubmitte los.<br />Le valor(es) incorrecte essera monstrate circumferite per un bordo rubie.';
+$lang['updated'] = 'Actualisation del configurationes succedite.';
+$lang['nochoice'] = '(nulle altere option disponibile)';
+$lang['locked'] = 'Le file de configuration non pote esser actualisate; si isto non es intentional, <br /> assecura te que le nomine e permissiones del file local de configuration es correcte.';
+$lang['danger'] = 'Periculo: Cambiar iste option pote render tu wiki e le menu de configuration inaccessibile!';
+$lang['warning'] = 'Attention: Cambiar iste option pote causar functionamento indesirate.';
+$lang['security'] = 'Advertimento de securitate: Cambiar iste option pote causar un risco de securitate.';
+$lang['_configuration_manager'] = 'Gestion de configurationes';
+$lang['_header_dokuwiki'] = 'Configurationes de DokuWiki';
+$lang['_header_plugin'] = 'Configurationes de plug-ins';
+$lang['_header_template'] = 'Configurationes de patronos';
+$lang['_header_undefined'] = 'Configurationes non definite';
+$lang['_basic'] = 'Configurationes de base';
+$lang['_display'] = 'Configurationes de visualisation';
+$lang['_authentication'] = 'Configurationes de authentication';
+$lang['_anti_spam'] = 'Configurationes anti-spam';
+$lang['_editing'] = 'Configurationes de modification';
+$lang['_links'] = 'Configurationes de ligamines';
+$lang['_media'] = 'Configurationes de multimedia';
+$lang['_advanced'] = 'Configurationes avantiate';
+$lang['_network'] = 'Configurationes de rete';
+$lang['_plugin_sufix'] = 'Configurationes de plug-ins';
+$lang['_template_sufix'] = 'Configurationes de patronos';
+$lang['_msg_setting_undefined'] = 'Nulle metadatos de configuration.';
+$lang['_msg_setting_no_class'] = 'Nulle classe de configuration.';
+$lang['_msg_setting_no_default'] = 'Nulle valor predefinite.';
+$lang['fmode'] = 'Permissiones al creation de files';
+$lang['dmode'] = 'Permissiones al creation de directorios';
+$lang['lang'] = 'Lingua del interfacie';
+$lang['basedir'] = 'Cammino al servitor (p.ex.. <code>/dokuwiki/</code>). Lassa vacue pro autodetection.';
+$lang['baseurl'] = 'URL del servitor (p.ex. <code>http://www.yourserver.com</code>). Lassa vacue pro autodetection.';
+$lang['savedir'] = 'Directorio pro salveguardar datos';
+$lang['start'] = 'Nomine del pagina initial';
+$lang['title'] = 'Titulo del wiki';
+$lang['template'] = 'Patrono';
+$lang['license'] = 'Sub qual licentia debe tu contento esser publicate?';
+$lang['fullpath'] = 'Revelar le cammino complete del paginas in le pede';
+$lang['recent'] = 'Modificationes recente';
+$lang['breadcrumbs'] = 'Numero de micas de pan';
+$lang['youarehere'] = 'Micas de pan hierarchic';
+$lang['typography'] = 'Face substitutiones typographic';
+$lang['htmlok'] = 'Permitter incorporation de HTML';
+$lang['phpok'] = 'Permitter incorporation de PHP';
+$lang['dformat'] = 'Formato del datas (vide le function <a href="http://www.php.net/strftime">strftime</a> de PHP)';
+$lang['signature'] = 'Signatura';
+$lang['toptoclevel'] = 'Nivello principal pro tabula de contento';
+$lang['tocminheads'] = 'Numero minimal de titulos requirite pro inserer tabula de contento';
+$lang['maxtoclevel'] = 'Nivello maximal pro tabula de contento';
+$lang['maxseclevel'] = 'Nivello maximal pro modification de sectiones';
+$lang['camelcase'] = 'Usar CamelCase pro ligamines';
+$lang['deaccent'] = 'Nomines nette de paginas';
+$lang['useheading'] = 'Usar le prime titulo como nomine de pagina';
+$lang['refcheck'] = 'Verification de referentias multimedia';
+$lang['refshow'] = 'Numero de referentias multimedia a monstrar';
+$lang['allowdebug'] = 'Permitter debugging <b>disactiva si non necessari!</b>';
+$lang['usewordblock'] = 'Blocar spam a base de lista de parolas';
+$lang['indexdelay'] = 'Retardo ante generation de indice (secundas)';
+$lang['relnofollow'] = 'Usar rel="nofollow" pro ligamines externe';
+$lang['mailguard'] = 'Offuscar adresses de e-mail';
+$lang['iexssprotect'] = 'Verificar files incargate pro codice HTML o JavaScript possibilemente malitiose';
+$lang['showuseras'] = 'Como monstrar le usator que faceva le ultime modification de un pagina';
+$lang['useacl'] = 'Usar listas de controlo de accesso';
+$lang['autopasswd'] = 'Automaticamente generar contrasignos';
+$lang['authtype'] = 'Servicio de authentication';
+$lang['passcrypt'] = 'Methodo de cryptographia de contrasignos';
+$lang['defaultgroup'] = 'Gruppo predefinite';
+$lang['superuser'] = 'Superusator: le gruppo, usator o lista separate per commas ("usator1,@gruppo1,usator2") con accesso integral a tote le paginas e functiones sin reguardo del ACL';
+$lang['manager'] = 'Administrator: le gruppo, usator o lista separate per commas ("usator1,@gruppo1,usator2") con accesso a certe functiones administrative';
+$lang['profileconfirm'] = 'Confirmar modificationes del profilo con contrasigno';
+$lang['disableactions'] = 'Disactivar actiones DokuWiki';
+$lang['disableactions_check'] = 'Verificar';
+$lang['disableactions_subscription'] = 'Subscriber/Cancellar subscription';
+$lang['disableactions_wikicode'] = 'Vider codice-fonte/Exportar texto crude';
+$lang['disableactions_other'] = 'Altere actiones (separate per commas)';
+$lang['sneaky_index'] = 'Normalmente, DokuWiki monstra tote le spatios de nomines in le vista del indice. Si iste option es active, illos ubi le usator non ha le permission de lectura essera celate. Isto pote resultar in le celamento de subspatios de nomines accessibile. Isto pote render le indice inusabile con certe configurationes de ACL.';
+$lang['auth_security_timeout'] = 'Expiration pro securitate de authentication (secundas)';
+$lang['securecookie'] = 'Debe le cookies definite via HTTPS solmente esser inviate via HTTPS per le navigator? Disactiva iste option si solmente le apertura de sessiones a tu wiki es protegite con SSL ma le navigation del wiki es facite sin securitate.';
+$lang['xmlrpc'] = 'Activar/disactivar interfacie XML-RPC.';
+$lang['xmlrpcuser'] = 'Limitar le accesso a XML-RPC al gruppos o usatores date hic, separate per commas. Lassa isto vacue pro dar accesso a omnes.';
+$lang['updatecheck'] = 'Verificar si existe actualisationes e advertimentos de securitate? DokuWiki debe contactar update.dokuwiki.org pro exequer iste function.';
+$lang['userewrite'] = 'Usar URLs nette';
+$lang['useslash'] = 'Usar le barra oblique ("/") como separator de spatios de nomines in URLs';
+$lang['usedraft'] = 'Automaticamente salveguardar un version provisori durante le modification';
+$lang['sepchar'] = 'Separator de parolas in nomines de paginas';
+$lang['canonical'] = 'Usar URLs completemente canonic';
+$lang['autoplural'] = 'Verificar si il ha formas plural in ligamines';
+$lang['compression'] = 'Methodo de compression pro files a mansarda';
+$lang['cachetime'] = 'Etate maximal pro le cache (secundas)';
+$lang['locktime'] = 'Etate maximal pro le files de serratura (secundas)';
+$lang['fetchsize'] = 'Numero maximal de bytes per file que fetch.php pote discargar de sitos externe';
+$lang['notify'] = 'Inviar notificationes de cambios a iste adresse de e-mail';
+$lang['registernotify'] = 'Inviar informationes super usatores novemente registrate a iste adresse de e-mail';
+$lang['mailfrom'] = 'Adresse de e-mail a usar pro messages automatic';
+$lang['gzip_output'] = 'Usar Content-Encoding gzip pro xhtml';
+$lang['gdlib'] = 'Version de GD Lib';
+$lang['im_convert'] = 'Cammino al programma "convert" de ImageMagick';
+$lang['jpg_quality'] = 'Qualitate del compression JPEG (0-100)';
+$lang['subscribers'] = 'Activar le possibilitate de subscriber se al paginas';
+$lang['subscribe_time'] = 'Tempore post le qual le listas de subscription e le digestos es inviate (in secundas); isto debe esser minor que le tempore specificate in recent_days.';
+$lang['compress'] = 'Compactar le output CSS e JavaScript';
+$lang['hidepages'] = 'Celar paginas correspondente (expressiones regular)';
+$lang['send404'] = 'Inviar "HTTP 404/Pagina non trovate" pro paginas non existente';
+$lang['sitemap'] = 'Generar mappa de sito Google (dies)';
+$lang['broken_iua'] = 'Es le function ignore_user_abort defectuose in tu systema? Isto pote resultar in un indice de recerca que non functiona. Vide <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> pro plus info.';
+$lang['xsendfile'] = 'Usar le capite X-Sendfile pro lassar le servitor web livrar files static? Tu navigator del web debe supportar isto.';
+$lang['renderer_xhtml'] = 'Renditor a usar pro le output wiki principal (xhtml)';
+$lang['renderer__core'] = '%s (nucleo dokuwiki)';
+$lang['renderer__plugin'] = '%s (plug-in)';
+$lang['rememberme'] = 'Permitter cookies de session permanente (memorar me)';
+$lang['rss_type'] = 'Typo de syndication XML';
+$lang['rss_linkto'] = 'Syndication XML liga verso';
+$lang['rss_content'] = 'Que monstrar in le entratas de syndication XML?';
+$lang['rss_update'] = 'Intervallo de actualisation pro syndicationes XML (secundas)';
+$lang['recent_days'] = 'Retener quante modificationes recente? (dies)';
+$lang['rss_show_summary'] = 'Monstrar summario in titulo de syndication XML';
+$lang['target____wiki'] = 'Fenestra de destination pro ligamines interne';
+$lang['target____interwiki'] = 'Fenestra de destination pro ligamines interwiki';
+$lang['target____extern'] = 'Fenestra de destination pro ligamines externe';
+$lang['target____media'] = 'Fenestra de destination pro ligamines multimedia';
+$lang['target____windows'] = 'Fenestra de destination pro ligamines a fenestras';
+$lang['proxy____host'] = 'Nomine de servitor proxy';
+$lang['proxy____port'] = 'Porto del proxy';
+$lang['proxy____user'] = 'Nomine de usator pro le proxy';
+$lang['proxy____pass'] = 'Contrasigno pro le proxy';
+$lang['proxy____ssl'] = 'Usar SSL pro connecter al proxy';
+$lang['safemodehack'] = 'Permitter truco de modo secur';
+$lang['ftp____host'] = 'Servitor FTP pro truco de modo secur';
+$lang['ftp____port'] = 'Porto FTP pro truco de modo secur';
+$lang['ftp____user'] = 'Nomine de usator FTP pro truco de modo secur';
+$lang['ftp____pass'] = 'Contrasigno FTP pro truco de modo secur';
+$lang['ftp____root'] = 'Directorio radice FTP pro truco de modo securr';
+$lang['license_o_'] = 'Nihil seligite';
+$lang['typography_o_0'] = 'nulle';
+$lang['typography_o_1'] = 'excludente ';
+$lang['typography_o_2'] = 'includente virgulettas singule (pote non sempre functionar)';
+$lang['userewrite_o_0'] = 'nulle';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'interne a DokuWIki';
+$lang['deaccent_o_0'] = 'disactivate';
+$lang['deaccent_o_1'] = 'remover accentos';
+$lang['deaccent_o_2'] = 'romanisar';
+$lang['gdlib_o_0'] = 'GD Lib non disponibile';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Autodetection';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Abstracte';
+$lang['rss_content_o_diff'] = 'In formato Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'Tabella de diff in formato HTML';
+$lang['rss_content_o_html'] = 'Contento complete del pagina in HTML';
+$lang['rss_linkto_o_diff'] = 'vista de differentias';
+$lang['rss_linkto_o_page'] = 'le pagina revidite';
+$lang['rss_linkto_o_rev'] = 'lista de versiones';
+$lang['rss_linkto_o_current'] = 'le pagina actual';
+$lang['compression_o_0'] = 'nulle';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'non usar';
+$lang['xsendfile_o_1'] = 'Capite proprietari "lighttpd" (ante version 1.5)';
+$lang['xsendfile_o_2'] = 'Capite standard "X-Sendfile"';
+$lang['xsendfile_o_3'] = 'Capite proprietari "X-Accel-Redirect" de Nginx';
+$lang['showuseras_o_loginname'] = 'Nomine de usator';
+$lang['showuseras_o_username'] = 'Nomine real del usator';
+$lang['showuseras_o_email'] = 'Adresse de e-mail del usator (offuscate secundo le configuration de Mailguard)';
+$lang['showuseras_o_email_link'] = 'Adresse de e-mail del usator como ligamine "mailto:"';
+$lang['useheading_o_0'] = 'Nunquam';
+$lang['useheading_o_navigation'] = 'Navigation solmente';
+$lang['useheading_o_content'] = 'Contento wiki solmente';
+$lang['useheading_o_1'] = 'Sempre';
diff --git a/lib/plugins/config/lang/id-ni/intro.txt b/lib/plugins/config/lang/id-ni/intro.txt
new file mode 100644
index 000000000..cd77caa99
--- /dev/null
+++ b/lib/plugins/config/lang/id-ni/intro.txt
@@ -0,0 +1,7 @@
+====== Fakake famöfö'ö ======
+
+Plugin da'e itolo ba wangehaogö fakake moroi ba DokuWiki. Fanolo bawamöfö'ö tesöndra tou [[doku>config]]. Lala wangiila Plugin tanöbö'ö tesöndra tou ba [[doku>plugin:config]].
+
+Famöfö'ö zura furi la'a soyo no laproteksi, lötesöndra bakha ba Plugin andre. Famöfö'ö zura furi la'a sobalau ya'ia wamöfö'ö sito'ölö...
+
+Böi olifu ndra'ugö ba wofetugö **Irö'ö** fatua lö öröi fakake wamöfö'ö soguna bawangirö'ö wamöfö'ö safuria.
diff --git a/lib/plugins/config/lang/id-ni/lang.php b/lib/plugins/config/lang/id-ni/lang.php
new file mode 100644
index 000000000..edde733fb
--- /dev/null
+++ b/lib/plugins/config/lang/id-ni/lang.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * idni language file
+ *
+ * @author Harefa <fidelis@harefa.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
+$lang['xmlrpc'] = 'Orifi/böi\'orifi XML-RPC interface.';
+$lang['renderer_xhtml'] = 'Fake Renderer ba zito\'ölö (XHTML) Wiki-output.';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rss_type'] = 'Tipe XML feed';
+$lang['rss_linkto'] = 'XML feed links khö';
+$lang['rss_content'] = 'Hadia wangoromaö nifake ba XML-Feed?';
+$lang['rss_update'] = 'XML feed (sec) inötö wamohouni';
+$lang['recent_days'] = 'Hawa\'oya laforoma\'ö moroi bazibohou? (Hari)';
+$lang['rss_show_summary'] = 'XML feed foromaö summary ba title';
+$lang['target____wiki'] = 'Lala window ba internal links';
+$lang['target____interwiki'] = 'Lala window ba interwiki links';
+$lang['target____extern'] = 'Lala window ba external links';
+$lang['target____media'] = 'Lala window ba media links';
+$lang['target____windows'] = 'Lala window ba windows links';
+$lang['proxy____host'] = 'Töi server proxy';
+$lang['proxy____port'] = 'Port proxy';
+$lang['proxy____user'] = 'Töi proxy';
+$lang['proxy____pass'] = 'Kode proxy';
+$lang['proxy____ssl'] = 'Fake ssl ba connect awö Proxy';
+$lang['safemodehack'] = 'Orifi safemode hack';
+$lang['ftp____host'] = 'FTP server khö safemode hack';
+$lang['ftp____port'] = 'FTP port khö safemode hack';
+$lang['ftp____user'] = 'Töi FTP khö safemode hack';
+$lang['ftp____pass'] = 'FTP kode khö safemode hack';
+$lang['ftp____root'] = 'FTP root directory for safemode hack';
+$lang['typography_o_0'] = 'lö\'ö';
+$lang['typography_o_1'] = 'Ha sitombua kutip';
+$lang['typography_o_2'] = 'Fefu nikutip (itataria lömohalöwö)';
+$lang['userewrite_o_0'] = 'lö\'ö';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki bakha';
+$lang['deaccent_o_0'] = 'ofolai';
+$lang['deaccent_o_1'] = 'heta aksen';
+$lang['deaccent_o_2'] = 'romanize';
+$lang['gdlib_o_0'] = 'GD Lib lötesöndra';
+$lang['gdlib_o_1'] = 'Versi 1.x';
+$lang['gdlib_o_2'] = 'Otomatis';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Abstrak';
+$lang['rss_content_o_diff'] = 'Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML formatted diff table';
+$lang['rss_content_o_html'] = 'Fefu HTML format diff table';
+$lang['rss_linkto_o_diff'] = 'foromaö difference';
+$lang['rss_linkto_o_page'] = 'Refisi nga\'örö';
+$lang['rss_linkto_o_rev'] = 'Daftar nihaogö';
+$lang['rss_linkto_o_current'] = 'Nga\'örö safuria';
+$lang['compression_o_0'] = 'Lö\'ö';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'böi fake';
+$lang['xsendfile_o_1'] = 'Proprieteri lighttpd Header (furi Release 1.5)';
+$lang['xsendfile_o_2'] = 'Standar X-Sendfile header';
+$lang['xsendfile_o_3'] = 'Proprieteri Nginx X-Accel-Redirect header';
+$lang['showuseras_o_loginname'] = 'Töi';
+$lang['showuseras_o_username'] = 'Töi safönu';
+$lang['showuseras_o_email'] = 'Fake döi imele (obfuscated according to mailguard setting)';
+$lang['showuseras_o_email_link'] = 'Fake döi imele sifao mailto: link';
diff --git a/lib/plugins/config/lang/id/intro.txt b/lib/plugins/config/lang/id/intro.txt
new file mode 100644
index 000000000..296206d02
--- /dev/null
+++ b/lib/plugins/config/lang/id/intro.txt
@@ -0,0 +1,5 @@
+====== Manajemen Konfigurasi ======
+
+Gunakan halaman ini untuk mengatur konfigurasi instalasi DokuWiki Anda. Untuk bantuan dalam konfigurasi, silahkan lihat di [[doku>config]]. Unuk mengetahui lebih lanjut tentang plugin in silahkan lihat [[doku>plugin:config]].
+
+Konfigurasi dengan warna merah dilindungi dan tidak bisa diubah dengan plugin ini. Konfigurasi dengan warna biru adalah nilai default, dan konfigurasi dengan latar putih telah diset khusus untuk instalasi ini. Konfigurasi berwarna putih atau b
diff --git a/lib/plugins/config/lang/id/lang.php b/lib/plugins/config/lang/id/lang.php
new file mode 100644
index 000000000..c3d485930
--- /dev/null
+++ b/lib/plugins/config/lang/id/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Indonesian language file
+ *
+ * @author Irwan Butar Butar <irwansah.putra@gmail.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/config/lang/is/lang.php b/lib/plugins/config/lang/is/lang.php
new file mode 100644
index 000000000..c4905d0f9
--- /dev/null
+++ b/lib/plugins/config/lang/is/lang.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Icelandic language file
+ *
+ * @author Hrannar Baldursson <hrannar.baldursson@gmail.com>
+ * @author Ólafur Gunnlaugsson <oli@audiotools.com>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ */
+$lang['menu'] = 'Stillingar';
+$lang['error'] = 'Stillingum ekki breitt þar sem rangar upplýsingar voru settar inn, vinsamlegast yfirfarið stillingar merktar með rauðu';
+$lang['updated'] = 'Stillingum breitt';
+$lang['nochoice'] = '(engir aðrir valmöguleikar fyrir hendi)';
+$lang['_display'] = 'Skjástillingar';
+$lang['_anti_spam'] = 'Stillingar gegn ruslpósti';
+$lang['_editing'] = 'Útgáfastillingar';
+$lang['_plugin_sufix'] = 'Viðbótstillingar';
+$lang['lang'] = 'Tungumál';
+$lang['title'] = 'Heiti wikis';
+$lang['template'] = 'Mát';
+$lang['recent'] = 'Nýlegar breytingar';
+$lang['breadcrumbs'] = 'Fjöldi brauðmolar';
+$lang['youarehere'] = 'Stigveldisá brauðmolar';
+$lang['typography'] = 'Gera stað fyrir leturgerðir';
+$lang['htmlok'] = 'Fella HTML inn';
+$lang['phpok'] = 'Fella PHP inn';
+$lang['dformat'] = 'Dagsetningarsnið (sjá PHP-aðgerð <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Undirskrift';
+$lang['passcrypt'] = 'Dulritunaraðferð aðgangsorðs';
+$lang['defaultgroup'] = 'Sjálfgefinn hópur';
+$lang['superuser'] = 'Hópur kerfisstjóra ';
+$lang['profileconfirm'] = 'Staðfestu breytingar með aðgangsorði';
+$lang['mailfrom'] = 'Rafpóstfang fyrir sjálfvirkar póstsendingar';
+$lang['gdlib'] = 'Útgáfa af GD Lib';
+$lang['jpg_quality'] = 'JPG gæðastilling (0-100)';
+$lang['proxy____host'] = 'Heiti staðgengilsþjóns';
+$lang['proxy____port'] = 'Staðgengilstengi';
+$lang['proxy____user'] = 'Staðgengill notendanafn';
+$lang['proxy____pass'] = 'Staðgengilsaðgangsorð';
+$lang['proxy____ssl'] = 'Nýta SSL til að tengjast staðgengill';
+$lang['license_o_'] = 'Ekkert valið';
+$lang['typography_o_0'] = 'engin';
+$lang['userewrite_o_0'] = 'engin';
+$lang['deaccent_o_0'] = 'slökkt';
+$lang['deaccent_o_1'] = 'fjarlægja broddi';
+$lang['deaccent_o_2'] = 'gera rómverskt';
+$lang['gdlib_o_0'] = 'GD Lib ekki til staðar';
+$lang['gdlib_o_1'] = 'Útgáfa 1,x';
+$lang['gdlib_o_2'] = 'Sjálfvirk leit';
+$lang['rss_type_o_rss'] = 'RSS 0,91';
+$lang['rss_type_o_rss1'] = 'RSS 1,0';
+$lang['rss_type_o_rss2'] = 'RSS 2,0';
+$lang['rss_type_o_atom'] = 'Atom 0,3';
+$lang['rss_type_o_atom1'] = 'Atom 1,0';
+$lang['compression_o_0'] = 'engin';
+$lang['showuseras_o_loginname'] = 'Innskránafn';
+$lang['showuseras_o_username'] = 'Fullt notendanafn';
+$lang['useheading_o_0'] = 'Aldrei';
+$lang['useheading_o_1'] = 'Alltaf';
diff --git a/lib/plugins/config/lang/it/intro.txt b/lib/plugins/config/lang/it/intro.txt
new file mode 100644
index 000000000..617e8c7b5
--- /dev/null
+++ b/lib/plugins/config/lang/it/intro.txt
@@ -0,0 +1,9 @@
+====== Configurazione Wiki ======
+
+Usa questa pagina per gestire la configurazione della tua installazione DokuWiki. Per la guida sulle singole impostazioni fai riferimento alla pagina [[doku>config|Configurazione]]. Per ulteriori dettagli su questo plugin vedi [[doku>plugin:config|Plugin di configurazione]].
+
+Le impostazioni con lo sfondo rosso chiaro sono protette e non possono essere modificate con questo plugin. Le impostazioni con lo sfondo blu contengono i valori predefiniti, e le impostazioni con lo sfondo bianco sono relative solo a questa particolare installazione. Sia le impostazioni su sfondo blu che quelle su sfondo bianco possono essere modificate.
+
+Ricordati di premere il pulsante **SALVA** prima di lasciare questa pagina altrimenti le modifiche andranno perse.
+
+
diff --git a/lib/plugins/config/lang/it/lang.php b/lib/plugins/config/lang/it/lang.php
new file mode 100644
index 000000000..c4dd433ed
--- /dev/null
+++ b/lib/plugins/config/lang/it/lang.php
@@ -0,0 +1,195 @@
+<?php
+/**
+ * Italian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Silvia Sargentoni <polinnia@tin.it>
+ * @author Pietro Battiston toobaz@email.it
+ * @author Diego Pierotto ita.translations@tiscali.it
+ * @author ita.translations@tiscali.it
+ * @author Lorenzo Breda <lbreda@gmail.com>
+ * @author snarchio@alice.it
+ * @author robocap <robocap1@gmail.com>
+ * @author Osman Tekin osman.tekin93@hotmail.it
+ * @author Jacopo Corbetta <jacopo.corbetta@gmail.com>
+ */
+$lang['menu'] = 'Configurazione Wiki';
+$lang['error'] = 'Impostazioni non aggiornate a causa di un valore non corretto, controlla le modifiche apportate e salva di nuovo.
+<br />I valori non corretti sono evidenziati da un riquadro rosso.';
+$lang['updated'] = 'Aggiornamento impostazioni riuscito.';
+$lang['nochoice'] = '(nessun\'altra scelta disponibile)';
+$lang['locked'] = 'Il file di configurazione non può essere aggiornato, se questo non è intenzionale, <br />
+assicurati che il nome e i permessi del file contenente la configurazione locale siano corretti.';
+$lang['danger'] = 'Attenzione: cambiare questa opzione può rendere inaccessibile il wiki e il menu di configurazione.';
+$lang['warning'] = 'Avviso: cambiare questa opzione può causare comportamenti indesiderati.';
+$lang['security'] = 'Avviso di sicurezza: vambiare questa opzione può esporre a rischi di sicurezza.';
+$lang['_configuration_manager'] = 'Configurazione Wiki';
+$lang['_header_dokuwiki'] = 'Impostazioni DokuWiki';
+$lang['_header_plugin'] = 'Impostazioni Plugin';
+$lang['_header_template'] = 'Impostazioni Modello';
+$lang['_header_undefined'] = 'Impostazioni non definite';
+$lang['_basic'] = 'Impostazioni Base';
+$lang['_display'] = 'Impostazioni Visualizzazione';
+$lang['_authentication'] = 'Impostazioni Autenticazione';
+$lang['_anti_spam'] = 'Impostazioni Anti-Spam';
+$lang['_editing'] = 'Impostazioni Modifica';
+$lang['_links'] = 'Impostazioni Collegamenti';
+$lang['_media'] = 'Impostazioni File';
+$lang['_advanced'] = 'Impostazioni Avanzate';
+$lang['_network'] = 'Impostazioni Rete';
+$lang['_plugin_sufix'] = 'Impostazioni Plugin';
+$lang['_template_sufix'] = 'Impostazioni Modello';
+$lang['_msg_setting_undefined'] = 'Nessun metadato definito.';
+$lang['_msg_setting_no_class'] = 'Nessuna classe definita.';
+$lang['_msg_setting_no_default'] = 'Nessun valore predefinito.';
+$lang['fmode'] = 'Permessi per i nuovi file';
+$lang['dmode'] = 'Permessi per le nuove directory';
+$lang['lang'] = 'Lingua';
+$lang['basedir'] = 'Directory di base';
+$lang['baseurl'] = 'URL di base';
+$lang['savedir'] = 'Directory per il salvataggio dei dati';
+$lang['start'] = 'Nome della pagina iniziale';
+$lang['title'] = 'Titolo del wiki';
+$lang['template'] = 'Modello';
+$lang['license'] = 'Sotto quale licenza vorresti rilasciare il tuo contenuto?';
+$lang['fullpath'] = 'Mostra il percorso completo delle pagine';
+$lang['recent'] = 'Ultime modifiche';
+$lang['breadcrumbs'] = 'Numero di breadcrumb';
+$lang['youarehere'] = 'Breadcrumb gerarchici';
+$lang['typography'] = 'Abilita la sostituzione tipografica';
+$lang['htmlok'] = 'Consenti HTML incorporato';
+$lang['phpok'] = 'Consenti PHP incorporato';
+$lang['dformat'] = 'Formato delle date (vedi la funzione <a href="http://www.php.net/strftime">strftime</a> di PHP)';
+$lang['signature'] = 'Firma';
+$lang['toptoclevel'] = 'Livello superiore per l\'indice';
+$lang['tocminheads'] = 'Ammontare minimo di intestazioni che determinano la creazione del TOC';
+$lang['maxtoclevel'] = 'Numero massimo di livelli per l\'indice';
+$lang['maxseclevel'] = 'Livello massimo per le sezioni modificabili';
+$lang['camelcase'] = 'Usa CamelCase per i collegamenti';
+$lang['deaccent'] = 'Pulizia dei nomi di pagina';
+$lang['useheading'] = 'Usa la prima intestazione come nome di pagina';
+$lang['refcheck'] = 'Controlla i riferimenti ai file';
+$lang['refshow'] = 'Numero di riferimenti da visualizzare';
+$lang['allowdebug'] = 'Abilita il debug <b>(disabilitare se non serve!)</b>';
+$lang['usewordblock'] = 'Blocca lo spam in base alla blacklist';
+$lang['indexdelay'] = 'Intervallo di tempo prima dell\'indicizzazione';
+$lang['relnofollow'] = 'Usa rel="nofollow" nei collegamenti esterni';
+$lang['mailguard'] = 'Oscuramento indirizzi email';
+$lang['iexssprotect'] = 'Controlla i file caricati in cerca di possibile codice JavaScript o HTML maligno.';
+$lang['showuseras'] = 'Cosa visualizzare quando si mostra l\'ultimo utente che ha modificato una pagina';
+$lang['useacl'] = 'Usa lista di controllo accessi (ACL)';
+$lang['autopasswd'] = 'Genera password in automatico';
+$lang['authtype'] = 'Sistema di autenticazione';
+$lang['passcrypt'] = 'Metodo di cifratura password';
+$lang['defaultgroup'] = 'Gruppo predefinito';
+$lang['superuser'] = 'Amministratore - gruppo, utente o elenco di utenti separati da virgole (user1,@group1,user2) con accesso completo a tutte le pagine e le funzioni che riguardano le impostazioni ACL';
+$lang['manager'] = 'Gestore - gruppo, utente o elenco di utenti separati da virgole (user1,@group1,user2) con accesso a determinate funzioni di gestione';
+$lang['profileconfirm'] = 'Richiedi la password per modifiche al profilo';
+$lang['disableactions'] = 'Disabilita azioni DokuWiki';
+$lang['disableactions_check'] = 'Controlla';
+$lang['disableactions_subscription'] = 'Sottoscrivi/Rimuovi sottoscrizione';
+$lang['disableactions_wikicode'] = 'Mostra sorgente/Esporta Raw';
+$lang['disableactions_other'] = 'Altre azioni (separate da virgola)';
+$lang['sneaky_index'] = 'Normalmente, DokuWiki mostra tutte le categorie nella vista indice. Abilitando questa opzione, saranno nascoste quelle per cui l\'utente non ha il permesso in lettura. Questo potrebbe far sì che alcune sottocategorie accessibili siano nascoste. La pagina indice potrebbe quindi diventare inutilizzabile con alcune configurazioni dell\'ACL.';
+$lang['auth_security_timeout'] = 'Tempo di sicurezza per l\'autenticazione (secondi)';
+$lang['securecookie'] = 'Devono i cookies impostati tramite HTTPS essere inviati al browser solo tramite HTTPS? Disattiva questa opzione solo quando l\'accesso al tuo wiki viene effettuato con il protocollo SSL ma la navigazione del wiki non risulta sicura.';
+$lang['xmlrpc'] = 'Abilita/disabilita interfaccia XML-RPC.';
+$lang['xmlrpcuser'] = 'Limita l\'accesso XML-RPC ai gruppi o utenti indicati qui (separati da virgola). Lascia il campo vuoto per dare accesso a tutti.';
+$lang['updatecheck'] = 'Controllare aggiornamenti e avvisi di sicurezza? DokuWiki deve contattare update.dokuwiki.org per questa funzione.';
+$lang['userewrite'] = 'Usa il rewrite delle URL';
+$lang['useslash'] = 'Usa la barra rovescia (slash) come separatore nelle URL';
+$lang['usedraft'] = 'Salva una bozza in automatico in fase di modifica';
+$lang['sepchar'] = 'Separatore di parole nei nomi di pagina';
+$lang['canonical'] = 'Usa URL canoniche';
+$lang['fnencode'] = 'Metodo per codificare i filenames non-ASCII.';
+$lang['autoplural'] = 'Controlla il plurale nei collegamenti';
+$lang['compression'] = 'Usa la compressione per i file dell\'archivio';
+$lang['cachetime'] = 'Durata della cache (sec)';
+$lang['locktime'] = 'Durata dei file di lock (sec)';
+$lang['fetchsize'] = 'Dimensione massima (bytes) scaricabile da fetch.php da extern';
+$lang['notify'] = 'Invia notifiche sulle modifiche a questo indirizzo';
+$lang['registernotify'] = 'Invia informazioni sui nuovi utenti registrati a questo indirizzo email';
+$lang['mailfrom'] = 'Mittente per le mail automatiche';
+$lang['mailprefix'] = 'Prefisso da inserire nell\'oggetto delle mail automatiche';
+$lang['gzip_output'] = 'Usa il Content-Encoding gzip per xhtml';
+$lang['gdlib'] = 'Versione GD Lib ';
+$lang['im_convert'] = 'Percorso per il convertitore di ImageMagick';
+$lang['jpg_quality'] = 'Qualità di compressione JPG (0-100)';
+$lang['subscribers'] = 'Abilita la sottoscrizione alle pagine';
+$lang['subscribe_time'] = 'Tempo dopo il quale le liste di sottoscrizione e i riassunti vengono inviati (sec); Dovrebbe essere inferiore al tempo specificato in recent_days.';
+$lang['compress'] = 'Comprimi i file CSS e javascript';
+$lang['hidepages'] = 'Nascondi le pagine che soddisfano la condizione (inserire un\'espressione regolare)';
+$lang['send404'] = 'Invia "HTTP 404/Pagina non trovata" per le pagine inesistenti';
+$lang['sitemap'] = 'Genera una sitemap Google (giorni)';
+$lang['broken_iua'] = 'La funzione ignore_user_abort non funziona sul tuo sistema? Questo potrebbe far sì che l\'indice di ricerca sia inutilizzabile. È noto che nella configurazione IIS+PHP/CGI non funziona. Vedi il<a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> per maggiori informazioni.';
+$lang['xsendfile'] = 'Usare l\'header X-Sendfile per permettere al webserver di fornire file statici? Questa funzione deve essere supportata dal tuo webserver.';
+$lang['renderer_xhtml'] = 'Renderer da usare per la visualizzazione del wiki (xhtml)';
+$lang['renderer__core'] = '%s (dokuwiki)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Permetti i cookies di accesso permanenti (ricordami)';
+$lang['rss_type'] = 'Tipo di feed XML';
+$lang['rss_linkto'] = 'Collega i feed XML a';
+$lang['rss_content'] = 'Cosa mostrare negli elementi dei feed XML?';
+$lang['rss_update'] = 'Intervallo di aggiornamento dei feed XML (sec)';
+$lang['recent_days'] = 'Quante modifiche recenti tenere (giorni)';
+$lang['rss_show_summary'] = 'I feed XML riportano un sommario nel titolo';
+$lang['target____wiki'] = 'Finestra di destinazione per i collegamenti interni';
+$lang['target____interwiki'] = 'Finestra di destinazione per i collegamenti interwiki';
+$lang['target____extern'] = 'Finestra di destinazione per i collegamenti esterni';
+$lang['target____media'] = 'Finestra di destinazione per i collegamenti ai file';
+$lang['target____windows'] = 'Finestra di destinazione per i collegamenti alle risorse condivise';
+$lang['proxy____host'] = 'Nome server proxy';
+$lang['proxy____port'] = 'Porta proxy';
+$lang['proxy____user'] = 'Nome utente proxy';
+$lang['proxy____pass'] = 'Password proxy';
+$lang['proxy____ssl'] = 'Usa SSL per connetterti al proxy';
+$lang['proxy____except'] = 'Espressioni regolari per far corrispondere le URLs per i quali i proxy dovrebbero essere ommessi.';
+$lang['safemodehack'] = 'Abilita safemode hack';
+$lang['ftp____host'] = 'Server FTP per safemode hack';
+$lang['ftp____port'] = 'Porta FTP per safemode hack';
+$lang['ftp____user'] = 'Nome utente FTP per safemode hack';
+$lang['ftp____pass'] = 'Password FTP per safemode hack';
+$lang['ftp____root'] = 'Directory principale FTP per safemode hack';
+$lang['license_o_'] = 'Nessuna scelta';
+$lang['typography_o_0'] = 'nessuno';
+$lang['typography_o_1'] = 'Solo virgolette';
+$lang['typography_o_2'] = 'Tutti (potrebbe non funzionare sempre)';
+$lang['userewrite_o_0'] = 'nessuno';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki';
+$lang['deaccent_o_0'] = 'disabilitata';
+$lang['deaccent_o_1'] = 'rimuovi gli accenti';
+$lang['deaccent_o_2'] = 'romanizza';
+$lang['gdlib_o_0'] = 'GD Lib non disponibile';
+$lang['gdlib_o_1'] = 'Versione 1.x';
+$lang['gdlib_o_2'] = 'Rileva automaticamente';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Sunto';
+$lang['rss_content_o_diff'] = 'Diff unificata';
+$lang['rss_content_o_htmldiff'] = 'Tabella delle diff formattata HTML';
+$lang['rss_content_o_html'] = 'Tutto il contenuto della pagina in HTML';
+$lang['rss_linkto_o_diff'] = 'vista differenze';
+$lang['rss_linkto_o_page'] = 'pagina revisionata';
+$lang['rss_linkto_o_rev'] = 'elenco revisioni';
+$lang['rss_linkto_o_current'] = 'pagina attuale';
+$lang['compression_o_0'] = 'nessuna';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'non usare';
+$lang['xsendfile_o_1'] = 'Header proprietario lighttpd (prima della versione 1.5)';
+$lang['xsendfile_o_2'] = 'Header standard X-Sendfile';
+$lang['xsendfile_o_3'] = 'Header proprietario Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Nome utente';
+$lang['showuseras_o_username'] = 'Nome completo dell\'utente';
+$lang['showuseras_o_email'] = 'Indirizzo email dell\'utente (offuscato in base alle impostazioni di sicurezza posta)';
+$lang['showuseras_o_email_link'] = 'Indirizzo email dell\'utente come collegamento mailto:';
+$lang['useheading_o_0'] = 'Mai';
+$lang['useheading_o_navigation'] = 'Solo navigazione';
+$lang['useheading_o_content'] = 'Solo contenuto wiki';
+$lang['useheading_o_1'] = 'Sempre';
+$lang['readdircache'] = 'Tempo massimo per le readdir cache (sec)';
diff --git a/lib/plugins/config/lang/ja/intro.txt b/lib/plugins/config/lang/ja/intro.txt
new file mode 100644
index 000000000..0c45471c6
--- /dev/null
+++ b/lib/plugins/config/lang/ja/intro.txt
@@ -0,0 +1,9 @@
+====== 設定管理 ======
+
+この画面で、Dokuwikiの設定を管理することが出来ます。 個々の設定に関しては [[doku>config]] を参照してください。 このプラグインに関する詳細な情報は [[doku>plugin:config]] を参照してください。
+
+背景が薄い赤になっている場合、その設定は変更することが出来ません。 背景が青の値はデフォルト、背景が白の値は現在の設定となっており、 どちらの値も変更が可能です。
+
+設定の変更後は必ず **保存** ボタンを押して変更を確定してください。 ボタンを押さなかった場合、変更は破棄されます。
+
+
diff --git a/lib/plugins/config/lang/ja/lang.php b/lib/plugins/config/lang/ja/lang.php
new file mode 100644
index 000000000..500d44539
--- /dev/null
+++ b/lib/plugins/config/lang/ja/lang.php
@@ -0,0 +1,193 @@
+<?php
+/**
+ * japanese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Yuji Takenaka <webmaster@davilin.com>
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Ikuo Obataya <i.obataya@gmail.com>
+ * @author Daniel Dupriest <kououken@gmail.com>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ */
+$lang['menu'] = 'サイト設定';
+$lang['error'] = '不正な値が存在するため、設定は更新されませんでした。入力値を確認してから、再度更新してください。
+ <br />不正な値が入力されている項目は赤い線で囲まれています。';
+$lang['updated'] = '設定は正しく更新されました。';
+$lang['nochoice'] = '(他の選択肢はありません)';
+$lang['locked'] = '設定用ファイルを更新できません。もし意図して変更不可にしているのでなければ、<br />
+ ローカル設定ファイルの名前と権限を確認して下さい。';
+$lang['danger'] = '危険:この設定を変更するとウィキや設定管理画面にアクセスできなくなる恐れがあります。';
+$lang['warning'] = '注意:この設定を変更すると意図しない作動につながる可能性があります。';
+$lang['security'] = '警告:この設定を変更するとセキュリティに悪影響する恐れがあります。';
+$lang['_configuration_manager'] = '設定管理';
+$lang['_header_dokuwiki'] = 'DokuWiki';
+$lang['_header_plugin'] = 'プラグイン';
+$lang['_header_template'] = 'テンプレート';
+$lang['_header_undefined'] = 'その他';
+$lang['_basic'] = '基本';
+$lang['_display'] = '表示';
+$lang['_authentication'] = '認証';
+$lang['_anti_spam'] = 'スパム対策';
+$lang['_editing'] = '編集';
+$lang['_links'] = 'リンク';
+$lang['_media'] = 'メディア';
+$lang['_advanced'] = '高度な設定';
+$lang['_network'] = 'ネットワーク';
+$lang['_plugin_sufix'] = 'プラグイン設定';
+$lang['_template_sufix'] = 'テンプレート設定';
+$lang['_msg_setting_undefined'] = '設定のためのメタデータがありません。';
+$lang['_msg_setting_no_class'] = '設定クラスがありません。';
+$lang['_msg_setting_no_default'] = '初期値が設定されていません。';
+$lang['fmode'] = 'ファイル作成マスク';
+$lang['dmode'] = 'フォルダ作成マスク';
+$lang['lang'] = '使用言語';
+$lang['basedir'] = 'サーバのパス (例: <code>/dokuwiki/</code>)。空欄にすると自動的に検出します。';
+$lang['baseurl'] = 'サーバの URL (例: <code>http://www.yourserver.com</code>)。空欄にすると自動的に検出します。';
+$lang['savedir'] = '保存ディレクトリ';
+$lang['cookiedir'] = 'Cookie のパス。空欄にすると baseurl を使用します。';
+$lang['start'] = 'スタートページ名';
+$lang['title'] = 'WIKIタイトル';
+$lang['template'] = 'テンプレート';
+$lang['license'] = '作成した内容をどのライセンスでリリースしますか?';
+$lang['fullpath'] = 'ページのフッターに絶対パスを表示';
+$lang['recent'] = '最近の変更表示数';
+$lang['breadcrumbs'] = 'トレース(パンくず)表示数';
+$lang['youarehere'] = '現在位置を表示';
+$lang['typography'] = 'タイポグラフィー変換';
+$lang['htmlok'] = 'HTML埋め込み';
+$lang['phpok'] = 'PHP埋め込み';
+$lang['dformat'] = '日付フォーマット(PHPの<a href="http://www.php.net/strftime">strftime</a>関数を参照)';
+$lang['signature'] = '署名';
+$lang['toptoclevel'] = '目次 トップレベル見出し';
+$lang['tocminheads'] = '目次を生成するための最小見出し数';
+$lang['maxtoclevel'] = '目次 表示限度見出し';
+$lang['maxseclevel'] = '編集可能見出し';
+$lang['camelcase'] = 'キャメルケースリンク';
+$lang['deaccent'] = 'ページ名アクセント';
+$lang['useheading'] = '最初の見出しをページ名とする';
+$lang['refcheck'] = 'メディア参照元チェック';
+$lang['refshow'] = 'メディア参照元表示数';
+$lang['allowdebug'] = 'デバッグモード(<b>必要で無いときは無効にしてください</b>)';
+$lang['mediarevisions'] = 'メディアファイルの履歴を有効にしますか?';
+$lang['usewordblock'] = '単語リストに基づくスパムブロック';
+$lang['indexdelay'] = 'インデックスを許可(何秒後)';
+$lang['relnofollow'] = 'rel="nofollow"を付加';
+$lang['mailguard'] = 'メールアドレス保護';
+$lang['iexssprotect'] = 'アップロードファイルに悪意のあるJavaScriptやHTMLが含まれていないかチェックする';
+$lang['showuseras'] = '最終編集者の情報として表示する内容';
+$lang['useacl'] = 'アクセス管理を行う(ACL)';
+$lang['autopasswd'] = 'パスワードの自動生成(ACL)';
+$lang['authtype'] = '認証方法(ACL)';
+$lang['passcrypt'] = '暗号化方法(ACL)';
+$lang['defaultgroup'] = 'デフォルトグループ(ACL)';
+$lang['superuser'] = 'スーパーユーザー(ACL)';
+$lang['manager'] = 'マネージャー(特定の管理機能を使用可能なユーザーもしくはグループ)';
+$lang['profileconfirm'] = 'プロフィール変更時に現在のパスワードを要求(ACL)';
+$lang['disableactions'] = 'DokuWiki の動作を無効にする';
+$lang['disableactions_check'] = 'チェック';
+$lang['disableactions_subscription'] = '登録 / 解除';
+$lang['disableactions_wikicode'] = 'ソース閲覧 / 生データ出力';
+$lang['disableactions_other'] = 'その他の動作(カンマ区切り)';
+$lang['sneaky_index'] = 'デフォルトでは索引にすべての名前空間を表示しますが、この機能はユーザーに閲覧権限のない名前空間を非表示にします。ただし、閲覧が可能な副名前空間まで表示されなくなるため、ACLの設定が適正でない場合は索引機能が使えなくなる場合があります。';
+$lang['auth_security_timeout'] = '認証タイムアウト設定(秒)';
+$lang['securecookie'] = 'クッキーをHTTPSにてセットする場合は、ブラウザよりHTTPS経由で送信された場合にみに制限しますか?ログインのみをSSLで行う場合は、この機能を無効にしてください。';
+$lang['xmlrpc'] = 'XML-RPCインターフェースを有効/無効にする';
+$lang['xmlrpcuser'] = 'XML-RPCアクセスを指定グループとユーザーに制限します(半角コンマ区切り)。 すべての人にアクセスを許可する場合は空のままにしてください。';
+$lang['updatecheck'] = 'DokuWikiの更新とセキュリティに関する情報をチェックしますか? この機能は update.dokuwiki.org への接続が必要です。';
+$lang['userewrite'] = 'URLの書き換え';
+$lang['useslash'] = 'URL上の名前空間の区切りにスラッシュを使用';
+$lang['usedraft'] = '編集中の自動保存(ドラフト)機能を使用';
+$lang['sepchar'] = 'ページ名の単語区切り文字';
+$lang['canonical'] = 'canonical URL(正準URL)を使用';
+$lang['fnencode'] = '非アスキーファイル名のエンコーディング方法';
+$lang['autoplural'] = '自動複数形処理';
+$lang['compression'] = 'アーカイブファイルの圧縮方法';
+$lang['cachetime'] = 'キャッシュ保持時間(秒)';
+$lang['locktime'] = 'ファイルロック期限(秒)';
+$lang['fetchsize'] = '外部からのダウンロード最大サイズ';
+$lang['notify'] = '変更を通知するメールアドレス';
+$lang['registernotify'] = '新規ユーザー登録を通知するメールアドレス';
+$lang['mailfrom'] = 'メール送信時の送信元アドレス';
+$lang['mailprefix'] = '自動メールの題名に使用する接頭語';
+$lang['gzip_output'] = 'xhtmlに対するコンテンツ圧縮(gzip)を使用';
+$lang['gdlib'] = 'GDlibバージョン';
+$lang['im_convert'] = 'ImageMagick変換ツールへのパス';
+$lang['jpg_quality'] = 'JPG圧縮品質(0-100)';
+$lang['subscribers'] = '更新通知機能';
+$lang['subscribe_time'] = '購読リストと概要を送信する期間(秒)。「最近の変更とする期間」で指定した期間より小さくしてください。';
+$lang['compress'] = 'CSSとJavaScriptを圧縮';
+$lang['cssdatauri'] = 'HTTP リクエスト数によるオーバーヘッドを減らすため、CSS ファイルから参照される画像ファイルのサイズがここで指定するバイト数以内の場合は CSS ファイル内に Data URI として埋め込みます。このテクニックは IE7 以下では動作しません! <code>400</code> から <code>600</code> バイトがちょうどよい値です。<code>0</code> を指定すると埋め込み処理は行われません。';
+$lang['hidepages'] = '非公開ページ(Regex)';
+$lang['send404'] = '文書が存在しないページに"HTTP404/Page Not Found"を使用';
+$lang['sitemap'] = 'Googleサイトマップ作成頻度(日数)';
+$lang['broken_iua'] = 'ignore_user_abort関数が破損している恐れがあります。そのため、検索インデックスが動作しない可能性があります。IIS+PHP/CGIの組み合わせで破損することが判明しています。詳しくは<a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>を参照してください。';
+$lang['xsendfile'] = 'ウェブサーバーが静的ファイルを生成するために X-Sendfile ヘッダーを使用しますか?なお、この機能をウェブサーバーがサポートしている必要があります。';
+$lang['renderer_xhtml'] = 'Wikiの出力(xhtml)にレンダラーを使用する';
+$lang['renderer__core'] = '%s (Dokuwikiコア)';
+$lang['renderer__plugin'] = '%s (プラグイン)';
+$lang['rememberme'] = 'ログイン用クッキーを永久に保持することを許可(ログインを保持)';
+$lang['rss_type'] = 'RSSフィード形式';
+$lang['rss_linkto'] = 'RSS内リンク先';
+$lang['rss_content'] = 'XMLフィードに何を表示させますか?';
+$lang['rss_update'] = 'RSSフィードの更新間隔(秒)';
+$lang['recent_days'] = '最近の変更とする期間(日数)';
+$lang['rss_show_summary'] = 'フィードのタイトルにサマリーを表示';
+$lang['target____wiki'] = '内部リンクの表示先';
+$lang['target____interwiki'] = 'InterWikiリンクの表示先';
+$lang['target____extern'] = '外部リンクの表示先';
+$lang['target____media'] = 'メディアリンクの表示先';
+$lang['target____windows'] = 'Windowsリンクの表示先';
+$lang['proxy____host'] = 'プロキシ - サーバー名';
+$lang['proxy____port'] = 'プロキシ - ポート';
+$lang['proxy____user'] = 'プロキシ - ユーザー名';
+$lang['proxy____pass'] = 'プロキシ - パスワード';
+$lang['proxy____ssl'] = 'プロキシへの接続にsslを使用';
+$lang['proxy____except'] = 'スキップするプロキシのURL正規表現';
+$lang['safemodehack'] = 'セーフモード対策を行う';
+$lang['ftp____host'] = 'FTP サーバー名(セーフモード対策)';
+$lang['ftp____port'] = 'FTP ポート(セーフモード対策)';
+$lang['ftp____user'] = 'FTP ユーザー名(セーフモード対策)';
+$lang['ftp____pass'] = 'FTP パスワード(セーフモード対策)';
+$lang['ftp____root'] = 'FTP ルートディレクトリ(セーフモード対策)';
+$lang['license_o_'] = '選択されていません';
+$lang['typography_o_0'] = '無し';
+$lang['typography_o_1'] = '二重引用符(ダブルクオート)のみ';
+$lang['typography_o_2'] = 'すべての引用符(動作しない場合があります)';
+$lang['userewrite_o_0'] = '使用しない';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWikiによる設定';
+$lang['deaccent_o_0'] = '指定しない';
+$lang['deaccent_o_1'] = 'アクセントを除去';
+$lang['deaccent_o_2'] = 'ローマナイズ';
+$lang['gdlib_o_0'] = 'GDを利用できません';
+$lang['gdlib_o_1'] = 'バージョン 1.x';
+$lang['gdlib_o_2'] = '自動検出';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = '概要';
+$lang['rss_content_o_diff'] = '差分(Unified Diff)';
+$lang['rss_content_o_htmldiff'] = '差分(HTML形式)';
+$lang['rss_content_o_html'] = '完全なHTMLページ';
+$lang['rss_linkto_o_diff'] = '変更点のリスト';
+$lang['rss_linkto_o_page'] = '変更されたページ';
+$lang['rss_linkto_o_rev'] = 'リビジョンのリスト';
+$lang['rss_linkto_o_current'] = '現在のページ';
+$lang['compression_o_0'] = '圧縮しない';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = '使用しない';
+$lang['xsendfile_o_1'] = 'lighttpd ヘッダー(リリース1.5以前)';
+$lang['xsendfile_o_2'] = '標準 X-Sendfile ヘッダー';
+$lang['xsendfile_o_3'] = 'Nginx X-Accel-Redirect ヘッダー';
+$lang['showuseras_o_loginname'] = 'ログイン名';
+$lang['showuseras_o_username'] = 'ユーザーのフルネーム';
+$lang['showuseras_o_email'] = 'ユーザーのメールアドレス(メールガード設定による難読化)';
+$lang['showuseras_o_email_link'] = 'ユーザーのメールアドレスをリンクにする';
+$lang['useheading_o_0'] = '使用しない';
+$lang['useheading_o_navigation'] = 'ナビゲーションのみ';
+$lang['useheading_o_content'] = 'Wikiの内容のみ';
+$lang['useheading_o_1'] = '常に使用する';
+$lang['readdircache'] = 'readdir キャッシュの最大保持期間(秒)';
diff --git a/lib/plugins/config/lang/kk/lang.php b/lib/plugins/config/lang/kk/lang.php
new file mode 100644
index 000000000..dde5b9577
--- /dev/null
+++ b/lib/plugins/config/lang/kk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * kazakh language file
+ *
+ * @author Nurgozha Kaliaskarov astana08@gmail.com
+ */
diff --git a/lib/plugins/config/lang/ko/intro.txt b/lib/plugins/config/lang/ko/intro.txt
new file mode 100644
index 000000000..22dd96ef6
--- /dev/null
+++ b/lib/plugins/config/lang/ko/intro.txt
@@ -0,0 +1,9 @@
+====== 환경 설정 관리 ======
+
+DokuWiki 설치할 때 설정들을 변경하기 위해 사용하는 페이지입니다. 각 설정에 대한 자세한 도움말이 필요하다면 [[doku>ko:config|설정 문서(번역)]]와 [[doku>config|설정 문서(영문)]]를 참조합니다.
+
+플러그인에 대한 자세한 정보가 필요하다면 [[doku>plugin:config|플러그인 설정]]페이지를 참조합니다. 붉은 배경색으로 보이는 설정들은 이 플러인에서 변경하지 못하도록 되어있습니다. 파란 배경색으로 보이는 설정들은 기본 설정값을 가지고 있습니다. 흰색 배경색으로 보이는 설정들은 특별한 설치를 위해 설정되어 있습니다. 파란색과 흰색 배경 설정들이 수정 가능합니다.
+
+이페이지를 끝내기 전에 **저장**버튼을 누르지 않으면 설정값들은 적용되지 않습니다.
+
+
diff --git a/lib/plugins/config/lang/ko/lang.php b/lib/plugins/config/lang/ko/lang.php
new file mode 100644
index 000000000..20cfcdcfe
--- /dev/null
+++ b/lib/plugins/config/lang/ko/lang.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * korean language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author jk Lee
+ * @author dongnak@gmail.com
+ * @author Song Younghwan <purluno@gmail.com>
+ * @author SONG Younghwan <purluno@gmail.com>
+ * @author Seung-Chul Yoo <dryoo@live.com>
+ */
+$lang['menu'] = '환경 설정';
+$lang['error'] = '잘못된 값때문에 설정들을 변경할 수 없습니다. 수정한 값들을 검사하고 확인을 누르기 바랍니다.
+ <br />잘못된 값(들)은 붉은 선으로 둘러싸여 있습니다.';
+$lang['updated'] = '설정이 성공적으로 변경되었습니다.';
+$lang['nochoice'] = '(다른 선택이 불가능합니다.)';
+$lang['locked'] = '환경 설정 파일을 수정할 수 없습니다. 의도된 행동이 아니라면,<br /> 파일이름과 권한이 맞는지 확인하기 바랍니다. ';
+$lang['danger'] = '위험 : 이 옵션을 잘못 수정하면 환경설정 메뉴를 사용할 수 없을 수도 있습니다.';
+$lang['warning'] = '경고 : 이 옵션을 잘못 수정하면 잘못 동작 할 수 있습니다.';
+$lang['security'] = '보안 경고 : 이 옵션은 보안에 위험이 있을 수 있습니다.';
+$lang['_configuration_manager'] = '환경 설정 관리자';
+$lang['_header_dokuwiki'] = 'DokuWiki 설정';
+$lang['_header_plugin'] = 'Plugin 설정';
+$lang['_header_template'] = 'Template 설정';
+$lang['_header_undefined'] = '정의되지 않은 설정';
+$lang['_basic'] = '기본 설정';
+$lang['_display'] = '화면 표시 설정';
+$lang['_authentication'] = '인증 설정';
+$lang['_anti_spam'] = '안티-스팸 설정';
+$lang['_editing'] = '편집 설정';
+$lang['_links'] = '링크 설정';
+$lang['_media'] = '미디어 설정';
+$lang['_advanced'] = '진보된 설정';
+$lang['_network'] = '네트워크 설정';
+$lang['_plugin_sufix'] = 'Plugin 설정';
+$lang['_template_sufix'] = 'Template 설정';
+$lang['_msg_setting_undefined'] = '설정되지 않은 메타데이타.';
+$lang['_msg_setting_no_class'] = '설정되지 않은 클래스.';
+$lang['_msg_setting_no_default'] = '기본값 없음.';
+$lang['fmode'] = '파일 생성 모드';
+$lang['dmode'] = '디렉토리 생성 모드';
+$lang['lang'] = '언어';
+$lang['basedir'] = '기본 디렉토리';
+$lang['baseurl'] = '기본 URL';
+$lang['savedir'] = '데이타 저장 디렉토리';
+$lang['start'] = '시작 페이지 이름';
+$lang['title'] = '위키 제목';
+$lang['template'] = '템플릿';
+$lang['license'] = '컨텐트에 어떤 라이센스 정책을 적용하시겠습니까?';
+$lang['fullpath'] = '페이지 하단에 전체 경로 보여주기';
+$lang['recent'] = '최근에 바뀐 것';
+$lang['breadcrumbs'] = '위치 추적 수';
+$lang['youarehere'] = '계층형 위치 추적';
+$lang['typography'] = '기호 대체';
+$lang['htmlok'] = 'HTML 내장 허용';
+$lang['phpok'] = 'PHP 내장 허용';
+$lang['dformat'] = '날짜 포맷 (PHP <a href="http://www.php.net/strftime">strftime</a> 기능) 참조';
+$lang['signature'] = '서명';
+$lang['toptoclevel'] = '목차 최상위 항목';
+$lang['tocminheads'] = '목차 표시 여부를 결정할 최소한의 표제 항목의 수';
+$lang['maxtoclevel'] = '목차 최대 단계';
+$lang['maxseclevel'] = '섹션 최대 편집 단계';
+$lang['camelcase'] = '링크에 CamelCase 사용';
+$lang['deaccent'] = '악센트 없는 페이지 이름';
+$lang['useheading'] = '페이지 이름으로 첫 헤드라인 사용';
+$lang['refcheck'] = '미디어 참조 검사';
+$lang['refshow'] = '보여줄 미디어 참조 수';
+$lang['allowdebug'] = '디버그 허용 <b>필요하지 않으면 금지!</b>';
+$lang['usewordblock'] = '금지단어를 사용해 스팸 막기';
+$lang['indexdelay'] = '색인 연기 시간(초)';
+$lang['relnofollow'] = '외부 링크에 rel="nofollow" 사용';
+$lang['mailguard'] = '이메일 주소를 알아볼 수 없게';
+$lang['iexssprotect'] = '업로드 파일의 악성 Javascript, HTML 코드 가능성 여부를 검사';
+$lang['showuseras'] = '마지막으로 페이지를 수정한 사용자를 보여줄지 여부';
+$lang['useacl'] = '접근 제어 목록(ACL) 사용';
+$lang['autopasswd'] = '자동으로 만들어진 패스워드';
+$lang['authtype'] = '인증 백-엔드';
+$lang['passcrypt'] = '패스워드 암호화 방법';
+$lang['defaultgroup'] = '기본 그룹';
+$lang['superuser'] = '슈퍼 유저';
+$lang['manager'] = '관리자 - 관리 기능들을 사용할 수 있는 그룹이나 사용자';
+$lang['profileconfirm'] = '개인정보 변경시 암호 재확인';
+$lang['disableactions'] = 'DokuWiki Action 금지';
+$lang['disableactions_check'] = '검사';
+$lang['disableactions_subscription'] = '구독 신청/해지';
+$lang['disableactions_wikicode'] = '문서 소스 보기';
+$lang['disableactions_other'] = '다른 Action(comma로 구분)';
+$lang['sneaky_index'] = '기본적으로, DokuWiki는 색인 목록에 모든 네임스페이스들을 보여줍니다.
+이 옵션을 설정하면 사용자가 읽기 권한을 가지고 있지 않은 네임스페이스들은 보여주지 않습니다. 접근 가능한 하위 네임스페이스들 보이지않게 설정하면 자동으로 설정됩니다.
+특정 ACL 설정은 색인 사용이 불가능하게 할 수도 있습니다.';
+$lang['auth_security_timeout'] = '인증 보안 초과 시간(초)';
+$lang['securecookie'] = 'HTTPS로 보내진 쿠키는 HTTPS에만 적용 할까요? 위키의 로그인 페이지만 SSL로 암호화 하고 위키 페이지는 그렇지 않은경우 꺼야 합니다.';
+$lang['xmlrpc'] = 'XML-RPC 인터페이스 지원/무시';
+$lang['xmlrpcuser'] = '주어진 그룹이나 유저들에게만 XML-RPC접근을 허락하려면 컴마로 구분하여 적으세요. 비어두면 모두에게 허용됩니다.';
+$lang['updatecheck'] = '업데이트와 보안 문제를 검사(DokuWiki를 update.dokuwiki.org에 연결해야 합니다.)';
+$lang['userewrite'] = 'URL rewriting기능 사용';
+$lang['useslash'] = 'URL에서 네임스페이스 구분자로 슬래쉬 문자 사용';
+$lang['usedraft'] = '편집하는 동안 자동으로 문서 초안 저장';
+$lang['sepchar'] = '페이지 이름 단어 구분자';
+$lang['canonical'] = '완전한 canonical URL 사용';
+$lang['fnencode'] = '아스키가 아닌 파일이름을 인코딩 하는 방법.';
+$lang['autoplural'] = '링크 연결시 plural폼 검사';
+$lang['compression'] = 'attic파일 압축 방법 선택';
+$lang['cachetime'] = '최대 캐쉬 생존 시간(초)';
+$lang['locktime'] = '쵀대 파일 잠금 시간(초)';
+$lang['fetchsize'] = 'fetch.php가 외부에서 다운로드할 수도 있는 최대 크기(바이트)';
+$lang['notify'] = '이메일 알람 기능';
+$lang['registernotify'] = '신규 등록자 알람 기능';
+$lang['mailfrom'] = '자동으로 보내지는 메일 발신자';
+$lang['mailprefix'] = '자동으로 보내지는 메일의 제목 말머리 내용';
+$lang['gzip_output'] = 'xhml 내용 gzip 압축 여부';
+$lang['gdlib'] = 'GD 라이브러리 버전';
+$lang['im_convert'] = 'ImageMagick 위치';
+$lang['jpg_quality'] = 'JPG 압축 품질 (0-100)';
+$lang['subscribers'] = '페이지 갱신 알람 기능';
+$lang['subscribe_time'] = ' 구독 목록과 요약이 보내질 경과 시간 (초); 이 것은 recent_days에서 설정된 시간보다 작아야 합니다.';
+$lang['compress'] = '최적화된 CSS, javascript 출력';
+$lang['hidepages'] = '매칭된 페이지 숨기기(정규표현식)';
+$lang['send404'] = '존재하지 않는 페이지에 대해 "HTTP 404/Page Not Found" 응답';
+$lang['sitemap'] = '구글 사이트맵 생성(날짜)';
+$lang['broken_iua'] = '설치된 시스템에서 ignore_user_abort 기능에 문제가 있으면 색인이 정상적으로 동작하지 않습니다. 이 기능이 IIS+PHP/CGI에서 문제가 있는 것으로 알려졌습니다. 자세한 정보는 <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>를 참고하기 바랍니다.';
+$lang['xsendfile'] = '웹 서버 static 파일 전송 지원을 위해 X-Sendfile 헤더를 사용한다면 이 옵션을 사용합니다.
+웹 서버가 이 기능을 지원해야 합니다.';
+$lang['renderer_xhtml'] = '주 (xhtml) 위키 출력 처리기';
+$lang['renderer__core'] = '%s (DokuWiki 내부 기능)';
+$lang['renderer__plugin'] = '%s (DokuWiki 플러그인)';
+$lang['rememberme'] = '로그인 정보 저장 허용';
+$lang['rss_type'] = 'XML feed 타잎';
+$lang['rss_linkto'] = 'XML feed 링크 정보';
+$lang['rss_content'] = 'XML feed 항목들에 표시되는 내용은?';
+$lang['rss_update'] = 'XML feed 갱신 주기(초)';
+$lang['recent_days'] = '최근 바뀐 페이지 기준 시간(날짜)';
+$lang['rss_show_summary'] = 'XML feed 제목에서 요약정보 보여주기';
+$lang['target____wiki'] = '내부 링크들에 대한 타겟 윈도우 ';
+$lang['target____interwiki'] = 'InterWiki 링크들에 대한 타겟 윈도우';
+$lang['target____extern'] = '외부 링크들에 대한 타겟 윈도우';
+$lang['target____media'] = '미디어 링크들에 대한 타겟 윈도우';
+$lang['target____windows'] = '윈도우 링크들에 대한 타겟 윈도우';
+$lang['proxy____host'] = '프록시 서버 이름';
+$lang['proxy____port'] = '프록시 서버 포트';
+$lang['proxy____user'] = '프록시 사용자 이름';
+$lang['proxy____pass'] = '프록시 패스워드';
+$lang['proxy____ssl'] = '프록시 연결시 ssl사용';
+$lang['proxy____except'] = '프록시설정이 무시될 URL주소들의 RegEx형식표현';
+$lang['safemodehack'] = 'safemode hack기능 사용';
+$lang['ftp____host'] = 'safemode hack의 FTP 서버';
+$lang['ftp____port'] = 'safemode hack의 FTP port';
+$lang['ftp____user'] = 'safemode hack의 FTP 사용자 이름';
+$lang['ftp____pass'] = 'safemode hack의 FTP 패스워드';
+$lang['ftp____root'] = 'safemode hack의 FTP 루트 디렉토리';
+$lang['license_o_'] = '선택하지 않음';
+$lang['typography_o_0'] = '사용 안함';
+$lang['typography_o_1'] = '이중 인용부호("")만 지원';
+$lang['typography_o_2'] = '모든 가능한 인용 부호 (동작 안될 수도 있음)';
+$lang['userewrite_o_0'] = '사용 안함';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki 내부 기능';
+$lang['deaccent_o_0'] = '사용 안함';
+$lang['deaccent_o_1'] = '악센트 제거';
+$lang['deaccent_o_2'] = '라틴문자화';
+$lang['gdlib_o_0'] = 'GD 라이브러리 사용 불가';
+$lang['gdlib_o_1'] = '버전 1.x';
+$lang['gdlib_o_2'] = '자동 인식';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = '개요';
+$lang['rss_content_o_diff'] = '통합 차이점 목록';
+$lang['rss_content_o_htmldiff'] = '차이점 목록 (HTML 테이블)';
+$lang['rss_content_o_html'] = '내용 (HTML 페이지)';
+$lang['rss_linkto_o_diff'] = '차이점 보기';
+$lang['rss_linkto_o_page'] = '변경 페이지 보기';
+$lang['rss_linkto_o_rev'] = '변경 목록 보기';
+$lang['rss_linkto_o_current'] = '최근 페이지 보기';
+$lang['compression_o_0'] = '없음';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = '사용 불가';
+$lang['xsendfile_o_1'] = '비공개 lighttpd 헤더 (1.5 이전 버전)';
+$lang['xsendfile_o_2'] = '표준 X-Sendfile 헤더';
+$lang['xsendfile_o_3'] = '비공개 Nginx X-Accel-Redirect 헤더';
+$lang['showuseras_o_loginname'] = '로그인 이름';
+$lang['showuseras_o_username'] = '사용자 이름';
+$lang['showuseras_o_email'] = '사용자 e-mail 주소(메일주소 보호 셋팅에 따라 안보일 수 있음)';
+$lang['showuseras_o_email_link'] = 'mailto: link로 표현될 사용자 e-mail 주소';
+$lang['useheading_o_0'] = '아니요';
+$lang['useheading_o_navigation'] = '네비게이션에만';
+$lang['useheading_o_content'] = '위키 내용에만';
+$lang['useheading_o_1'] = '항상';
+$lang['readdircache'] = 'readdir 캐쉬를 위한 최대 시간 (초)';
diff --git a/lib/plugins/config/lang/la/intro.txt b/lib/plugins/config/lang/la/intro.txt
new file mode 100644
index 000000000..573d34ac1
--- /dev/null
+++ b/lib/plugins/config/lang/la/intro.txt
@@ -0,0 +1,7 @@
+====== Optionum Administratio ======
+
+In hac pagina administratoris optiones mutare et inspicere potes. Auxilia in pagina [[doku>config|conformationis]] sunt, si singulas res uidere uis, i ad paginam [[doku>plugin:config|conformationis]].
+
+Optiones ostensae rubro colore tutae et non nunc mutabiles sunt. Optiones ostensae caeruleo colore praecipuae sunt et optiones ostensae in area alba singulares huic uici sunt. Et caerulae et albae optiones mutabiles sunt.
+
+Memento premere **SERVA** ante quam nouam paginam eas: si hoc non facias, mutata amissa sunt. \ No newline at end of file
diff --git a/lib/plugins/config/lang/la/lang.php b/lib/plugins/config/lang/la/lang.php
new file mode 100644
index 000000000..07d92ae36
--- /dev/null
+++ b/lib/plugins/config/lang/la/lang.php
@@ -0,0 +1,181 @@
+<?php
+/**
+ * Latin language file
+ *
+ * @author Massimiliano Vassalli <vassalli.max@gmail.com>
+ */
+$lang['menu'] = 'Optiones Administrationis';
+$lang['error'] = 'Optiones non nouatae ob errores: rursum temptat. Errores rubro colore signati sunt.';
+$lang['updated'] = 'Optiones feliciter nouatae.';
+$lang['nochoice'] = '(nulla optio est)';
+$lang['locked'] = 'Optio documenti non nouata est, <br/> optiones et facultates documenti inspicis.';
+$lang['danger'] = 'CAVE: si has optiones mutabis, in administrationis indicem non inire potes.';
+$lang['warning'] = 'CAVE: si hae optiones mutabis, graues errores erunt.';
+$lang['security'] = 'CAVE: si hae optiones mutabis, graues errores erunt.';
+$lang['_configuration_manager'] = 'Optionum administratio';
+$lang['_header_dokuwiki'] = 'Vicis Optiones';
+$lang['_header_plugin'] = 'Addendorum Optiones';
+$lang['_header_template'] = 'Vicis Formae Optiones';
+$lang['_header_undefined'] = 'Variae Optiones';
+$lang['_basic'] = 'Praecipuae Optiones';
+$lang['_display'] = 'Speciei Optiones';
+$lang['_authentication'] = 'Confirmationis Optiones';
+$lang['_anti_spam'] = 'In Mala Optiones';
+$lang['_editing'] = 'Recensendi Optiones';
+$lang['_links'] = 'Nexi Optiones';
+$lang['_media'] = 'Visiuorum Optiones';
+$lang['_advanced'] = 'Maiores Optiones';
+$lang['_network'] = 'Interretis Optiones';
+$lang['_plugin_sufix'] = 'Addendorum Optiones';
+$lang['_template_sufix'] = 'Vicis Formae Optiones';
+$lang['_msg_setting_undefined'] = 'Res codicum sine optionibus.';
+$lang['_msg_setting_no_class'] = 'Classes sine optionibus';
+$lang['_msg_setting_no_default'] = 'Nihil';
+$lang['fmode'] = 'Documentum creandum ratio';
+$lang['dmode'] = 'Scrinia creandam ratio';
+$lang['lang'] = 'Linguae optiones';
+$lang['basedir'] = 'Computatoris seruitoris domicilium (ex. <code>/dokuwiki/</code>). Nihil scribere si id machinatione agnoscere uis.';
+$lang['baseurl'] = 'Computatoris seruitoris VRL (ex. <code>http://www.yourserver.com</code>). Nihil scribere si id machinatione agnoscere uis.';
+$lang['savedir'] = 'Documentorum seruatorum domicilium';
+$lang['start'] = 'Nomen paginae dominicae';
+$lang['title'] = 'Vicis titulus';
+$lang['template'] = 'Vicis forma';
+$lang['license'] = 'Sub quibus legibus uicem creare uin?';
+$lang['fullpath'] = 'Totum domicilium paginae in pedibus scribis.';
+$lang['recent'] = 'Extremae mutationes';
+$lang['breadcrumbs'] = 'Numerus uestigiorum';
+$lang['youarehere'] = 'Ordo uestigiorum';
+$lang['typography'] = 'Signa supponentes';
+$lang['htmlok'] = 'HTML aptum facere';
+$lang['phpok'] = 'PHP aptum facere';
+$lang['dformat'] = 'Forma diei (uide paginam <a href="http://www.php.net/strftime">de diebus</a>)';
+$lang['signature'] = 'Subscriptio';
+$lang['toptoclevel'] = 'Gradus maior tabularum argumentorum';
+$lang['tocminheads'] = 'Minimus numerus capitum';
+$lang['maxtoclevel'] = 'Maximus numerus tabularum argumentorum';
+$lang['maxseclevel'] = 'Maxima pars gradus recensendi';
+$lang['camelcase'] = 'SignaContinua nexis apta facere';
+$lang['deaccent'] = 'Titulus paginarum abrogare';
+$lang['useheading'] = 'Capite primo ut titulo paginae uti';
+$lang['refcheck'] = 'Documenta uisiua inspicere';
+$lang['refshow'] = 'Numerus documentorum ostendorum';
+$lang['allowdebug'] = '<b>ineptum facias si non necessarium!</b> aptum facere';
+$lang['usewordblock'] = 'Malum interretiale ob uerba delere';
+$lang['indexdelay'] = 'Tempus transitum in ordinando (sec)';
+$lang['relnofollow'] = 'rel="nofollow" externis nexis uti';
+$lang['mailguard'] = 'Cursus interretiales abscondere';
+$lang['iexssprotect'] = 'Documenta nouata ob mala JavaScript uel HTML inspicere';
+$lang['showuseras'] = 'Quid, cum Sodalem, qui extremus paginam recensuit, ostendat, scribere';
+$lang['useacl'] = 'Aditus inspectionis indicibus uti';
+$lang['autopasswd'] = 'Tessera machinatione generata';
+$lang['authtype'] = 'Confirmationis finis';
+$lang['passcrypt'] = 'Ratio tesserae tuendae';
+$lang['defaultgroup'] = 'Grex communis';
+$lang['superuser'] = 'Magister\stra - grex, Sodalis uel index diuisus a uigulis sodalis1,@grex,sodalis2 cum plenis facultatibus sine ICA optionum termino';
+$lang['manager'] = 'Administrator - grex, Sodalis uel index diuisus a uigulis sodalis1,@grex,sodalis2 cum certis facultatibus';
+$lang['profileconfirm'] = 'Mutationes tessera confirmanda sunt';
+$lang['disableactions'] = 'Vicis actiones ineptas facere';
+$lang['disableactions_check'] = 'Inspicere';
+$lang['disableactions_subscription'] = 'Inscribe/Delere';
+$lang['disableactions_wikicode'] = 'Fontem uidere/Rudem transcribere';
+$lang['disableactions_other'] = 'Aliae actiones (uirgulis diuisae)';
+$lang['sneaky_index'] = 'Hic uicis omnia genera in indice inserit. Si ineptam hanc optionem facias, solum ea, quae Sodales uidere possunt, in indice erunt. Hoc suggreges et suggenera abscondere potest.';
+$lang['auth_security_timeout'] = 'Confirmationis Tempus (secundis)';
+$lang['securecookie'] = 'Formulae HTTPS mittine solum per HTTPS possunt? Ineptam hanc optio facias, si accessus uicis tutus est, sed interretis non.';
+$lang['xmlrpc'] = 'Aptam\Ineptam XML-RPC administrationem facere';
+$lang['xmlrpcuser'] = 'Accessus XML-RPC gregibus uel Sodalibus in hoc indice astringere. Nihil scribere ut omnes accessum habeant';
+$lang['updatecheck'] = 'Nouationes et fiducias inspicerene? Hic uicis connectere update.dokuwiki.org debes.';
+$lang['userewrite'] = 'VRL formosis uti';
+$lang['useslash'] = 'Repagula in URL, ut genera diuidas, uti';
+$lang['usedraft'] = 'Propositum in recensione machinatione seruatur';
+$lang['sepchar'] = 'Signum, quod paginas diuidit';
+$lang['canonical'] = 'VRL perfecto uti';
+$lang['fnencode'] = 'Ratio quae nomen documentorum non-ASCII codificit';
+$lang['autoplural'] = 'Pluralia in nexis inspicere';
+$lang['compression'] = 'Ratio compressionis documentis "attic"';
+$lang['cachetime'] = 'Maximum tempus formulis (sec)';
+$lang['locktime'] = 'Maximum tempus documentis inclusis (sec)';
+$lang['fetchsize'] = 'Maximum pondus (bytes), quod fetch.php ab externis onerare potest';
+$lang['notify'] = 'Adnotationis mutationes ad hunc cursum mittere';
+$lang['registernotify'] = 'De nouis Sodalibus ad hunc cursum notas mittere';
+$lang['mailfrom'] = 'Cursus interretialis, quo in cursibus uti';
+$lang['gzip_output'] = 'gzip Argumentum-Codificans xhtml uti';
+$lang['gdlib'] = 'GD Lib forma';
+$lang['im_convert'] = 'Domicilium machinae ImageMagick\'s';
+$lang['jpg_quality'] = 'JPG compressio colorum (0-100)';
+$lang['subscribers'] = 'Inscriptionis paginarum auxilium aptus facere';
+$lang['subscribe_time'] = 'Tempus post quod inscriptionum index et summa missa sunt (sec); Hic minor quam tempus declaratum fortasse est.';
+$lang['compress'] = 'CSS et javascript dimissio';
+$lang['hidepages'] = 'Paginas congruentes abscondere (uerba regularia)';
+$lang['send404'] = 'Mitte "HTTP 404/ Pagina non reperta" si paginae non sunt.';
+$lang['sitemap'] = 'Google formam situs gignere (dies)';
+$lang['broken_iua'] = 'ignore_user_abort functio inepta estne? Hoc indicem quaestionum, quae non aptae sunt, creare non potest. IIS+PHP/CGI ineptum est. Vide <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>';
+$lang['xsendfile'] = 'X-Sendfile utine ut seruitor interretialis documenta firma creet? Tuus seruitor interretialis hunc pati debes.';
+$lang['renderer_xhtml'] = 'Quid dimittere ut hoc in principio uicis (xhtml) utaris';
+$lang['renderer__core'] = '%s (uicis nucleus)';
+$lang['renderer__plugin'] = '%s (addenda)';
+$lang['rememberme'] = 'Formulas aditus aptas facere (memento me)';
+$lang['rss_type'] = 'XML summae genus';
+$lang['rss_linkto'] = 'XML summae connectio';
+$lang['rss_content'] = 'Quid in XML summis uidere?';
+$lang['rss_update'] = 'XML summae renouationis interuallum temporis';
+$lang['recent_days'] = 'Numerus mutationum recentium tenendorum (dies)';
+$lang['rss_show_summary'] = 'XML summa titulos ostendit';
+$lang['target____wiki'] = 'Fenestra nexis internis';
+$lang['target____interwiki'] = 'Fenestra nexis inter uicem';
+$lang['target____extern'] = 'Fenestra nexis externis';
+$lang['target____media'] = 'Fenestra nexis uisiuis';
+$lang['target____windows'] = 'Fenestra nexis fenestrarum';
+$lang['proxy____host'] = 'Proxis seruitoris nomen';
+$lang['proxy____port'] = 'Proxis portus';
+$lang['proxy____user'] = 'Proxis nomen sodalis';
+$lang['proxy____pass'] = 'Proxis tessera';
+$lang['proxy____ssl'] = 'SSL ut connectas uti';
+$lang['proxy____except'] = 'Verba, ut VRL inspicias, quibus Proxis non agnoscitur.';
+$lang['safemodehack'] = 'Ad tempus conseruatio apta facere';
+$lang['ftp____host'] = 'FTP computator seruitor ad tempus seruatis';
+$lang['ftp____port'] = 'FTP ianua ad tempus seruatis';
+$lang['ftp____user'] = 'FTP Sodalis ad tempus seruatis';
+$lang['ftp____pass'] = 'FTP tessera ad tempus seruatis';
+$lang['ftp____root'] = 'FTP domicilium ad tempus seruatis';
+$lang['license_o_'] = 'Nihil electum';
+$lang['typography_o_0'] = 'neuter';
+$lang['typography_o_1'] = 'sine singulis uirgulis';
+$lang['typography_o_2'] = 'cum singulis uirgulis';
+$lang['userewrite_o_0'] = 'neuter';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki domesticus';
+$lang['deaccent_o_0'] = 'ex';
+$lang['deaccent_o_1'] = 'accentum tollere';
+$lang['deaccent_o_2'] = 'Latinis litteris';
+$lang['gdlib_o_0'] = 'GD Lib inepta';
+$lang['gdlib_o_1'] = 'Forma 1.x';
+$lang['gdlib_o_2'] = 'Machinatione inspicere';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Summa';
+$lang['rss_content_o_diff'] = 'Comparatio una';
+$lang['rss_content_o_htmldiff'] = 'Tabulae HTML formatae comparatae';
+$lang['rss_content_o_html'] = 'Pagina cum HTML';
+$lang['rss_linkto_o_diff'] = 'discrimina uidere';
+$lang['rss_linkto_o_page'] = 'pagina recensita';
+$lang['rss_linkto_o_rev'] = 'recensionum index';
+$lang['rss_linkto_o_current'] = 'hic pagina';
+$lang['compression_o_0'] = 'neuter';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'Noli uti';
+$lang['xsendfile_o_2'] = 'Praecipuus X-Sendfile';
+$lang['xsendfile_o_3'] = 'Proprietarius Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Sodalis nomen';
+$lang['showuseras_o_username'] = 'Sodalis nomen uerum';
+$lang['showuseras_o_email'] = 'Sodalis cursus interretialis (absconditus ut is tueratur)';
+$lang['showuseras_o_email_link'] = 'Sodalis cursus interretialis ut mailto: nexum';
+$lang['useheading_o_0'] = 'Numquam';
+$lang['useheading_o_navigation'] = 'Solum adspicere';
+$lang['useheading_o_content'] = 'Solum uicis argumentum';
+$lang['useheading_o_1'] = 'Semper';
+$lang['readdircache'] = 'Maximum tempus readdir (sec)';
diff --git a/lib/plugins/config/lang/lb/intro.txt b/lib/plugins/config/lang/lb/intro.txt
new file mode 100644
index 000000000..964ee851c
--- /dev/null
+++ b/lib/plugins/config/lang/lb/intro.txt
@@ -0,0 +1,7 @@
+====== Konfiguratioun ======
+
+Dëses Plugin hëlleft der bei der Konfiguratioun vun DokuWiki. Hëllef zu deenen eenzelnen Astellungen fënns de ënner [[doku>config]]. Méi Informatiounen zu dësem Plugin kriss de ënner [[doku>plugin:config]].
+
+Astellungen mat engem hellrouden Hannergrond si geséchert a kënnen net mat dësem Plugin verännert ginn. Astellungen mat hellbloem Hannergrond si Virastellungen, wäiss hannerluechte Felder weisen lokal verännert Werter un. Souwuel dié blo wéi och déi wäiss Felder kënne verännert ginn.
+
+Vergiess w.e.g. net **Späicheren** ze drécken iers de d'Säit verléiss, anescht ginn all deng Ännerungen verluer.
diff --git a/lib/plugins/config/lang/lb/lang.php b/lib/plugins/config/lang/lb/lang.php
new file mode 100644
index 000000000..59acdf7a8
--- /dev/null
+++ b/lib/plugins/config/lang/lb/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * lb language file
+ *
+ * @author joel@schintgen.net
+ */
diff --git a/lib/plugins/config/lang/lt/intro.txt b/lib/plugins/config/lang/lt/intro.txt
new file mode 100644
index 000000000..ac3c2f6e8
--- /dev/null
+++ b/lib/plugins/config/lang/lt/intro.txt
@@ -0,0 +1,7 @@
+====== Konfiguracijos Administravimas ======
+
+Naudokite šį puslapį Dokuwiki instaliacijos tvarkymui. Pagalba individualiems nustatymams [[doku>config]]. Daugiau informacijos apie šį priedą [[doku>plugin:config]].
+
+Nustatymai raudoname fone yra apsaugoti nuo pakeitimų ir negali būti pakeisti šio įrankio pagalba. Nustatymai mėlyname fone nustatyti pagal nutylėjimą, o baltame fone nustatyti lokaliai būtent šiai instaliacijai. Nustatymai mėlyname ir baltame fone gali būti keičiami.
+
+Prieš paliekant ši puslapį, nepamirškite išsaugoti pakeitimus, tai galite padaryti nuspaudę **SAVE** mygtuką, kitu atveju pakeitimai nebus išsaugoti.
diff --git a/lib/plugins/config/lang/lt/lang.php b/lib/plugins/config/lang/lt/lang.php
new file mode 100644
index 000000000..eff7f0e4a
--- /dev/null
+++ b/lib/plugins/config/lang/lt/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Lithuanian language file
+ *
+ * @author audrius.klevas@gmail.com
+ * @author Arunas Vaitekunas <aras@fan.lt>
+ */
+$lang['lang'] = 'Kalba';
+$lang['template'] = 'Paruoštukas';
+$lang['recent'] = 'Paskutiniai taisymai';
+$lang['disableactions_check'] = 'Patikrinti';
+$lang['xsendfile_o_1'] = 'Firminė lighthttpd antraštė (prieš 1.5 išleidimą)';
+$lang['xsendfile_o_2'] = 'Standartinė X-Sendfile antraštė';
+$lang['xsendfile_o_3'] = 'Firminė Nginx X-Accel-Redirect antraštė';
+$lang['showuseras_o_loginname'] = 'Prisijungimo vardas';
+$lang['showuseras_o_username'] = 'Vartotojo pilnas vardas';
+$lang['showuseras_o_email'] = 'Vartotojo el. pašto adresas (pasak pašto apsaugos yra netinkamas)';
+$lang['showuseras_o_email_link'] = 'Vartotojo el. pašto adresas kaip mailto: nuoroda';
+$lang['useheading_o_0'] = 'Niekada';
+$lang['useheading_o_navigation'] = 'Tik Navigacija';
+$lang['useheading_o_content'] = 'Tik Wiki Turinys';
+$lang['useheading_o_1'] = 'Visada';
diff --git a/lib/plugins/config/lang/lv/intro.txt b/lib/plugins/config/lang/lv/intro.txt
new file mode 100644
index 000000000..e4d8d4526
--- /dev/null
+++ b/lib/plugins/config/lang/lv/intro.txt
@@ -0,0 +1,7 @@
+====== Konfigurācijas vednis ======
+
+Lapā var uzdot DokuWiki instalācijas iestatījumus. Palīdzību par atsevišķiem iestatījumiem meklēt [[doku>config]]. Sīkākas ziņas par šo moduli skatīt [[doku>plugin:config]].
+
+Ar sarkanu fonu parādītie iestatījumi ir aizsargāti un ar šo moduli nav labojami. Ar zilu fonu parādītie iestatījumi ir noklusētās vērtības, bet uz balta fona parādīti programmas lokālie iestatījumi . Gan zilos, gan baltos var labot.
+
+Pirms aizej no šīs lapas, atceries nopsiest pogu **SAGLABĀT**, lai nezustu veiktās izmaiņas.
diff --git a/lib/plugins/config/lang/lv/lang.php b/lib/plugins/config/lang/lv/lang.php
new file mode 100644
index 000000000..2f5883269
--- /dev/null
+++ b/lib/plugins/config/lang/lv/lang.php
@@ -0,0 +1,185 @@
+<?php
+/**
+ * Latvian, Lettish language file
+ *
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['menu'] = 'Konfigurācijas iestatījumi.';
+$lang['error'] = 'Iestatījumi nav saglabāti, jo uzdotas aplamas vērtības. Lūdzu pārskatīt izmaiņas un saglabāt atkārtoti.
+<br /> Aplamās vērtības izceltas sarkanā rāmī.';
+$lang['updated'] = 'Iestatījumi veiksmīgi saglabāti.';
+$lang['nochoice'] = '(citu iespēju nav)';
+$lang['locked'] = 'Iestatījumu fails nav grozāms, ja tā nevajag būt, <br />
+pārliecinies, ka ir pareizs lokālo iestatījuma faila vārds un tiesības.';
+$lang['danger'] = 'Bīstami: Šī parametra maiņa var padarīt wiki sistēmu un konfigurācijas izvēlni nepieejamu.';
+$lang['warning'] = 'Brīdinājums: Šī parametra maiņa var izraisīt negaidītu programmas uzvedību.';
+$lang['security'] = 'Drošības brīdinājums: Šī parametra maiņa var būt riskanta drošībai.';
+$lang['_configuration_manager'] = 'Konfigurācijas pārvaldnieks';
+$lang['_header_dokuwiki'] = 'Dokuwiki iestatījumi';
+$lang['_header_plugin'] = 'Moduļu iestatījumi';
+$lang['_header_template'] = 'Šablonu iestatījumi';
+$lang['_header_undefined'] = 'Citi iestatījumi';
+$lang['_basic'] = 'Pamatiestatījumi';
+$lang['_display'] = 'Izskata iestatījumi';
+$lang['_authentication'] = 'Autentifikācija';
+$lang['_anti_spam'] = 'Pretspama iestatījumi';
+$lang['_editing'] = 'Labošanas iestatījumi';
+$lang['_links'] = 'Saišu iestatījumi';
+$lang['_media'] = 'Mēdiju iestatījumi';
+$lang['_advanced'] = 'Smalkāka iestatīšana';
+$lang['_network'] = 'Tīkla iestatījumi';
+$lang['_plugin_sufix'] = 'moduļa iestatījumi';
+$lang['_template_sufix'] = 'šablona iestatījumi';
+$lang['_msg_setting_undefined'] = 'Nav atrodami iestatījumu metadati';
+$lang['_msg_setting_no_class'] = 'Nav iestatījumu klases';
+$lang['_msg_setting_no_default'] = 'Nav noklusētās vērtības';
+$lang['fmode'] = 'Tiesības izveidotajiem failiem';
+$lang['dmode'] = 'Tiesības izveidotajām direktorijām';
+$lang['lang'] = 'Valoda';
+$lang['basedir'] = 'Saknes direktorija';
+$lang['baseurl'] = 'Saknes adrese (URL)';
+$lang['savedir'] = 'Direktorija datu glabāšanai';
+$lang['start'] = 'Sākumlapas vārds';
+$lang['title'] = 'Wiki virsraksts';
+$lang['template'] = 'Šablons';
+$lang['license'] = 'Ar kādu licenci saturs tiks publicēts?';
+$lang['fullpath'] = 'Norādīt kājenē pilnu lapas ceļu';
+$lang['recent'] = 'Jaunākie grozījumi';
+$lang['breadcrumbs'] = 'Apmeklējumu vēstures garums';
+$lang['youarehere'] = 'Rādīt "tu atrodies šeit"';
+$lang['typography'] = 'Veikt tipogrāfijas aizvietošanu';
+$lang['htmlok'] = 'Atļaut iekļautu HTTP';
+$lang['phpok'] = 'Atļaut iekļautu PHP';
+$lang['dformat'] = 'Datuma formāts (sk. PHP <a href="http://www.php.net/strftime">strftime</a> funkciju)';
+$lang['signature'] = 'Paraksts';
+$lang['toptoclevel'] = 'Satura rādītāja pirmais līmenis';
+$lang['tocminheads'] = 'Mazākais virsrakstu skaits, no kuriem jāveido satura rādītājs.';
+$lang['maxtoclevel'] = 'Satura rādītāja dziļākais līmenis';
+$lang['maxseclevel'] = 'Dziļākais sekciju labošanas līmenis';
+$lang['camelcase'] = 'Lietot saitēm CamelCase';
+$lang['deaccent'] = 'Lapu nosaukumu transliterācija';
+$lang['useheading'] = 'Izmantot pirmo virsrakstu lapu nosaukumiem';
+$lang['refcheck'] = 'Pārbaudīt saites uz mēdiju failiem';
+$lang['refshow'] = 'Cik saites uz mēdiju failiem rādīt';
+$lang['allowdebug'] = 'Ieslēgt atkļūdošanu. <b>Izslēdz!</b>';
+$lang['usewordblock'] = 'Bloķēt spamu pēc slikto vārdu saraksta.';
+$lang['indexdelay'] = 'Laika aizture pirms indeksācijas (sekundēs)';
+$lang['relnofollow'] = 'rel="nofollow" ārējām saitēm';
+$lang['mailguard'] = 'Slēpt epasta adreses';
+$lang['iexssprotect'] = 'Pārbaudīt, vai augšupielādētajā failā nav nav potenciāli bīstamā JavaScript vai HTML koda.';
+$lang['showuseras'] = 'Kā rādīt pēdējo lietotāju, ka labojis lapu';
+$lang['useacl'] = 'Izmantot piekļuves tiesības';
+$lang['autopasswd'] = 'Automātiski ģenerēt paroles';
+$lang['authtype'] = 'Autentifikācijas mehānisms';
+$lang['passcrypt'] = 'Paroļu šifrēšanas metode';
+$lang['defaultgroup'] = 'Noklusētā grupa';
+$lang['superuser'] = 'Administrators - grupa, lietotājs vai to saraksts ( piem.: user1,@group1,user2), kam ir pilnas tiesības.';
+$lang['manager'] = 'Pārziņi - grupa, lietotājs vai to saraksts ( piem.: user1,@group1,user2), kam ir pieeja pie dažām administrēšanas funkcijām.';
+$lang['profileconfirm'] = 'Profila labošanai vajag paroli';
+$lang['disableactions'] = 'Bloķēt Dokuwiki darbības';
+$lang['disableactions_check'] = 'atzīmēt';
+$lang['disableactions_subscription'] = 'abonēt/atteikties';
+$lang['disableactions_wikicode'] = 'skatīt/eksportēt izejtekstu';
+$lang['disableactions_other'] = 'citas darbības (atdalīt ar komatiem)';
+$lang['sneaky_index'] = 'Pēc noklusētā DokuWiki lapu sarakstā parāda visu nodaļu lapas. Ieslēdzot šo parametru, noslēps tās nodaļas, kuras apmeklētājam nav tiesības lasīt. Bet tad tiks arī paslēptas dziļākas, bet atļautas nodaļas. Atsevišķos pieejas tiesību konfigurācijas gadījumos lapu saraksts var nedarboties.';
+$lang['auth_security_timeout'] = 'Autorizācijas drošības intervāls (sekundēs)';
+$lang['securecookie'] = 'Vai pa HTTPS sūtāmās sīkdatnes sūtīt tikai pa HTTPS? Atslēdz šo iespēju, kad tikai pieteikšanās wiki sistēmā notiek pa SSL šifrētu savienojumu, bet skatīšana - pa nešifrētu.';
+$lang['xmlrpc'] = 'Ieslēgt/izslēgt XML-RPC interfeisu.';
+$lang['xmlrpcuser'] = 'Ierobežot XML-RPC piekļuvi norādītām lietotāju grupām vai lietotājiem (atdalīt ar komatiem!). Atstāt tukšu, lai piekļuve būtu visiem.';
+$lang['updatecheck'] = 'Pārbaudīt, vai pieejami atjauninājumi un drošības brīdinājumi? Dokuwiki sazināsies ar update.dokuwiki.org';
+$lang['userewrite'] = 'Ērti lasāmas adreses (URL)';
+$lang['useslash'] = 'Lietot slīpiņu par URL atdalītāju';
+$lang['usedraft'] = 'Labojot automātiski saglabāt melnrakstu';
+$lang['sepchar'] = 'Lapas nosaukuma vārdu atdalītājs';
+$lang['canonical'] = 'Lietot kanoniskus URL';
+$lang['fnencode'] = 'Ne ASCII failvārdu kodēšanas metode:';
+$lang['autoplural'] = 'Automātisks daudzskaitlis';
+$lang['compression'] = 'Saspiešanas metode vecajiem failiem';
+$lang['cachetime'] = 'Bufera maksimālais vecums (sek)';
+$lang['locktime'] = 'Bloķēšanas failu maksimālais vecums';
+$lang['fetchsize'] = 'Maksimālais faila apjoms baitos, ko fetch.php var ielādēt no interneta.';
+$lang['notify'] = 'Nosūtīt izmaiņu paziņojumu uz epasta adresi';
+$lang['registernotify'] = 'Nosūtīt paziņojumu par jauniem lietotājiem uz epasta adresi';
+$lang['mailfrom'] = 'Epasta adrese automātiskajiem paziņojumiem';
+$lang['mailprefix'] = 'E-pasta temata prefikss automātiskajiem paziņojumiem';
+$lang['gzip_output'] = 'Lietot gzip Content-Encoding priekš xhtml';
+$lang['gdlib'] = 'GD Lib versija';
+$lang['im_convert'] = 'Ceļš uz ImageMagick convert rīku';
+$lang['jpg_quality'] = 'JPG saspiešanas kvalitāte';
+$lang['subscribers'] = 'Atļaut abonēt izmaiņas';
+$lang['subscribe_time'] = 'Pēc cik ilga laika izsūtīt abonētos sarakstus un kopsavilkumus (sekundes); jābūt mazākam par laiku, kas norādīts "recent_days".';
+$lang['compress'] = 'Saspiest CSS un javascript failus';
+$lang['hidepages'] = 'Slēpt lapas (regulāras izteiksmes)';
+$lang['send404'] = 'Par neesošām lapām atbildēt "HTTP 404/Page Not Found" ';
+$lang['sitemap'] = 'Lapas karte priekš Google (dienas)';
+$lang['broken_iua'] = 'Varbūt tavā serverī nedarbojas funkcija ignore_user_abort? Tā dēļ var nestādāt meklēšanas indeksācija. Šī problēma sastopama, piemēram, IIS ar PHP/CGI. Papildus informāciju skatīt <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Kļūdā Nr.852</a>.';
+$lang['xsendfile'] = 'Lietot X-Sendfile virsrakstu, augšupielādējot failu serverī? ';
+$lang['renderer_xhtml'] = 'Galveno (xhtml) wiki saturu renderēt ar ';
+$lang['renderer__core'] = '%s (dokuwiki kodols)';
+$lang['renderer__plugin'] = '%s (modulis)';
+$lang['rememberme'] = 'Atļaut pastāvīgas ielogošanās sīkdatnes ("atceries mani")';
+$lang['rss_type'] = 'XML barotnes veids';
+$lang['rss_linkto'] = 'XML barotnes uz ';
+$lang['rss_content'] = 'Ko attēlot XML barotnē?';
+$lang['rss_update'] = 'XML barotnes atjaunošanas intervāls (sec)';
+$lang['recent_days'] = 'Cik dienas glabāt jaunākās izmaiņas';
+$lang['rss_show_summary'] = 'Rādīt visrakstos XML barotnes kopsavilkumu ';
+$lang['target____wiki'] = 'Kur atvērt iekšējās saites';
+$lang['target____interwiki'] = 'Kur atvērt saites strap wiki';
+$lang['target____extern'] = 'Kur atvērt ārējās saites';
+$lang['target____media'] = 'Kur atvērt mēdiju saites';
+$lang['target____windows'] = 'Kur atvērt saites uz tīkla mapēm';
+$lang['proxy____host'] = 'Proxy servera vārds';
+$lang['proxy____port'] = 'Proxy ports';
+$lang['proxy____user'] = 'Proxy lietotāja vārds';
+$lang['proxy____pass'] = 'Proxy parole';
+$lang['proxy____ssl'] = 'Lietot SSL savienojumu ar proxy';
+$lang['proxy____except'] = 'Regulārā izteiksme tiem URL, kam nevar lietot proxy.';
+$lang['safemodehack'] = 'Lietot safemode apeju';
+$lang['ftp____host'] = 'FTP serveris safemode apejai';
+$lang['ftp____port'] = 'FTP ports safemode apejai';
+$lang['ftp____user'] = 'FTP lietotājvārds safemode apejai';
+$lang['ftp____pass'] = 'FTP parole safemode apejai';
+$lang['ftp____root'] = 'FTP saknes diektorija safemode apejai';
+$lang['license_o_'] = 'Ar nekādu';
+$lang['typography_o_0'] = 'neko';
+$lang['typography_o_1'] = 'tikai dubultpēdiņas';
+$lang['typography_o_2'] = 'visas pēdiņas (ne vienmēr strādā)';
+$lang['userewrite_o_0'] = 'nē';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki līdzekļi';
+$lang['deaccent_o_0'] = 'nē';
+$lang['deaccent_o_1'] = 'atmest diakritiku';
+$lang['deaccent_o_2'] = 'pārrakstīt latīņu burtiem';
+$lang['gdlib_o_0'] = 'GD Lib nav pieejama';
+$lang['gdlib_o_1'] = 'versija 1.x';
+$lang['gdlib_o_2'] = 'noteikt automātiksi';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Abstract';
+$lang['rss_content_o_diff'] = 'apvienotu diff';
+$lang['rss_content_o_htmldiff'] = 'HTML formatētu diff tabulu';
+$lang['rss_content_o_html'] = 'pilnu HTML lapas saturu';
+$lang['rss_linkto_o_diff'] = 'atšķirības';
+$lang['rss_linkto_o_page'] = 'grozītās lapas';
+$lang['rss_linkto_o_rev'] = 'grozījumu sarakstu';
+$lang['rss_linkto_o_current'] = 'patreizējo lapu';
+$lang['compression_o_0'] = 'nav';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nelietot';
+$lang['xsendfile_o_1'] = 'lighttpd (pirms laidiena 1.5) veida galvene';
+$lang['xsendfile_o_2'] = 'Standarta X-Sendfile galvene';
+$lang['xsendfile_o_3'] = 'Nginx X-Accel-Redirect veida galvene';
+$lang['showuseras_o_loginname'] = 'Login vārds';
+$lang['showuseras_o_username'] = 'Pilns lietotāja vārds';
+$lang['showuseras_o_email'] = 'Lietotāja epasta adrese (slēpta ar norādīto paņēmienu)';
+$lang['showuseras_o_email_link'] = 'Lietot epasta adreses kā mailto: saites';
+$lang['useheading_o_0'] = 'Nekad';
+$lang['useheading_o_navigation'] = 'Tikai navigācija';
+$lang['useheading_o_content'] = 'Tikai Wiki saturs';
+$lang['useheading_o_1'] = 'Vienmēr';
+$lang['readdircache'] = 'Maksimālais readdir kesš dzīves laiks (sek.)';
diff --git a/lib/plugins/config/lang/mk/lang.php b/lib/plugins/config/lang/mk/lang.php
new file mode 100644
index 000000000..6d4530f79
--- /dev/null
+++ b/lib/plugins/config/lang/mk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Macedonian language file
+ *
+ * @author Dimitar Talevski <dimi3.14@gmail.com>
+ */
diff --git a/lib/plugins/config/lang/mr/intro.txt b/lib/plugins/config/lang/mr/intro.txt
new file mode 100644
index 000000000..12ada73a1
--- /dev/null
+++ b/lib/plugins/config/lang/mr/intro.txt
@@ -0,0 +1,10 @@
+====== कॉन्फिगरेशन व्यवस्थापक ======
+
+तुमच्या डॉक्युविकीची सेटिंग बदलान्यासाथी हे पान वापरा.
+विशिष्ठ सेटिंग विषयी माहिती पाहिजे असल्यास [[doku>config]] पहा.
+प्लगिन विषयी अधिक माहितीसाठी [[doku>plugin:config]] पहा.
+हलक्या लाल पार्श्वभूमिमधे दाखवलेले सेटिंग सुरक्षित आहेत व या प्लगिन द्वारा बदलता येणार नाहीत.
+निळ्या पार्श्वभूमीमधे दाखवलेले सेटिंग आपोआप सेट होणार्या किमती आहेत आणि पांढर्या पार्श्वभूमीमधे
+दाखवलेले सेटिंग या इन्स्टॉलेशनसाठी ख़ास सेट केलेले आहेत. निळे आणि पांढरे दोन्ही सेटिंग बदलता येतील.
+
+ह्या पानावरून बाहर जाण्याआधी "Save" चे बटन क्लिक करायला विसरू नका नाहीतर सर्व बदल नाहीसे होतील. \ No newline at end of file
diff --git a/lib/plugins/config/lang/mr/lang.php b/lib/plugins/config/lang/mr/lang.php
new file mode 100644
index 000000000..321e05546
--- /dev/null
+++ b/lib/plugins/config/lang/mr/lang.php
@@ -0,0 +1,182 @@
+<?php
+/**
+ * Marathi language file
+ *
+ * @author ghatothkach@hotmail.com
+ * @author Padmanabh Kulkarni <kulkarnipadmanabh@gmail.com>
+ * @author Padmanabh Kulkarni<kulkarnipadmanabh@gmail.com>
+ * @author shantanoo@gmail.com
+ */
+$lang['menu'] = 'कॉन्फिगरेशन सेटिंग';
+$lang['error'] = 'चुकीचा शब्द टाकल्यामुळे सेटिंग अद्ययावत केलेली नाहीत. कृपया तुमचे बदल परत तपासा आणि परत सबमिट करा. <br /> चुकीच्या शब्दांभोवती लाल बॉर्डर दाखवली जाईल.';
+$lang['updated'] = 'सेटिंग अद्ययावत केली आहेत.';
+$lang['nochoice'] = '( इतर काही पर्याय नाहीत )';
+$lang['locked'] = 'सेटिंगची फाइल अद्ययावत करू शकलो नाही. जर हे सहेतुक नसेल तर, <br />
+सेटिंग च्या फाइल चे नाव व त्यावरील परवानग्या बरोबर असल्याची खात्री करा.';
+$lang['danger'] = 'सावधान : हा पर्याय बदलल्यास तुमची विकी आणि तिचे कॉनफिगरेशन निकामी होऊ शकते.';
+$lang['warning'] = 'सावघान: येथील पर्याय बदल्यास, अनपेक्षीत गोष्टी होऊ शकतात.';
+$lang['security'] = 'सुरक्षा संबंधी सूचना : हा पर्याय बदलल्यास तुमची साईट असुरक्षित होऊ शकते.';
+$lang['_configuration_manager'] = 'कॉन्फिगरेशन व्यवस्थापक';
+$lang['_header_dokuwiki'] = 'डॉक्युविकि सेटिंग';
+$lang['_header_plugin'] = 'प्लगिन सेटिंग';
+$lang['_header_template'] = 'टेम्पलेट (नमुना) सेटिंग';
+$lang['_header_undefined'] = 'अनिश्चित सेटिंग';
+$lang['_basic'] = 'पायाभूत सेटिंग';
+$lang['_display'] = 'डिसप्ले सेटिंग';
+$lang['_authentication'] = 'अधिकृत करण्याविषयी सेटिंग';
+$lang['_anti_spam'] = 'भंकस-विरोधी सेटिंग';
+$lang['_editing'] = 'संपादन सेटिंग';
+$lang['_links'] = 'लिंक सेटिंग';
+$lang['_media'] = 'दृक्श्राव्य माध्यम सेटिंग';
+$lang['_advanced'] = 'सविस्तर सेटिंग';
+$lang['_network'] = 'नेटवर्क सेटिंग';
+$lang['_plugin_sufix'] = 'प्लगिन सेटिंग';
+$lang['_template_sufix'] = 'टेम्पलेट ( नमुना ) सेटिंग';
+$lang['_msg_setting_undefined'] = 'सेटिंगविषयी उप-डेटा उपलब्ध नाही.';
+$lang['_msg_setting_no_class'] = 'सेटिंगचा क्लास उपलब्ध नाही';
+$lang['_msg_setting_no_default'] = 'आपोआप किम्मत नाही';
+$lang['fmode'] = 'फाइल निर्मिती मोड';
+$lang['dmode'] = 'डिरेक्टरी निर्मिती मोड';
+$lang['lang'] = 'भाषा';
+$lang['basedir'] = 'पायाभूत डिरेक्टरी';
+$lang['baseurl'] = 'पायाभूत URL';
+$lang['savedir'] = 'डेटा साठवण्यासाठीची डिरेक्टरी';
+$lang['start'] = 'सुरुवातीच्या पानाचे नाव';
+$lang['title'] = 'विकीचे शीर्षक';
+$lang['template'] = 'नमुना';
+$lang['license'] = 'कुठल्या लायसंसच्या अंतर्गत तुमचा मजकूर रिलीज़ केला गेला पाहिजे ?';
+$lang['fullpath'] = 'पानांचा पूर्ण पत्ता फूटर मधे दाखव';
+$lang['recent'] = 'अलीकडील बदल';
+$lang['breadcrumbs'] = 'ब्रेडक्रम्बची संख्या';
+$lang['youarehere'] = 'प्रतवार ब्रेडक्रम्ब';
+$lang['typography'] = 'अनवधानाने झालेल्या चुका बदला';
+$lang['htmlok'] = 'अंतर्गत HTML टाकायची परवानगी असू दे';
+$lang['phpok'] = 'अंतर्गत PHP टाकायची परवानगी असू दे';
+$lang['dformat'] = 'दिनांकाची पद्धत ( PHP चं <a href="http://www.php.net/strftime">strftime</a> हे फंक्शन पाहा )';
+$lang['signature'] = 'हस्ताक्षर';
+$lang['toptoclevel'] = 'अनुक्रमणिकेची सर्वोच्च पातळी';
+$lang['tocminheads'] = 'कमीत कमी किती शीर्षके असल्यास अनुक्रमणिका बनवावी';
+$lang['maxtoclevel'] = 'अनुक्रमणिकेची जास्तीत जास्त पातळी ';
+$lang['maxseclevel'] = 'विभागीय संपादनाची जास्तीतजास्त पातळी';
+$lang['camelcase'] = 'लिंकसाठी कॅमलकेस वापरा.';
+$lang['deaccent'] = 'सरळ्सोट पृष्ठ नाम';
+$lang['useheading'] = 'पहिलं शीर्षक पृष्ठ नाम म्हणुन वापरा';
+$lang['refcheck'] = 'दृक्श्राव्य माध्यमाचा संदर्भ तपासा';
+$lang['refshow'] = 'दृक्श्राव्य माध्यामाचे संदर्भ दाखवण्याची संख्या';
+$lang['allowdebug'] = 'डिबगची परवानगी <b> गरज नसल्यास बंद ठेवा !</b>';
+$lang['usewordblock'] = 'भंकस मजकूर थोपवण्यासाठी शब्दसमुह वापरा';
+$lang['indexdelay'] = 'सूचीकरणापूर्वीचा अवकाश ( सेकंदात )';
+$lang['relnofollow'] = 'बाह्य लिन्कसाठी rel=nofollow वापरा';
+$lang['mailguard'] = 'ईमेल दुर्बोध करा';
+$lang['iexssprotect'] = 'अपलोड केलेल्या फाइल हानिकारक जावास्क्रिप्ट किंवा HTML साठी तपासा';
+$lang['showuseras'] = 'पानाचं शेवटचं संपादन करणार्या सदस्याला काय दाखवायचं';
+$lang['useacl'] = 'ACL वापरा';
+$lang['autopasswd'] = 'पासवर्ड आपोआप बनवा';
+$lang['authtype'] = 'अधिकृत करण्याच्या व्यवस्थेचे बॅक-एंड';
+$lang['passcrypt'] = 'पासवर्ड गुप्त ठेवण्याची पद्धत';
+$lang['defaultgroup'] = 'डिफॉल्ट गट';
+$lang['superuser'] = 'सुपर सदस्य - गट, सदस्य किंवा स्वल्पविरामाने अलग केलेली यादी ( उदा. सदस्य१, गट१, सदस्य२ ) ज्यांना ACL च्या सेटिंग व्यतिरिक्त सर्व पानांवर पूर्ण हक्क असतो.';
+$lang['manager'] = 'व्यवस्थापक - गट, सदस्य किंवा स्वल्पविरामाने अलग केलेली यादी ( उदा. सदस्य१, गट१, सदस्य२ ) ज्यांना व्यवस्थापनाच्या निवडक सुविधा उपलब्ध असतात.';
+$lang['profileconfirm'] = 'प्रोफाइल मधील बदल पासवर्ड वापरून नक्की करा';
+$lang['disableactions'] = 'डॉक्युविकीच्या क्रिया बंद ठेवा';
+$lang['disableactions_check'] = 'तपासा';
+$lang['disableactions_subscription'] = 'सब्सक्राईब / अन्-सब्सक्राईब';
+$lang['disableactions_wikicode'] = 'स्त्रोत पहा / कच्च्या स्वरूपात एक्सपोर्ट करा';
+$lang['disableactions_other'] = 'इतर क्रिया ( स्वल्पविरामाने अलग केलेल्या )';
+$lang['sneaky_index'] = 'सूची दृश्यामधे डिफॉल्ट स्वरूपात डॉक्युविकी सगळे नेमस्पेस दाखवते. हा पर्याय चालू केल्यास सदस्याला वाचण्याची परवानगी नसलेले नेमस्पेस दिसणार नाहीत. यामुळे परवानगी असलेले उप - नेमस्पेस न दिसण्याची शक्यता आहे. यामुळे काही विशिष्ठ ACL सेटिंगसाठी सूची वापरता येण्यासारखी राहणार नाही.';
+$lang['auth_security_timeout'] = 'अधिकृत करण्याच्या प्रक्रियेची कालमर्यादा';
+$lang['securecookie'] = 'HTTPS वापरून सेट केलेले कूकीज ब्राउजरने HTTPS द्वाराच पाठवले पाहिजेत का? जर तुमच्या विकीचं फ़क्त लॉगिन पानच SSL वापरून सुरक्षित केलं असेल व पानांचं ब्राउजिंग असुरक्षित असेल तर हा पर्याय चालू करू नका.';
+$lang['xmlrpc'] = 'XML-RPC इंटरफेस चालू/बंद करा';
+$lang['xmlrpcuser'] = 'XML-RPC सुविधा फ़क्त इथे स्वल्पविरामाने अलग करून दिलेल्या गट किंवा वापरकर्त्याला उपलब्ध आहेत. सर्वाना ही सुविधा देण्यासाठी ही जागा रिकामी सोडा.';
+$lang['updatecheck'] = 'अपडेट आणि सुरक्षिततेविशयी सूचनान्वर पाळत ठेऊ का? या सुविधेसाठी डॉक्युविकीला update.dokuwiki.org शी संपर्क साधावा लागेल.';
+$lang['userewrite'] = 'छान छान URL वापर';
+$lang['useslash'] = 'URL मधे नेमस्पेस अलग करण्यासाठी \'/\' चिह्न वापरा';
+$lang['usedraft'] = 'संपादन करताना मसुदा आपोआप सुरक्षित करा';
+$lang['sepchar'] = 'पानाच्या नावातील शब्द अलग करण्याचे चिह्न';
+$lang['canonical'] = 'पूर्णपणे सुटसुटीत URL वापरा';
+$lang['autoplural'] = 'लिंकमधिल अनेकवचने तपासा';
+$lang['compression'] = 'अडगळीतल्या फाइल संकुचित करण्याची पद्धत';
+$lang['cachetime'] = 'कॅशचे जास्तीतजास्त वयोमान ( सेकंदात )';
+$lang['locktime'] = 'लॉक फाइलचे जास्तीतजास्त वयोमान ( सेकंदात )';
+$lang['fetchsize'] = 'बाह्य स्त्रोताकडून जास्तीतजास्त किती डाउनलोड fecth.php करू शकतो ( बाइट्स मधे )';
+$lang['notify'] = 'बदलाच्या सूचना ह्या ईमेल वर पाठवा';
+$lang['registernotify'] = 'नवीन नोंदणी केलेल्या सदस्यांची माहिती ह्या ईमेल वर पाठवा';
+$lang['mailfrom'] = 'आपोआप ईमेल पाठवण्यासाठी वापरायचा ईमेल';
+$lang['gzip_output'] = 'xhtml साठी gzip Content-encoding वापरा';
+$lang['gdlib'] = 'gzip लायब्ररीची आवृत्ती';
+$lang['im_convert'] = 'ImageMagik च्या परिवर्तन करणार्या टूलचा पाथ';
+$lang['jpg_quality'] = 'JPG संकुचित करण्याचा दर्जा ( १ - १०० )';
+$lang['subscribers'] = 'पानाची पुरवणी देण्याची सुविधा चालू करा';
+$lang['compress'] = 'CSS आणि जावास्क्रिप्टचे आउट्पुट संकुचित करा';
+$lang['hidepages'] = 'समान पाने लपवा';
+$lang['send404'] = 'अस्तित्वात नसलेल्या पानांसाठी "HTTP 404/Page not found" संदेश पाठवा';
+$lang['sitemap'] = 'गूगल साईट-मॅप बनवा';
+$lang['broken_iua'] = 'ignore_user_abort फंक्शन तुमच्या सिस्टम वर चालत नाही का? यामुळे शोध सूची निकामी होऊ शकते. IIS + PHP/CGI वर हे काम करत नाही हे नक्की झाले आहे. अधिक माहितीसाठी <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">बग ८५२</a> पहा.';
+$lang['xsendfile'] = 'सर्वर कडून स्थिर फाइल पाठवली जाण्यासाठी X-Sendfile शीर्षक ( header ) वापरू का ? तुमच्या वेब सर्वर मधे ही सुविधा असली पाहिजे.';
+$lang['renderer_xhtml'] = 'मुख्य ( xhtml ) विकी आउट्पुट साथी वापरायचा चित्रक ( renderer )';
+$lang['renderer__core'] = '%s (डॉक्युविकीचा मूलभूत)';
+$lang['renderer__plugin'] = '%s (प्लगिन)';
+$lang['rememberme'] = 'कायमच्या लॉगिन कुकीजला परवानगी दया ( लक्षात ठेवा )';
+$lang['rss_type'] = 'XML पुरवणीचा प्रकार';
+$lang['rss_linkto'] = 'XML पुरवणीची लिंक येथे जाते';
+$lang['rss_content'] = 'XML पुरवणीतल्या मुद्द्यामधे काय काय दाखवायचं?';
+$lang['rss_update'] = 'XML पुरवणी अद्ययावत करण्याचा कालखंड ( सेकंदात )';
+$lang['recent_days'] = 'किती अलीकडील बदल ठेवायचे? ( दिवसात )';
+$lang['rss_show_summary'] = 'XML पुरावानीच्या शीर्षकात सारांश दाखवा';
+$lang['target____wiki'] = 'अंतर्गत लिंकसाठीची विंडो';
+$lang['target____interwiki'] = 'आंतरविकि लिंकसाठीची विंडो';
+$lang['target____extern'] = 'बाह्य लिंकसाठीची विंडो';
+$lang['target____media'] = 'दृक्श्राव्य लिंकसाठीची विंडो';
+$lang['target____windows'] = 'विंडो लिंकसाठीची विंडो';
+$lang['proxy____host'] = 'छद्म ( proxy ) सर्वरचे नाव';
+$lang['proxy____port'] = 'छद्म ( proxy ) सर्वरचे पोर्ट';
+$lang['proxy____user'] = 'छद्म ( proxy ) सर्वरचे सदस्यनाम';
+$lang['proxy____pass'] = 'छद्म ( proxy ) सर्वरचा पासवर्ड';
+$lang['proxy____ssl'] = 'छद्म सर्वरला संपर्क साधण्यासाठी SSL वापरा';
+$lang['safemodehack'] = 'सेफमोड़ हॅक चालू करा';
+$lang['ftp____host'] = 'सेफमोड़ हॅक साठी FTP सर्वर';
+$lang['ftp____port'] = 'सेफमोड़ हॅक साठी FTP पोर्ट';
+$lang['ftp____user'] = 'सेफमोड़ हॅक साठी FTP सदस्यनाम';
+$lang['ftp____pass'] = 'सेफमोड़ हॅक साठी FTP पासवर्ड';
+$lang['ftp____root'] = 'सेफमोड़ हॅक साठी FTP मूळ डिरेक्टरी';
+$lang['license_o_'] = 'काही निवडले नाही';
+$lang['typography_o_0'] = 'काही नाही';
+$lang['typography_o_1'] = 'फक्त दुहेरी अवतरण चिह्न';
+$lang['typography_o_2'] = 'सर्व प्रकारची अवतरण चिन्हे ( नेहेमी चालेलच असं नाही )';
+$lang['userewrite_o_0'] = 'कुठेही नाही';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'डॉक्युविकी अंतर्गत';
+$lang['deaccent_o_0'] = 'बंद';
+$lang['deaccent_o_1'] = 'एक्सेंट काढून टाका';
+$lang['deaccent_o_2'] = 'रोमन लिपित बदला';
+$lang['gdlib_o_0'] = 'GD Lib उपलब्ध नाही';
+$lang['gdlib_o_1'] = 'आवृत्ती १.x';
+$lang['gdlib_o_2'] = 'आपोआप ओळखा';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'सारांश';
+$lang['rss_content_o_diff'] = 'एकत्रित फरक';
+$lang['rss_content_o_htmldiff'] = 'HTML पद्धतीचा फरकांचा तक्ता';
+$lang['rss_content_o_html'] = 'पानाचा पूर्ण HTML मजकूर';
+$lang['rss_linkto_o_diff'] = 'फरक दृश्य';
+$lang['rss_linkto_o_page'] = 'उजळणी केलेले पान';
+$lang['rss_linkto_o_rev'] = 'आवृत्त्यांची यादी';
+$lang['rss_linkto_o_current'] = 'सद्य पान';
+$lang['compression_o_0'] = 'काही नाही';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'वापरू नका';
+$lang['xsendfile_o_1'] = 'lighttpd चा प्रोप्रायटरी शीर्षक (हेडर)';
+$lang['xsendfile_o_2'] = 'स्टॅण्डर्ड X-sendfile शीर्षक';
+$lang['xsendfile_o_3'] = ' Nginx चा प्रोप्रायटरी Accel-Redirect शीर्षक';
+$lang['showuseras_o_loginname'] = 'लॉगिन नाम';
+$lang['showuseras_o_username'] = 'सदस्याचे पूर्ण नाव';
+$lang['showuseras_o_email'] = 'सदस्याचा ईमेल ( मेल सुरक्षिततेच्या सेटिंग अनुसार दुर्बोध केलेला ) ';
+$lang['showuseras_o_email_link'] = 'सदस्याचा ईमेल maito: लिंक स्वरूपात';
+$lang['useheading_o_0'] = 'कधीच नाही';
+$lang['useheading_o_navigation'] = 'फ़क्त मार्गदर्शन';
+$lang['useheading_o_content'] = 'फ़क्त विकी मजकूर';
+$lang['useheading_o_1'] = 'नेहमी';
diff --git a/lib/plugins/config/lang/ms/lang.php b/lib/plugins/config/lang/ms/lang.php
new file mode 100644
index 000000000..77ad2a1c1
--- /dev/null
+++ b/lib/plugins/config/lang/ms/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Malay language file
+ *
+ * @author Markos
+ */
diff --git a/lib/plugins/config/lang/ne/lang.php b/lib/plugins/config/lang/ne/lang.php
new file mode 100644
index 000000000..a8b426b9c
--- /dev/null
+++ b/lib/plugins/config/lang/ne/lang.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Nepali language file
+ *
+ * @author Saroj Kumar Dhakal <lotusnagarkot@gmail.com>
+ * @author SarojKumar Dhakal <lotusnagarkot@yahoo.com>
+ * @author Saroj Dhakal<lotusnagarkot@yahoo.com>
+ */
+$lang['nochoice'] = '(अरु विकल्पहरु अनुपलव्ध)';
+$lang['_configuration_manager'] = 'नियन्त्रण व्यवस्थापक';
+$lang['_header_dokuwiki'] = 'DokuWiki सेटिंङ्ग';
+$lang['_header_plugin'] = 'प्लगइन सेटिंङ्ग';
+$lang['_header_template'] = 'टेम्प्लेट सेटिंङ्ग';
+$lang['_header_undefined'] = 'नखुलेको सेटिंङ्ग';
+$lang['_basic'] = 'आधारभूत सेटिंङ्ग';
+$lang['_display'] = 'प्रदर्शन सेटिंङ्ग';
+$lang['_authentication'] = 'आधिकारिकता सेटिंङ्ग';
+$lang['_anti_spam'] = 'स्प्याम विरुद्धको सेटिंङ्ग';
+$lang['_editing'] = 'सम्पादन सेटिंङ्ग';
+$lang['_links'] = 'लिङ्क सेटिंङ्ग';
+$lang['_media'] = 'मिडिया सेटिंङ्ग';
+$lang['_advanced'] = 'विशिष्ठ सेटिंङ्ग';
+$lang['_network'] = 'सञ्जाल सेटिंङ्ग';
+$lang['_plugin_sufix'] = 'प्लगइन सेटिंङ्ग';
+$lang['_template_sufix'] = 'टेम्प्लेट सेटिंङ्ग';
+$lang['_msg_setting_undefined'] = 'सेटिंङ्ग मेटाडाटा नभएको';
+$lang['_msg_setting_no_class'] = 'सेटिंङ्ग वर्ग नभएको';
+$lang['_msg_setting_no_default'] = 'कुनै पूर्व निर्धारित मान छैन ।';
+$lang['fmode'] = 'फाइल निर्माण स्थिति';
+$lang['dmode'] = 'डाइरेक्टरी निर्माण स्थिति';
+$lang['lang'] = 'भाषा';
+$lang['basedir'] = 'आधार डाइरेक्टरी';
+$lang['baseurl'] = 'आधार URL';
+$lang['savedir'] = 'सामग्री वचत गर्ने डाइरेक्टरी';
+$lang['start'] = 'पृष्ट नाम सुरुगर्नुहोस्';
+$lang['title'] = 'विकि शिर्षक';
+$lang['template'] = 'ढाँचा';
+$lang['license'] = 'कुन प्रमाण पत्रको आधारमा सामग्री प्रकाशन गरिनु पर्छ ?';
+$lang['fullpath'] = 'पष्ठको पूरा बाटो निम्नशिर्षकमा देखाउने';
+$lang['recent'] = 'हालैको परिवर्तन';
+$lang['htmlok'] = 'इम्बेडगरिएको HTML खुला गर्नुहोस ।';
+$lang['phpok'] = 'इम्बेडगरिएको PHP खुला गर्नुहोस ।';
+$lang['signature'] = 'दस्तखत';
+$lang['renderer__core'] = ' %s (dokuwiki core)';
+$lang['renderer__plugin'] = ' %s (plugin)';
+$lang['rss_type'] = 'XML फिड प्रकार';
+$lang['rss_linkto'] = 'को XML फिड';
+$lang['gdlib_o_1'] = 'संस्करण १.x';
+$lang['gdlib_o_2'] = 'आफै पत्तालगाउनु होस् ';
+$lang['rss_type_o_rss'] = 'आरसस ०॒.९१';
+$lang['rss_type_o_rss1'] = 'आरसस १.०';
+$lang['rss_type_o_rss2'] = 'आरसस २.०';
+$lang['rss_type_o_atom'] = 'एटम ०.३';
+$lang['rss_type_o_atom1'] = 'एटम १.०';
+$lang['rss_content_o_abstract'] = 'सारांस';
+$lang['rss_content_o_diff'] = 'एकिकृत फरक';
+$lang['rss_content_o_htmldiff'] = 'HTML ढाँचाको फरक सुची';
+$lang['rss_content_o_html'] = 'पूरा HTML पृष्टमा रहेको वस्तु';
+$lang['rss_linkto_o_diff'] = 'फरक अवलोकन';
+$lang['rss_linkto_o_rev'] = 'पुन:संस्करण सुची';
+$lang['rss_linkto_o_current'] = 'चालु पृष्ठ';
+$lang['compression_o_0'] = 'कुनै पनि होइन ';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'प्रयोग नगर्नुहोस्';
+$lang['showuseras_o_loginname'] = 'प्रवेश नाम';
+$lang['showuseras_o_username'] = 'प्रयोगकर्ताको पूरा नाम';
+$lang['useheading_o_0'] = 'कहिले पनि ';
+$lang['useheading_o_content'] = 'विकी विषयवस्तु मात्र';
+$lang['useheading_o_1'] = 'सधैँ';
diff --git a/lib/plugins/config/lang/nl/intro.txt b/lib/plugins/config/lang/nl/intro.txt
new file mode 100644
index 000000000..3814b70bd
--- /dev/null
+++ b/lib/plugins/config/lang/nl/intro.txt
@@ -0,0 +1,9 @@
+====== Configuratie Manager ======
+
+Gebruik deze pagina om de instellingen van je DokuWiki te bekijken en/of te wijzigen. Voor hulp over specifieke instellingen kun je kijken op [[doku>config]]. Voor meer informatie over deze plugin zie [[doku>plugin:config]].
+
+Instellingen met een rode achtergond kunnen niet worden gewijzigd met deze plugin. Instellingen met een blauwe achtergrond hebben de default waarde, en instellingen met een witte achtergrond zijn lokaal gewijzigd voor deze specifieke installatie. Zowel blauwe als witte instellingen kunnen worden gewijzigd.
+
+Vergeet niet op **Opslaan** te drukken alvorens de pagina te verlaten, anders gaan je wijzigingen verloren.
+
+
diff --git a/lib/plugins/config/lang/nl/lang.php b/lib/plugins/config/lang/nl/lang.php
new file mode 100644
index 000000000..c98d05adb
--- /dev/null
+++ b/lib/plugins/config/lang/nl/lang.php
@@ -0,0 +1,198 @@
+<?php
+/**
+ * dutch language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Pieter van der Meulen <pieter@vdmeulen.net>
+ * @author Wouter Schoot <wouter@schoot.org>
+ * @author John de Graaff <john@de-graaff.net>
+ * @author Niels Schoot <niels.schoot@quintiq.com>
+ * @author Dion Nicolaas <dion@nicolaas.net>
+ * @author Danny Rotsaert <danny.rotsaert@edpnet.be>
+ * @author Marijn Hofstra hofstra.m@gmail.com
+ * @author Matthias Carchon webmaster@c-mattic.be
+ * @author Marijn Hofstra <hofstra.m@gmail.com>
+ * @author Timon Van Overveldt <timonvo@gmail.com>
+ * @author Jeroen
+ * @author Ricardo Guijt <ricardoguijt@gmail.com>
+ */
+$lang['menu'] = 'Configuratie-instellingen';
+$lang['error'] = 'De instellingen zijn niet gewijzigd wegens een incorrecte waarde, kijk je wijzigingen na en sla dan opnieuw op.<br />Je kunt de incorrecte waarde(s) herkennen aan de rode rand.';
+$lang['updated'] = 'Instellingen met succes opgeslagen.';
+$lang['nochoice'] = '(geen andere keuzemogelijkheden)';
+$lang['locked'] = 'Het bestand met instellingen kan niet worden gewijzigd. Als dit niet de bedoeling <br /> is, controleer dan de naam en de permissies voor het lokale installingenbestand.';
+$lang['danger'] = 'Gevaar: Het wijzigen van deze optie kan er voor zorgen dat uw wiki en het configuratiemenu niet langer toegankelijk zijn.';
+$lang['warning'] = 'Waarschuwing: Het wijzigen van deze optie kan onverwachte gedragingen veroorzaken.';
+$lang['security'] = 'Beveiligingswaarschuwing: Het wijzigen van deze optie kan een beveiligingsrisico inhouden.';
+$lang['_configuration_manager'] = 'Configuratiemanager';
+$lang['_header_dokuwiki'] = 'DokuWiki-instellingen';
+$lang['_header_plugin'] = 'Plugin-instellingen';
+$lang['_header_template'] = 'Sjabloon-instellingen';
+$lang['_header_undefined'] = 'Ongedefinieerde instellingen';
+$lang['_basic'] = 'Basisinstellingen';
+$lang['_display'] = 'Beeldinstellingen';
+$lang['_authentication'] = 'Authenticatie-instellingen';
+$lang['_anti_spam'] = 'Anti-spaminstellingen';
+$lang['_editing'] = 'Pagina-wijzigingsinstellingen';
+$lang['_links'] = 'Link-instellingen';
+$lang['_media'] = 'Media-instellingen';
+$lang['_advanced'] = 'Geavanceerde instellingen';
+$lang['_network'] = 'Netwerkinstellingen';
+$lang['_plugin_sufix'] = 'Plugin-instellingen';
+$lang['_template_sufix'] = 'Sjabloon-instellingen';
+$lang['_msg_setting_undefined'] = 'Geen metadata voor deze instelling.';
+$lang['_msg_setting_no_class'] = 'Geen class voor deze instelling.';
+$lang['_msg_setting_no_default'] = 'Geen standaard waarde.';
+$lang['fmode'] = 'Bestandaanmaak-modus (file creation mode)';
+$lang['dmode'] = 'Directory-aanmaak-modus (directory creation mode)';
+$lang['lang'] = 'Taal';
+$lang['basedir'] = 'Basisdirectory';
+$lang['baseurl'] = 'Basis-URL';
+$lang['savedir'] = 'Directory om data op te slaan';
+$lang['cookiedir'] = 'Cookie pad. Laat leeg om de basis URL te gebruiken.';
+$lang['start'] = 'Naam startpagina';
+$lang['title'] = 'Titel van de wiki';
+$lang['template'] = 'Sjabloon';
+$lang['license'] = 'Onder welke licentie zou je tekst moeten worden gepubliceerd?';
+$lang['fullpath'] = 'Volledig pad van pagina\'s in de footer weergeven';
+$lang['recent'] = 'Recente wijzigingen';
+$lang['breadcrumbs'] = 'Aantal broodkruimels';
+$lang['youarehere'] = 'Hierarchische broodkruimels';
+$lang['typography'] = 'Breng typografische wijzigingen aan';
+$lang['htmlok'] = 'Embedded HTML toestaan';
+$lang['phpok'] = 'Embedded PHP toestaan';
+$lang['dformat'] = 'Datum formaat (zie de PHP <a href="http://www.php.net/strftime">strftime</a> functie)';
+$lang['signature'] = 'Ondertekening';
+$lang['toptoclevel'] = 'Bovenste niveau voor inhoudsopgave';
+$lang['tocminheads'] = 'Minimum aantal koppen dat bepaald of een index gemaakt wordt';
+$lang['maxtoclevel'] = 'Laagste niveau voor inhoudsopgave';
+$lang['maxseclevel'] = 'Laagste sectiewijzigingsniveau';
+$lang['camelcase'] = 'CamelCase gebruiken voor links';
+$lang['deaccent'] = 'Paginanamen ontdoen van vreemde tekens';
+$lang['useheading'] = 'Eerste kopje voor paginanaam gebruiken';
+$lang['refcheck'] = 'Controleer verwijzingen naar media';
+$lang['refshow'] = 'Aantal te tonen mediaverwijzingen';
+$lang['allowdebug'] = 'Debug toestaan <b>uitzetten indien niet noodzakelijk!</b>';
+$lang['mediarevisions'] = 'Media revisies activeren?';
+$lang['usewordblock'] = 'Blokkeer spam op basis van woordenlijst';
+$lang['indexdelay'] = 'Uitstel voor indexeren (sec)';
+$lang['relnofollow'] = 'Gebruik rel="nofollow" voor externe links';
+$lang['mailguard'] = 'E-mailadressen onherkenbaar maken';
+$lang['iexssprotect'] = 'Controleer geüploade bestanden op mogelijk schadelijke JavaScript of HTML code';
+$lang['showuseras'] = 'Hoe de gebruiker die de pagina het laatst wijzigde weergeven';
+$lang['useacl'] = 'Gebruik access control lists';
+$lang['autopasswd'] = 'Zelf wachtwoorden genereren';
+$lang['authtype'] = 'Authenticatiemechanisme';
+$lang['passcrypt'] = 'Encryptie-methode voor wachtwoord ';
+$lang['defaultgroup'] = 'Standaardgroep';
+$lang['superuser'] = 'Superuser - een groep of gebruiker of kommalijst (gebruiker1,@groep1,gebruiker2) met volledige toegang tot alle pagina\'s en functies, ongeacht de ACL instellingen';
+$lang['manager'] = 'Beheerder - een groep of gebruiker of kommalijst (gebruiker1,@groep1,gebruiker2) met toegang tot bepaalde beheersfunctionaliteit';
+$lang['profileconfirm'] = 'Bevestig profielwijzigingen met wachtwoord';
+$lang['disableactions'] = 'Aangevinkte DokuWiki-akties uitschakelen';
+$lang['disableactions_check'] = 'Controleer';
+$lang['disableactions_subscription'] = 'Inschrijven/opzeggen';
+$lang['disableactions_wikicode'] = 'Bron bekijken/exporteer rauw';
+$lang['disableactions_other'] = 'Andere akties (gescheiden door komma\'s)';
+$lang['sneaky_index'] = 'Met de standaardinstellingen zal DokuWiki alle namespaces laten zien in de index. Het inschakelen van deze optie zorgt ervoor dat de namespaces waar de gebruiker geen leestoegang tot heeft, verborgen worden. Dit kan resulteren in het verbergen van subnamespaces waar de gebruiker wel toegang to heeft. Dit kan de index onbruikbaar maken met bepaalde ACL-instellingen.';
+$lang['auth_security_timeout'] = 'Authenticatiebeveiligings-timeout (seconden)';
+$lang['securecookie'] = 'Moeten cookies die via HTTPS gezet zijn alleen via HTTPS verzonden worden door de browser? Zet deze optie uit als alleen het inloggen op de wiki beveiligd is, maar het gebruik verder niet.';
+$lang['xmlrpc'] = 'Inschakelen/uitschakelen XML-RPC interface.';
+$lang['xmlrpcuser'] = 'Beperk XML-RPC toegang tot de lijst met kommagescheiden groepen of gebruikers die hier zijn opgegeven. Laat leeg om iedereen toegang te geven.';
+$lang['updatecheck'] = 'Controleer op nieuwe versies en beveiligingswaarschuwingen? DokuWiki moet hiervoor contact opnemen met update.dokuwiki.org.';
+$lang['userewrite'] = 'Gebruik nette URL\'s';
+$lang['useslash'] = 'Gebruik slash (/) als scheiding tussen namepaces in URL\'s';
+$lang['usedraft'] = 'Sla automatisch een concept op tijdens het wijzigen';
+$lang['sepchar'] = 'Woordscheider in paginanamen';
+$lang['canonical'] = 'Herleid URL\'s tot hun basisvorm';
+$lang['fnencode'] = 'Methode om niet-ASCII bestandsnamen te coderen.';
+$lang['autoplural'] = 'Controleer op meervoudsvormen in links';
+$lang['compression'] = 'Compressiemethode voor attic-bestanden';
+$lang['cachetime'] = 'Maximum leeftijd voor cache (sec)';
+$lang['locktime'] = 'Maximum leeftijd voor lockbestanden (sec)';
+$lang['fetchsize'] = 'Maximum grootte (bytes) die fetch.php mag downloaden van buiten';
+$lang['notify'] = 'Stuur e-mailnotificaties naar dit adres';
+$lang['registernotify'] = 'Stuur informatie over nieuw aangemelde gebruikers naar dit e-mailadres';
+$lang['mailfrom'] = 'E-mailadres voor automatische e-mail';
+$lang['mailprefix'] = 'Te gebruiken voorvoegsel voor onderwerp automatische email';
+$lang['gzip_output'] = 'Gebruik gzip Content-Encoding voor xhtml';
+$lang['gdlib'] = 'Versie GD Lib ';
+$lang['im_convert'] = 'Path naar ImageMagick\'s convert tool';
+$lang['jpg_quality'] = 'JPG compressiekwaliteit (0-100)';
+$lang['subscribers'] = 'Ondersteuning pagina-inschrijving aanzetten';
+$lang['subscribe_time'] = 'Inschrijvingsmeldingen en samenvattingen worden na deze tijdsduur (in seconden) verzonden. Deze waarde dient kleiner te zijn dan de tijd ingevuld bij "Hoeveel recente wijzigingen bewaren (dagen)"';
+$lang['compress'] = 'Compacte CSS en javascript output';
+$lang['cssdatauri'] = 'Maximale omvang in bytes van in CSS gelinkte afbeeldingen die bij de stylesheet moeten worden ingesloten ter reductie van de HTTP request header overhead. Deze techniek werkt niet in IE7 en ouder! <code>400</code> tot <code>600</code> is een geschikte omvang. Stel de omvang in op <code>0</code> om deze functionaliteit uit te schakelen.';
+$lang['hidepages'] = 'Verberg deze pagina\'s (regular expressions)';
+$lang['send404'] = 'Stuur "HTTP 404/Page Not Found" voor niet-bestaande pagina\'s';
+$lang['sitemap'] = 'Genereer Google sitemap (dagen)';
+$lang['broken_iua'] = 'Is de ignore_user_abort functie onbruikbaar op uw systeem? Dit kan een onbruikbare zoekindex tot gevolg hebben. IIS+PHP/CGI staat hier bekend om. Zie <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> voor meer informatie.';
+$lang['xsendfile'] = 'Gebruik de X-Sendfile header om de webserver statische content te laten versturen? De webserver moet dit wel ondersteunen.';
+$lang['renderer_xhtml'] = 'Weergavesysteem voor de standaard (xhtml) wiki-uitvoer';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Permanente login cookie toestaan (onthoud mij)';
+$lang['rss_type'] = 'XML feed type';
+$lang['rss_linkto'] = 'XML feed linkt naar';
+$lang['rss_content'] = 'Wat moet er in de XML feed items weergegeven worden?';
+$lang['rss_update'] = 'XML feed verversingsinterval (sec)';
+$lang['recent_days'] = 'Hoeveel recente wijzigingen bewaren (dagen)';
+$lang['rss_show_summary'] = 'XML feed samenvatting in titel weergeven';
+$lang['target____wiki'] = 'Doelvenster voor interne links';
+$lang['target____interwiki'] = 'Doelvenster voor interwiki-links';
+$lang['target____extern'] = 'Doelvenster voor externe links';
+$lang['target____media'] = 'Doelvenster voor medialinks';
+$lang['target____windows'] = 'Doelvenster voor windows links';
+$lang['proxy____host'] = 'Proxy server';
+$lang['proxy____port'] = 'Proxy port';
+$lang['proxy____user'] = 'Proxy gebruikersnaam';
+$lang['proxy____pass'] = 'Proxy wachtwoord';
+$lang['proxy____ssl'] = 'Gebruik SSL om een connectie te maken met de proxy';
+$lang['proxy____except'] = 'Reguliere expressie om URL\'s te bepalen waarvoor de proxy overgeslaan moet worden.';
+$lang['safemodehack'] = 'Safemode hack aanzetten';
+$lang['ftp____host'] = 'FTP server voor safemode hack';
+$lang['ftp____port'] = 'FTP port voor safemode hack';
+$lang['ftp____user'] = 'FTP gebruikersnaam voor safemode hack';
+$lang['ftp____pass'] = 'FTP wachtwoord voor safemode hack';
+$lang['ftp____root'] = 'FTP root directory voor safemode hack';
+$lang['license_o_'] = 'Geen gekozen';
+$lang['typography_o_0'] = 'geen';
+$lang['typography_o_1'] = 'Alleen dubbele aanhalingstekens';
+$lang['typography_o_2'] = 'Alle aanhalingstekens (functioneert mogelijk niet altijd)';
+$lang['userewrite_o_0'] = 'geen';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki intern';
+$lang['deaccent_o_0'] = 'uit';
+$lang['deaccent_o_1'] = 'accenten verwijderen';
+$lang['deaccent_o_2'] = 'romaniseer';
+$lang['gdlib_o_0'] = 'GD Lib niet beschikbaar';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Autodetectie';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Abstract';
+$lang['rss_content_o_diff'] = 'Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'Diff-tabel in HTML';
+$lang['rss_content_o_html'] = 'Volledige pagina-inhoud in HTML';
+$lang['rss_linkto_o_diff'] = 'verschillen';
+$lang['rss_linkto_o_page'] = 'de gewijzigde pagina';
+$lang['rss_linkto_o_rev'] = 'lijst van revisies';
+$lang['rss_linkto_o_current'] = 'de huidige pagina';
+$lang['compression_o_0'] = 'geen';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'niet gebruiken';
+$lang['xsendfile_o_1'] = 'Eigen lighttpd header (voor release 1.5)';
+$lang['xsendfile_o_2'] = 'Standaard X-Sendfile header';
+$lang['xsendfile_o_3'] = 'Propritary Nginx X-Accel-Redirect header';
+$lang['showuseras_o_loginname'] = 'loginnaam';
+$lang['showuseras_o_username'] = 'Volledige naam';
+$lang['showuseras_o_email'] = 'E-mailadres (onherkenbaar gemaakt volgens mailguard-instelling)';
+$lang['showuseras_o_email_link'] = 'E-mailadres als mailto: link';
+$lang['useheading_o_0'] = 'Nooit';
+$lang['useheading_o_navigation'] = 'Alleen navigatie';
+$lang['useheading_o_content'] = 'Alleen wiki inhoud';
+$lang['useheading_o_1'] = 'Altijd';
+$lang['readdircache'] = 'Maximale leeftijd voor readdir cache (in seconden)';
diff --git a/lib/plugins/config/lang/no/intro.txt b/lib/plugins/config/lang/no/intro.txt
new file mode 100644
index 000000000..c1310cc6d
--- /dev/null
+++ b/lib/plugins/config/lang/no/intro.txt
@@ -0,0 +1,7 @@
+====== Konfigurasjonsinnstillinger ======
+
+Bruk denne siden for å kontrollere innstillingene for din DokuWiki. For hjelp om hver enkelt innstilling, se [[doku>config]]. For mer detaljer om denne innstillingssiden, se [[doku>plugin:config]].
+
+Innstillinger vist med lys rød bakgrunn er beskyttet og kan ikke endres på denne siden. Innstillinger vist med blå bakgrunn er standardverdier og innstillinger med hvit bakgrunn har blitt satt lokalt for denne installasjonen. Både blå og hvite innstillinger kan endres.
+
+Husk å trykke på **Lagre**-knappen før du forlater siden. Hvis ikke går endringene tapt.
diff --git a/lib/plugins/config/lang/no/lang.php b/lib/plugins/config/lang/no/lang.php
new file mode 100644
index 000000000..c41b5e566
--- /dev/null
+++ b/lib/plugins/config/lang/no/lang.php
@@ -0,0 +1,204 @@
+<?php
+/**
+ * Norwegianlanguage file
+ *
+ * @author Thomas Nygreen <nygreen@gmail.com>
+ * @author Arild Burud <arildb@met.no>
+ * @author Torkill Bruland <torkar-b@online.no>
+ * @author Rune M. Andersen <rune.andersen@gmail.com>
+ * @author Jakob Vad Nielsen (me@jakobnielsen.net)
+ * @author Kjell Tore Næsgaard <kjell.t.nasgaard@ntnu.no>
+ * @author Knut Staring <knutst@gmail.com>
+ * @author Lisa Ditlefsen <lisa@vervesearch.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author Rune Rasmussen syntaxerror.no@gmail.com
+ * @author Jon Bøe <jonmagneboe@hotmail.com>
+ * @author Egil Hansen <egil@rosetta.no>
+ */
+$lang['menu'] = 'Konfigurasjonsinnstillinger';
+$lang['error'] = 'Innstillingene ble ikke oppdatert på grunn av en eller flere ugyldig verdier. Vennligst se gjennom endringene og prøv på nytt.
+<br />Ugyldige verdier er omgitt av en rød ramme.';
+$lang['updated'] = 'Innstillingene ble oppdatert.';
+$lang['nochoice'] = '(ingen andre mulige valg)';
+$lang['locked'] = 'Innstillingene kan ikke oppdateres. Hvis dette ikke er meningen,<br />
+forsikre deg om at fila med de lokale innstillingene har korrekt filnavn<br/>
+og tillatelser.';
+$lang['danger'] = 'Advarsel: Endrig av dette valget kan føre til at wiki og konfigurasjon menyen ikke blir tilgjengelig.';
+$lang['warning'] = 'Advarsel: Endring av dette valget kan føre til utilsiktet atferd.
+
+';
+$lang['security'] = 'Sikkerhetsadvarsel: Endring av dette valget kan innebære en sikkerhetsrisiko.';
+$lang['_configuration_manager'] = 'Konfigurasjonsinnstillinger';
+$lang['_header_dokuwiki'] = 'Innstillinger for DokuWiki';
+$lang['_header_plugin'] = 'Innstillinger for tillegg';
+$lang['_header_template'] = 'Innstillinger for maler';
+$lang['_header_undefined'] = 'Udefinerte innstillinger';
+$lang['_basic'] = 'Grunnleggende innstillinger';
+$lang['_display'] = 'Innstillinger for visning av sider';
+$lang['_authentication'] = 'Innstillinger for autentisering';
+$lang['_anti_spam'] = 'Anti-Spam innstillinger';
+$lang['_editing'] = 'Innstillinger for redigering';
+$lang['_links'] = 'Innstillinger for lenker';
+$lang['_media'] = 'Innstillinger for mediafiler';
+$lang['_advanced'] = 'Avanserte innstillinger';
+$lang['_network'] = 'Nettverksinnstillinger';
+$lang['_plugin_sufix'] = '&ndash; innstillinger for tillegg';
+$lang['_template_sufix'] = '&ndash; innstillinger for mal';
+$lang['_msg_setting_undefined'] = 'Ingen innstillingsmetadata';
+$lang['_msg_setting_no_class'] = 'Ingen innstillingsklasse';
+$lang['_msg_setting_no_default'] = 'Ingen standard verdi';
+$lang['fmode'] = 'Rettigheter for nye filer';
+$lang['dmode'] = 'Rettigheter for nye mapper';
+$lang['lang'] = 'Språk';
+$lang['basedir'] = 'Grunnkatalog';
+$lang['baseurl'] = 'Grunn-nettadresse';
+$lang['savedir'] = 'Mappe for lagring av data';
+$lang['cookiedir'] = 'Sti for informasjonskapsler. La stå blankt for å bruke grunn-nettadressa.';
+$lang['start'] = 'Sidenavn på forsiden';
+$lang['title'] = 'Navn på Wikien';
+$lang['template'] = 'Mal';
+$lang['license'] = 'Under hvilken lisens skal ditt innhold utgis?';
+$lang['fullpath'] = 'Vis full sti til sider i bunnteksten';
+$lang['recent'] = 'Siste endringer';
+$lang['breadcrumbs'] = 'Antall nylig besøkte sider som vises';
+$lang['youarehere'] = 'Vis hvor i hvilke(t) navnerom siden er';
+$lang['typography'] = 'Gjør typografiske erstatninger';
+$lang['htmlok'] = 'Tillat HTML';
+$lang['phpok'] = 'Tillat PHP';
+$lang['dformat'] = 'Datoformat (se <a href="http://www.php.net/strftime">PHPs datofunksjon</a>)';
+$lang['signature'] = 'Signatur';
+$lang['toptoclevel'] = 'Toppnivå for innholdsfortegnelse';
+$lang['tocminheads'] = 'Minimum antall overskrifter som bestemmer om innholdsbetegnelse skal bygges.';
+$lang['maxtoclevel'] = 'Maksimalt antall nivåer i innholdsfortegnelse';
+$lang['maxseclevel'] = 'Maksimalt nivå for redigering av seksjon';
+$lang['camelcase'] = 'Gjør KamelKasse til lenke automatisk';
+$lang['deaccent'] = 'Rensk sidenavn';
+$lang['useheading'] = 'Bruk første overskrift som tittel';
+$lang['refcheck'] = 'Sjekk referanser før mediafiler slettes';
+$lang['refshow'] = 'Antall viste referanser til mediafiler';
+$lang['allowdebug'] = 'Tillat feilsøking <b>skru av om det ikke behøves!</b>';
+$lang['mediarevisions'] = 'Slå på mediaversjonering?';
+$lang['usewordblock'] = 'Blokker søppel basert på ordliste';
+$lang['indexdelay'] = 'Forsinkelse før indeksering (sekunder)';
+$lang['relnofollow'] = 'Bruk rel="nofollow" på eksterne lenker';
+$lang['mailguard'] = 'Beskytt e-postadresser';
+$lang['iexssprotect'] = 'Sjekk om opplastede filer inneholder skadelig JavaScrips- eller HTML-kode';
+$lang['showuseras'] = 'Hva som skal med når man viser brukeren som sist redigerte en side.';
+$lang['useacl'] = 'Bruk lister for adgangskontroll (ACL)';
+$lang['autopasswd'] = 'Generer passord automatisk';
+$lang['authtype'] = 'Autentiseringsmetode';
+$lang['passcrypt'] = 'Metode for kryptering av passord';
+$lang['defaultgroup'] = 'Standardgruppe';
+$lang['superuser'] = 'Superbruker - en gruppe, bruker eller liste (kommaseparert) med full tilgang til alle sider og funksjoner uavhengig av ACL-innstillingene';
+$lang['manager'] = 'Administrator - en gruppe, bruker eller liste (kommaseparert) med tilgang til visse administratorfunksjoner';
+$lang['profileconfirm'] = 'Bekreft profilendringer med passord';
+$lang['disableactions'] = 'Skru av følgende DokuWiki-kommandoer';
+$lang['disableactions_check'] = 'Sjekk';
+$lang['disableactions_subscription'] = 'Meld på/av';
+$lang['disableactions_wikicode'] = 'Vis kildekode/eksporter rådata';
+$lang['disableactions_other'] = 'Andre kommandoer (kommaseparert)';
+$lang['sneaky_index'] = 'DokuWiki vil som standard vise alle navnerom i innholdsfortegnelsen. Hvis du skrur på dette alternativet vil brukere bare se de navnerommene der de har lesetilgang. Dette kan føre til at tilgjengelige undernavnerom skjules. Det kan gjøre innholdsfortegnelsen ubrukelig med enkelte ACL-oppsett.';
+$lang['auth_security_timeout'] = 'Autentisering utløper etter (sekunder)';
+$lang['securecookie'] = 'Skal informasjonskapsler satt via HTTPS kun sendes via HTTPS av nettleseren? Skal ikke velges dersom bare innloggingen til din wiki er sikret med SSL, og annen navigering på wikien er usikret.';
+$lang['xmlrpc'] = 'Slå på/slå av XML-RPC-grensesnitt';
+$lang['xmlrpcuser'] = 'Å tillate XML-RPC-adgang til bestemte grupper eller brukere, sette deres navne (kommaseparert) her. Slik får du tilgang til alle, la feltet tomt.
+';
+$lang['updatecheck'] = 'Se etter oppdateringer og sikkerhetsadvarsler? Denne funksjonen er avhengig av å kontakte update.dokuwiki.org.';
+$lang['userewrite'] = 'Bruk pene URLer';
+$lang['useslash'] = 'Bruk / som skilletegn mellom navnerom i URLer';
+$lang['usedraft'] = 'Lagre kladd automatisk under redigering';
+$lang['sepchar'] = 'Skilletegn mellom ord i sidenavn';
+$lang['canonical'] = 'Bruk fulle URLer (i stedet for relative)';
+$lang['fnencode'] = 'Metode for å kode ikke-ASCII-filnavn';
+$lang['autoplural'] = 'Se etter flertallsformer i lenker';
+$lang['compression'] = 'Metode for komprimering av gamle filer';
+$lang['cachetime'] = 'Maksimal alder på hurtiglager (sekunder)';
+$lang['locktime'] = 'Maksimal alder på låsefiler (sekunder)';
+$lang['fetchsize'] = 'Maksimal størrelse (byter) fetch.php kan laste eksternt';
+$lang['notify'] = 'Send meldinger om endringer denne e-postadressen';
+$lang['registernotify'] = 'Send info om nylig registrerte brukere til denne e-postadressen';
+$lang['mailfrom'] = 'Avsenderadresse for automatiske e-poster';
+$lang['mailprefix'] = 'Prefiks for emne i automatiske e-poster ';
+$lang['gzip_output'] = 'Bruk gzip Content-Encoding for XHTML';
+$lang['gdlib'] = 'Versjon av libGD';
+$lang['im_convert'] = 'Sti til ImageMagicks konverteringsverktøy';
+$lang['jpg_quality'] = 'JPEG-kvalitet (0-100)';
+$lang['subscribers'] = 'Åpne for abonnement på endringer av en side';
+$lang['subscribe_time'] = 'Hvor lenge det skal gå mellom utsending av e-poster med endringer (i sekunder). Denne verdien bør være mindre enn verdien i recent_days.';
+$lang['compress'] = 'Kompakt CSS og JavaScript';
+$lang['cssdatauri'] = 'Opp til denne størrelsen (i bytes) skal bilder som er vist til i CSS-filer kodes direkte inn i fila for å redusere antall HTTP-forespørsler. Denne teknikken fungerer ikke i IE < 8! Mellom <code>400</code> og <code>600</code> bytes er fornuftige verdier. Bruk <code>0</code> for å skru av funksjonen.';
+$lang['hidepages'] = 'Skjul sider fra automatiske lister (regulære uttrykk)';
+$lang['send404'] = 'Send "HTTP 404/Page Not Found" for ikke-eksisterende sider';
+$lang['sitemap'] = 'Lag Google-sidekart (dager)';
+$lang['broken_iua'] = 'Er funksjonen ignore_user_abort på ditt system ødelagt? Dette kan gjøre at indeksering av søk ikke fungerer. Dette er et kjent problem med IIS+PHP/CGI. Se <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> for mer informasjon.';
+$lang['xsendfile'] = 'Bruk X-Sendfile header for å la webserver levere statiske filer? Din webserver må støtte dette.';
+$lang['renderer_xhtml'] = 'Renderer til bruk for wiki-output (XHTML)';
+$lang['renderer__core'] = '%s (dokuwikikjerne)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Tillat permanente informasjonskapsler for innlogging (husk meg)';
+$lang['rss_type'] = 'Type XML-feed';
+$lang['rss_linkto'] = 'XML-feed lenker til';
+$lang['rss_content'] = 'Hva skal vises i XML-feed elementer?';
+$lang['rss_update'] = 'Intervall for oppdatering av XML-feed (sekunder)';
+$lang['recent_days'] = 'Hvor lenge skal nylige endringer beholdes (dager)';
+$lang['rss_show_summary'] = 'Vis redigeringskommentar i tittelen på elementer i XML-feed ';
+$lang['target____wiki'] = 'Mål for interne linker';
+$lang['target____interwiki'] = 'Mål for interwiki-lenker';
+$lang['target____extern'] = 'Mål for eksterne lenker';
+$lang['target____media'] = 'Mål for lenker til mediafiler';
+$lang['target____windows'] = 'Mål for lenker til nettverksstasjoner i Windows';
+$lang['proxy____host'] = 'Navn på proxyserver';
+$lang['proxy____port'] = 'Proxyport';
+$lang['proxy____user'] = 'Brukernavn på proxyserver';
+$lang['proxy____pass'] = 'Passord på proxyserver';
+$lang['proxy____ssl'] = 'Bruk SSL for å koble til proxyserver';
+$lang['proxy____except'] = 'Regulært uttrykk for URLer som ikke trenger en proxy.';
+$lang['safemodehack'] = 'Bruk safemode-hack';
+$lang['ftp____host'] = 'FTP-server for safemode-hack';
+$lang['ftp____port'] = 'FTP-port for safemode-hack';
+$lang['ftp____user'] = 'FTP-brukernavn for safemode-hack';
+$lang['ftp____pass'] = 'FTP-passord for safemode-hack';
+$lang['ftp____root'] = 'FTP-rotmappe for safemode-hack';
+$lang['license_o_'] = 'Ingen valgt';
+$lang['typography_o_0'] = 'ingen';
+$lang['typography_o_1'] = 'Kun doble anførselstegn';
+$lang['typography_o_2'] = 'Alle anførselstegn (virker ikke alltid)';
+$lang['userewrite_o_0'] = 'ingen';
+$lang['userewrite_o_1'] = 'Apache (.htaccess)';
+$lang['userewrite_o_2'] = 'DokuWiki internt';
+$lang['deaccent_o_0'] = 'av';
+$lang['deaccent_o_1'] = 'fjern aksenter';
+$lang['deaccent_o_2'] = 'bytt til kun latinske bokstaver';
+$lang['gdlib_o_0'] = 'GD lib ikke tilgjengelig';
+$lang['gdlib_o_1'] = 'Versjon 1.x';
+$lang['gdlib_o_2'] = 'Automatisk oppdaging';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Ingress';
+$lang['rss_content_o_diff'] = 'Forent Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML-formatert diff-tabell';
+$lang['rss_content_o_html'] = 'Full HTML sideinnhold';
+$lang['rss_linkto_o_diff'] = 'endringsvisning';
+$lang['rss_linkto_o_page'] = 'den endrede siden';
+$lang['rss_linkto_o_rev'] = 'liste over endringer';
+$lang['rss_linkto_o_current'] = 'den nåværende siden';
+$lang['compression_o_0'] = 'ingen';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ikke bruk';
+$lang['xsendfile_o_1'] = 'Proprietær lighttpd header (før release 1.5)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile header';
+$lang['xsendfile_o_3'] = 'Priprietær Nginx X-Accel-Redirect header';
+$lang['showuseras_o_loginname'] = 'Brukernavn';
+$lang['showuseras_o_username'] = 'Brukerens fulle navn';
+$lang['showuseras_o_email'] = 'Brukerens e-postadresse (tilpasset i henhold til mailguar-instilling)';
+$lang['showuseras_o_email_link'] = 'Brukerens epost-addresse som "mailto:"-lenke';
+$lang['useheading_o_0'] = 'Aldri';
+$lang['useheading_o_navigation'] = 'Kun navigering';
+$lang['useheading_o_content'] = 'Kun wiki-innhold';
+$lang['useheading_o_1'] = 'Alltid';
+$lang['readdircache'] = 'Maksimal alder for mellomlagring av mappen med søkeindekser (sekunder)';
diff --git a/lib/plugins/config/lang/pl/intro.txt b/lib/plugins/config/lang/pl/intro.txt
new file mode 100644
index 000000000..72c0e1c13
--- /dev/null
+++ b/lib/plugins/config/lang/pl/intro.txt
@@ -0,0 +1,9 @@
+====== Menadżer konfiguracji ======
+
+Na tej stronie można zmienić ustawienia tej instalacji DokuWiki. W celu uzyskania pomocy na temat ustawień zajrzyj na stronę o [[doku>config|konfiguracji]]. W celu uzyskania informacji o tej wtyczce zajrzyj na stronę o [[doku>plugin:config|wtyczce]].
+
+Ustawienia w kolorze jasnoczerwonym są chronione i nie mogą być zmienioną z użyciem tej wtyczki. Ustawienia w kolorze niebieskim mają domyślne wartości. Ustawienia w kolorze białym są specyficzne dla tej instalacji. Ustawienia w kolorach niebieskim i białym mogą być zmienione.
+
+W celu zapisania nowej konfiguracji naciśnij **zapisz** przed opuszczeniem tej strony.
+
+
diff --git a/lib/plugins/config/lang/pl/lang.php b/lib/plugins/config/lang/pl/lang.php
new file mode 100644
index 000000000..a04f45c87
--- /dev/null
+++ b/lib/plugins/config/lang/pl/lang.php
@@ -0,0 +1,199 @@
+<?php
+/**
+ * polish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Grzegorz Żur <grzegorz.zur@gmail.com>
+ * @author Mariusz Kujawski <marinespl@gmail.com>
+ * @author Maciej Kurczewski <pipijajko@gmail.com>
+ * @author Sławomir Boczek <slawkens@gmail.com>
+ * @author Piotr JANKOWSKI <jankowski.piotr@gmail.com>
+ * @author sleshek@wp.pl
+ * @author Leszek Stachowski <shazarre@gmail.com>
+ * @author maros <dobrimaros@yahoo.pl>
+ * @author Grzegorz Widła <dzesdzes@gmail.com>
+ * @author Łukasz Chmaj <teachmeter@gmail.com>
+ * @author Begina Felicysym <begina.felicysym@wp.eu>
+ */
+$lang['menu'] = 'Ustawienia';
+$lang['error'] = 'Ustawienia nie zostały zapisane z powodu błędnych wartości, przejrzyj je i ponów próbę zapisu. <br/> Niepoprawne wartości są wyróżnione kolorem czerwonym.';
+$lang['updated'] = 'Ustawienia zostały zmienione.';
+$lang['nochoice'] = '(brak innych możliwości)';
+$lang['locked'] = 'Plik ustawień nie mógł zostać zmieniony, upewnij się, czy uprawnienia do pliku są odpowiednie.';
+$lang['danger'] = 'Uwaga: Zmiana tej opcji może uniemożliwić dostęp do twojej wiki oraz konfiguracji.';
+$lang['warning'] = 'Ostrzeżenie: Zmiana tej opcji może spowodować nieporządane skutki.';
+$lang['security'] = 'Alert bezpieczeństwa: Zmiana tej opcji może obniżyć bezpieczeństwo.';
+$lang['_configuration_manager'] = 'Menadżer konfiguracji';
+$lang['_header_dokuwiki'] = 'Ustawienia DokuWiki';
+$lang['_header_plugin'] = 'Ustawienia wtyczek';
+$lang['_header_template'] = 'Ustawienia motywu';
+$lang['_header_undefined'] = 'Inne ustawienia';
+$lang['_basic'] = 'Podstawowe';
+$lang['_display'] = 'Wygląd';
+$lang['_authentication'] = 'Autoryzacja';
+$lang['_anti_spam'] = 'Spam';
+$lang['_editing'] = 'Edycja';
+$lang['_links'] = 'Odnośniki';
+$lang['_media'] = 'Media';
+$lang['_advanced'] = 'Zaawansowane';
+$lang['_network'] = 'Sieć';
+$lang['_plugin_sufix'] = 'Wtyczki';
+$lang['_template_sufix'] = 'Motywy';
+$lang['_msg_setting_undefined'] = 'Brak danych o ustawieniu.';
+$lang['_msg_setting_no_class'] = 'Brak kategorii ustawień.';
+$lang['_msg_setting_no_default'] = 'Brak wartości domyślnej.';
+$lang['fmode'] = 'Tryb tworzenia pliku';
+$lang['dmode'] = 'Tryb tworzenia katalogu';
+$lang['lang'] = 'Język';
+$lang['basedir'] = 'Katalog główny';
+$lang['baseurl'] = 'Główny URL';
+$lang['savedir'] = 'Katalog z danymi';
+$lang['cookiedir'] = 'Ścieżka plików ciasteczek. Zostaw puste by użyć baseurl.';
+$lang['start'] = 'Tytuł strony początkowej';
+$lang['title'] = 'Tytuł wiki';
+$lang['template'] = 'Motyw';
+$lang['tagline'] = 'Motto (jeśli szablon daje taką możliwość)';
+$lang['sidebar'] = 'Nazwa strony paska bocznego (jeśli szablon je obsługuje), puste pole wyłącza pasek boczny';
+$lang['license'] = 'Pod jaką licencją publikować treści wiki?';
+$lang['fullpath'] = 'Wyświetlanie pełnych ścieżek';
+$lang['recent'] = 'Ilość ostatnich zmian';
+$lang['breadcrumbs'] = 'Długość śladu';
+$lang['youarehere'] = 'Ślad według struktury';
+$lang['typography'] = 'Konwersja cudzysłowu, myślników itp.';
+$lang['htmlok'] = 'Wstawki HTML';
+$lang['phpok'] = 'Wstawki PHP';
+$lang['dformat'] = 'Format daty';
+$lang['signature'] = 'Podpis';
+$lang['toptoclevel'] = 'Minimalny poziom spisu treści';
+$lang['tocminheads'] = 'Minimalna liczba nagłówków niezbędna do wytworzenia spisu treści.';
+$lang['maxtoclevel'] = 'Maksymalny poziom spisu treści';
+$lang['maxseclevel'] = 'Maksymalny poziom podziału na sekcje edycyjne';
+$lang['camelcase'] = 'Bikapitalizacja odnośników (CamelCase)';
+$lang['deaccent'] = 'Podmieniaj znaki spoza ASCII w nazwach';
+$lang['useheading'] = 'Pierwszy nagłówek jako tytuł';
+$lang['refcheck'] = 'Sprawdzanie odwołań przed usunięciem pliku';
+$lang['refshow'] = 'Ilość pokazywanych odwołań do pliku';
+$lang['allowdebug'] = 'Debugowanie (niebezpieczne!)';
+$lang['mediarevisions'] = 'Włączyć wersjonowanie multimediów?';
+$lang['usewordblock'] = 'Blokowanie spamu na podstawie słów';
+$lang['indexdelay'] = 'Okres indeksowania w sekundach';
+$lang['relnofollow'] = 'Nagłówek rel="nofollow" dla odnośników zewnętrznych';
+$lang['mailguard'] = 'Utrudnianie odczytu adresów e-mail';
+$lang['iexssprotect'] = 'Wykrywanie złośliwego kodu JavaScript i HTML w plikach';
+$lang['showuseras'] = 'Sposób wyświetlania nazwy użytkownika, który ostatnio edytował stronę';
+$lang['useacl'] = 'Kontrola uprawnień ACL';
+$lang['autopasswd'] = 'Automatyczne generowanie haseł';
+$lang['authtype'] = 'Typ autoryzacji';
+$lang['passcrypt'] = 'Kodowanie hasła';
+$lang['defaultgroup'] = 'Domyślna grupa';
+$lang['superuser'] = 'Administrator - grupa lub użytkownik z pełnymi uprawnieniami';
+$lang['manager'] = 'Menadżer - grupa lub użytkownik z uprawnieniami do zarządzania wiki';
+$lang['profileconfirm'] = 'Potwierdzanie zmiany profilu hasłem';
+$lang['disableactions'] = 'Wyłącz akcje DokuWiki';
+$lang['disableactions_check'] = 'Sprawdzanie';
+$lang['disableactions_subscription'] = 'Subskrypcje';
+$lang['disableactions_wikicode'] = 'Pokazywanie źródeł';
+$lang['disableactions_other'] = 'Inne akcje (oddzielone przecinkiem)';
+$lang['sneaky_index'] = 'Domyślnie, Dokuwiki pokazuje wszystkie katalogi w indeksie. Włączenie tej opcji ukryje katalogi, do których użytkownik nie ma praw. Może to spowodować ukrycie podkatalogów, do których użytkownik ma prawa. Ta opcja może spowodować błędne działanie indeksu w połączeniu z pewnymi konfiguracjami praw dostępu.';
+$lang['auth_security_timeout'] = 'Czas wygaśnięcia uwierzytelnienia (w sekundach)';
+$lang['securecookie'] = 'Czy ciasteczka wysłane do przeglądarki przez HTTPS powinny być przez nią odsyłane też tylko przez HTTPS? Odznacz tę opcję tylko wtedy, gdy logowanie użytkowników jest zabezpieczone SSL, ale przeglądanie stron odbywa się bez zabezpieczenia.';
+$lang['xmlrpc'] = 'Włącz/wyłącz interfejs XML-RPC';
+$lang['xmlrpcuser'] = 'Lista użytkowników i grup, którzy mogą korzystać z protokołu XML-RPC. Nazwy grup i użytkowników rozdziel przecinkami, puste pole oznacza dostęp dla wszystkich.';
+$lang['updatecheck'] = 'Sprawdzanie aktualizacji i bezpieczeństwa. DokuWiki będzie kontaktować się z serwerem update.dokuwiki.org.';
+$lang['userewrite'] = 'Proste adresy URL';
+$lang['useslash'] = 'Używanie ukośnika jako separatora w adresie URL';
+$lang['usedraft'] = 'Automatyczne zapisywanie szkicu podczas edycji';
+$lang['sepchar'] = 'Znak rozdzielający wyrazy nazw';
+$lang['canonical'] = 'Kanoniczne adresy URL';
+$lang['fnencode'] = 'Metoda kodowana nazw pików bez użycia ASCII.';
+$lang['autoplural'] = 'Automatyczne tworzenie liczby mnogiej';
+$lang['compression'] = 'Metoda kompresji dla usuniętych plików';
+$lang['cachetime'] = 'Maksymalny wiek cache w sekundach';
+$lang['locktime'] = 'Maksymalny wiek blokad w sekundach';
+$lang['fetchsize'] = 'Maksymalny rozmiar pliku (w bajtach) jaki można pobrać z zewnątrz';
+$lang['notify'] = 'Wysyłanie powiadomień na adres e-mail';
+$lang['registernotify'] = 'Prześlij informacje o nowych użytkownikach na adres e-mail';
+$lang['mailfrom'] = 'Adres e-mail tego wiki';
+$lang['mailprefix'] = 'Prefiks tematu e-mail do automatycznych wiadomości';
+$lang['gzip_output'] = 'Używaj kodowania GZIP dla zawartości XHTML';
+$lang['gdlib'] = 'Wersja biblioteki GDLib';
+$lang['im_convert'] = 'Ścieżka do programu imagemagick';
+$lang['jpg_quality'] = 'Jakość kompresji JPG (0-100)';
+$lang['subscribers'] = 'Subskrypcja';
+$lang['subscribe_time'] = 'Czas po którym są wysyłane listy subskrypcji i streszczenia (sek.); Powinna być to wartość większa niż podana w zmiennej recent_days.';
+$lang['compress'] = 'Kompresja arkuszy CSS i plików JavaScript';
+$lang['cssdatauri'] = 'Rozmiar w bajtach, poniżej którego odwołania do obrazów w plikach CSS powinny być osadzone bezpośrednio w arkuszu stylów by zmniejszyć ogólne żądania nagłówków HTTP. Technika ta nie działa w IE 7 i poniżej! <code>400</code> do <code>600</code> bajtów jest dobrą wartością. Ustaw <code>0</code> aby wyłączyć.';
+$lang['hidepages'] = 'Ukrywanie stron pasujących do wzorca (wyrażenie regularne)';
+$lang['send404'] = 'Nagłówek "HTTP 404/Page Not Found" dla nieistniejących stron';
+$lang['sitemap'] = 'Okres generowania Google Sitemap (w dniach)';
+$lang['broken_iua'] = 'Czy funkcja "ignore_user_abort" działa? Jeśli nie, może to powodować problemy z indeksem przeszukiwania. Funkcja nie działa przy konfiguracji oprogramowania IIS+PHP/CGI. Szczegółowe informacje: <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>.';
+$lang['xsendfile'] = 'Użyj nagłówka HTTP X-Sendfile w celu przesyłania statycznych plików. Serwer HTTP musi obsługiwać ten nagłówek.';
+$lang['renderer_xhtml'] = 'Mechanizm renderowania głównej treści strony (xhtml)';
+$lang['renderer__core'] = '%s (dokuwiki)';
+$lang['renderer__plugin'] = '%s (wtyczka)';
+$lang['rememberme'] = 'Pozwól na ciasteczka automatycznie logujące (pamiętaj mnie)';
+$lang['rss_type'] = 'Typ RSS';
+$lang['rss_linkto'] = 'Odnośniki w RSS';
+$lang['rss_content'] = 'Rodzaj informacji wyświetlanych w RSS ';
+$lang['rss_update'] = 'Okres aktualizacji RSS (w sekundach)';
+$lang['recent_days'] = 'Ilość ostatnich zmian (w dniach)';
+$lang['rss_show_summary'] = 'Podsumowanie w tytule';
+$lang['target____wiki'] = 'Okno docelowe odnośników wewnętrznych';
+$lang['target____interwiki'] = 'Okno docelowe odnośników do innych wiki';
+$lang['target____extern'] = 'Okno docelowe odnośników zewnętrznych';
+$lang['target____media'] = 'Okno docelowe odnośników do plików';
+$lang['target____windows'] = 'Okno docelowe odnośników zasobów Windows';
+$lang['proxy____host'] = 'Proxy - serwer';
+$lang['proxy____port'] = 'Proxy - port';
+$lang['proxy____user'] = 'Proxy - nazwa użytkownika';
+$lang['proxy____pass'] = 'Proxy - hasło';
+$lang['proxy____ssl'] = 'Proxy - SSL';
+$lang['proxy____except'] = 'Wyrażenie regularne określające adresy URL, do których nie należy używać proxy.';
+$lang['safemodehack'] = 'Bezpieczny tryb (przez FTP)';
+$lang['ftp____host'] = 'FTP - serwer';
+$lang['ftp____port'] = 'FTP - port';
+$lang['ftp____user'] = 'FTP - nazwa użytkownika';
+$lang['ftp____pass'] = 'FTP - hasło';
+$lang['ftp____root'] = 'FTP - katalog główny';
+$lang['license_o_'] = 'Nie wybrano żadnej';
+$lang['typography_o_0'] = 'brak';
+$lang['typography_o_1'] = 'tylko podwójne cudzysłowy';
+$lang['typography_o_2'] = 'wszystkie cudzysłowy (nie działa we wszystkich przypadkach)';
+$lang['userewrite_o_0'] = 'brak';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'dokuwiki';
+$lang['deaccent_o_0'] = 'zostaw oryginalną pisownię';
+$lang['deaccent_o_1'] = 'usuń litery';
+$lang['deaccent_o_2'] = 'zamień na ASCII';
+$lang['gdlib_o_0'] = 'biblioteka GDLib niedostępna';
+$lang['gdlib_o_1'] = 'wersja 1.x';
+$lang['gdlib_o_2'] = 'automatyczne wykrywanie';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Streszczenie';
+$lang['rss_content_o_diff'] = 'Różnice';
+$lang['rss_content_o_htmldiff'] = 'Różnice w postaci HTML';
+$lang['rss_content_o_html'] = 'Pełna strona w postaci HTML';
+$lang['rss_linkto_o_diff'] = 'różnice';
+$lang['rss_linkto_o_page'] = 'zmodyfikowana strona';
+$lang['rss_linkto_o_rev'] = 'lista zmian';
+$lang['rss_linkto_o_current'] = 'aktualna strona';
+$lang['compression_o_0'] = 'brak';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nie używaj';
+$lang['xsendfile_o_1'] = 'Specyficzny nagłówek lightttpd (poniżej wersji 1.5)';
+$lang['xsendfile_o_2'] = 'Standardowy nagłówek HTTP X-Sendfile';
+$lang['xsendfile_o_3'] = 'Specyficzny nagłówek Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Login użytkownika';
+$lang['showuseras_o_username'] = 'Pełne nazwisko użytkownika';
+$lang['showuseras_o_email'] = 'E-mail użytkownika (ukrywanie według ustawień mailguard)';
+$lang['showuseras_o_email_link'] = 'Adresy e-mail użytkowników w formie linku mailto:';
+$lang['useheading_o_0'] = 'Nigdy';
+$lang['useheading_o_navigation'] = 'W nawigacji';
+$lang['useheading_o_content'] = 'W treści';
+$lang['useheading_o_1'] = 'Zawsze';
+$lang['readdircache'] = 'Maksymalny czas dla bufora readdir (w sek).';
diff --git a/lib/plugins/config/lang/pt-br/intro.txt b/lib/plugins/config/lang/pt-br/intro.txt
new file mode 100644
index 000000000..850ba25cb
--- /dev/null
+++ b/lib/plugins/config/lang/pt-br/intro.txt
@@ -0,0 +1,7 @@
+====== Gerenciador de Configurações ======
+
+Use essa página para controlar as configurações da instalação do seu DokuWiki. Para ajuda acerca dos itens, consulte [[doku>config]]. Para mais detalhes sobre esse plug-in, veja [[doku>plugin:config]].
+
+Definições que apresentem um fundo vermelho claro são protegidas e não podem ser alteradas com esse plug-in. As definições com um fundo azul são o padrão e as com um fundo branco foram configuradas localmente para essa instalação em particular. Tanto as definições em azul quanto as em branco podem ser alteradas.
+
+Lembre-se de pressionar o botão **Salvar** antes de sair dessa página, caso contrário, suas configurações serão perdidas. \ No newline at end of file
diff --git a/lib/plugins/config/lang/pt-br/lang.php b/lib/plugins/config/lang/pt-br/lang.php
new file mode 100644
index 000000000..093e60ff8
--- /dev/null
+++ b/lib/plugins/config/lang/pt-br/lang.php
@@ -0,0 +1,200 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Lucien Raven <lucienraven@yahoo.com.br>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Flávio Veras <flaviove@gmail.com>
+ * @author Jeferson Propheta <jeferson.propheta@gmail.com>
+ * @author jair.henrique@gmail.com
+ * @author Luis Dantas <luis@dantas.com>
+ * @author Frederico Guimarães <frederico@teia.bio.br>
+ * @author Jair Henrique <jair.henrique@gmail.com>
+ * @author Luis Dantas <luisdantas@gmail.com>
+ * @author Sergio Motta sergio@cisne.com.br
+ * @author Isaias Masiero Filho <masiero@masiero.org>
+ * @author Balaco Baco <balacobaco@imap.cc>
+ */
+$lang['menu'] = 'Configurações do DokuWiki';
+$lang['error'] = 'As configurações não foram atualizadas devido a um valor inválido. Por favor, reveja suas alterações e reenvie-as.<br />O(s) valor(es) incorreto(s) serão exibidos contornados por uma borda vermelha.';
+$lang['updated'] = 'As configurações foram atualizadas com sucesso.';
+$lang['nochoice'] = '(nenhuma outra opção disponível)';
+$lang['locked'] = 'Não foi possível atualizar o arquivo de configurações. Se isso <br />
+não for intencional, certifique-se de que o nome do arquivo e as <br />
+e as suas permissões estejam corretos.';
+$lang['danger'] = 'Perigo: Alterar esta opção poderá tornar o seu wiki e menu de configuração inacessíveis.';
+$lang['warning'] = 'Aviso: A alteração desta opção pode causar um comportamento indesejável.';
+$lang['security'] = 'Aviso de segurança: A alteração desta opção pode representar um risco de segurança.';
+$lang['_configuration_manager'] = 'Gerenciador de configurações';
+$lang['_header_dokuwiki'] = 'Configurações do DokuWiki';
+$lang['_header_plugin'] = 'Configurações de plug-ins';
+$lang['_header_template'] = 'Configurações de modelos';
+$lang['_header_undefined'] = 'Configurações indefinidas';
+$lang['_basic'] = 'Configurações básicas';
+$lang['_display'] = 'Configurações de exibição';
+$lang['_authentication'] = 'Configurações de autenticação';
+$lang['_anti_spam'] = 'Configurações do anti-spam';
+$lang['_editing'] = 'Configurações de edição';
+$lang['_links'] = 'Configurações de link';
+$lang['_media'] = 'Configurações de mídia';
+$lang['_advanced'] = 'Configurações avançadas';
+$lang['_network'] = 'Configurações de rede';
+$lang['_plugin_sufix'] = 'Configurações de plug-ins';
+$lang['_template_sufix'] = 'Configurações de modelos';
+$lang['_msg_setting_undefined'] = 'Nenhum metadado configurado.';
+$lang['_msg_setting_no_class'] = 'Nenhuma classe definida.';
+$lang['_msg_setting_no_default'] = 'Nenhum valor padrão.';
+$lang['fmode'] = 'Modo de criação do arquivo';
+$lang['dmode'] = 'Modo de criação do diretório';
+$lang['lang'] = 'Idioma';
+$lang['basedir'] = 'Diretório base';
+$lang['baseurl'] = 'URL base';
+$lang['savedir'] = 'Diretório para salvar os dados';
+$lang['cookiedir'] = 'Caminhos dos cookies. Deixe em branco para usar a url base.';
+$lang['start'] = 'Nome da página inicial';
+$lang['title'] = 'Título do wiki';
+$lang['template'] = 'Modelo';
+$lang['license'] = 'Sob qual licença o seu conteúdo deve ser disponibilizado?';
+$lang['fullpath'] = 'Indica o caminho completo das páginas no rodapé';
+$lang['recent'] = 'Modificações recentes';
+$lang['breadcrumbs'] = 'Número de elementos na trilha de páginas visitadas';
+$lang['youarehere'] = 'Trilha hierárquica';
+$lang['typography'] = 'Efetuar modificações tipográficas';
+$lang['htmlok'] = 'Permitir incorporação de HTML';
+$lang['phpok'] = 'Permitir incorporação de PHP';
+$lang['dformat'] = 'Formato da data (veja a função <a href="http://www.php.net/strftime">strftime</a> do PHP)';
+$lang['signature'] = 'Assinatura';
+$lang['toptoclevel'] = 'Nível mais alto para a tabela de conteúdos';
+$lang['tocminheads'] = 'Quantidade mínima de cabeçalhos para a construção da tabela de conteúdos.';
+$lang['maxtoclevel'] = 'Nível máximo para entrar na tabela de conteúdos';
+$lang['maxseclevel'] = 'Nível máximo para gerar uma seção de edição';
+$lang['camelcase'] = 'Usar CamelCase para links';
+$lang['deaccent'] = '"Limpar" os nomes das páginas';
+$lang['useheading'] = 'Usar o primeiro cabeçalho como nome da página';
+$lang['refcheck'] = 'Verificação de referência da mídia';
+$lang['refshow'] = 'Número de referências de mídia a exibir';
+$lang['allowdebug'] = 'Habilitar a depuração <b>(desabilite se não for necessário!)</b>';
+$lang['usewordblock'] = 'Bloquear spam baseado em lista de palavras';
+$lang['indexdelay'] = 'Tempo de espera antes da indexação (seg)';
+$lang['relnofollow'] = 'Usar rel="nofollow" em links externos';
+$lang['mailguard'] = 'Obscurecer endereços de e-mail';
+$lang['iexssprotect'] = 'Verificar a existência de possíveis códigos maliciosos em HTML ou JavaScript nos arquivos enviados';
+$lang['showuseras'] = 'O que exibir quando mostrar o usuário que editou a página pela última vez';
+$lang['useacl'] = 'Usar listas de controle de acesso';
+$lang['autopasswd'] = 'Gerar senhas automaticamente';
+$lang['authtype'] = 'Método de autenticação';
+$lang['passcrypt'] = 'Método de criptografia da senha';
+$lang['defaultgroup'] = 'Grupo padrão';
+$lang['superuser'] = 'Superusuário - um grupo, usuário ou uma lista separada por vírgulas (usuário1,@grupo1,usuário2) que tenha acesso completo a todas as páginas e funções, independente das definições da ACL';
+$lang['manager'] = 'Gerente - um grupo, usuário ou uma lista separada por vírgulas (usuário1,@grupo1,usuário2) que tenha acesso a certas funções de gerenciamento';
+$lang['profileconfirm'] = 'Confirmar mudanças no perfil com a senha';
+$lang['disableactions'] = 'Desabilitar as ações do DokuWiki';
+$lang['disableactions_check'] = 'Verificação';
+$lang['disableactions_subscription'] = 'Monitoramento';
+$lang['disableactions_wikicode'] = 'Ver a fonte/Exportar sem processamento';
+$lang['disableactions_other'] = 'Outras ações (separadas por vírgula)';
+$lang['sneaky_index'] = 'Por padrão, o DokuWiki irá exibir todos os espaços de nomes na visualização do índice. Ao habilitar essa opção, serão escondidos aqueles que o usuário não tiver permissão de leitura. Isso pode resultar na omissão de subespaços de nomes, tornando o índice inútil para certas configurações de ACL.';
+$lang['auth_security_timeout'] = 'Tempo limite de segurança para autenticações (seg)';
+$lang['securecookie'] = 'Os cookies definidos via HTTPS devem ser enviados para o navegador somente via HTTPS? Desabilite essa opção quando somente a autenticação do seu wiki for realizada de maneira segura via SSL e a navegação, de maneira insegura.';
+$lang['xmlrpc'] = 'Habilitar/desabilitar interface XML-RPC.';
+$lang['xmlrpcuser'] = 'Acesso Restrito ao XML-RPC para grupos separados por virgula ou usuários aqui. Deixe em branco para conveder acesso a todos.';
+$lang['updatecheck'] = 'Verificar atualizações e avisos de segurança? O DokuWiki precisa contactar o "splitbrain.org" para efetuar esse recurso.';
+$lang['userewrite'] = 'Usar URLs "limpas"';
+$lang['useslash'] = 'Usar a barra como separador de espaços de nomes nas URLs';
+$lang['usedraft'] = 'Salvar o rascunho automaticamente durante a edição';
+$lang['sepchar'] = 'Separador de palavras no nome da página';
+$lang['canonical'] = 'Usar URLs absolutas (http://servidor/caminho)';
+$lang['fnencode'] = 'Método de codificação não-ASCII de nome de arquivos.';
+$lang['autoplural'] = 'Verificar formas plurais nos links';
+$lang['compression'] = 'Método de compressão para arquivos antigos';
+$lang['cachetime'] = 'Tempo máximo para o cache (seg)';
+$lang['locktime'] = 'Tempo máximo para o bloqueio de arquivos (seg)';
+$lang['fetchsize'] = 'Tamanho máximo (em bytes) que o "fetch.php" pode transferir do exterior';
+$lang['notify'] = 'Enviar notificações de mudança para esse endereço de e-mail';
+$lang['registernotify'] = 'Enviar informações de usuários registrados para esse endereço de e-mail';
+$lang['mailfrom'] = 'Endereço de e-mail a ser utilizado para mensagens automáticas';
+$lang['mailprefix'] = 'Prefixo do assunto dos e-mails de envio automático';
+$lang['gzip_output'] = 'Usar "Content-Encoding" do gzip para o código xhtml';
+$lang['gdlib'] = 'Versão da biblioteca "GD Lib"';
+$lang['im_convert'] = 'Caminho para a ferramenta de conversão ImageMagick';
+$lang['jpg_quality'] = 'Qualidade de compressão do JPG (0-100)';
+$lang['subscribers'] = 'Habilitar o suporte ao monitoramento de páginas';
+$lang['subscribe_time'] = 'Tempo de espera antes do envio das listas e mensagens de monitoramento (segundos); este tempo deve ser menor que o especificado no parâmetro recent_days';
+$lang['compress'] = 'Compactar as saídas de CSS e JavaScript';
+$lang['cssdatauri'] = 'Tamanho máximo em bytes para o qual as imagens referenciadas em arquivos CSS devam ser incorporadas na folha de estilos (o arquivo CSS) para reduzir o custo dos pedidos HTTP. Essa técnica não funcionará na versões do IE < 8! Valores de <code>400</code> a <code>600</code> são bons. Defina o valor <code>0</code> para desativar.';
+$lang['hidepages'] = 'Esconder páginas correspondentes (expressão regular)';
+$lang['send404'] = 'Enviar "HTTP 404/Página não encontrada" para páginas não existentes';
+$lang['sitemap'] = 'Gerar Google Sitemap (dias)';
+$lang['broken_iua'] = 'A função "ignore_user_abort" está com defeito no seu sistema? Isso pode causar um índice de busca defeituoso. IIS+PHP/CGI reconhecidamente possui esse erro. Veja o <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">bug 852</a> para mais informações.';
+$lang['xsendfile'] = 'Usar o cabeçalho "X-Sendfile" para permitir que o servidor web encaminhe arquivos estáticos? Seu servidor web precisa ter suporte a isso.';
+$lang['renderer_xhtml'] = 'Renderizador a ser utilizado para a saída principal (xhtml) do wiki';
+$lang['renderer__core'] = '%s (núcleo do DokuWiki)';
+$lang['renderer__plugin'] = '%s ("plug-in")';
+$lang['rememberme'] = 'Permitir cookies de autenticação permanentes ("Lembre-se de mim")';
+$lang['rss_type'] = 'Tipo de fonte XML';
+$lang['rss_linkto'] = 'Os links da fonte XML apontam para';
+$lang['rss_content'] = 'O que deve ser exibido nos itens da fonte XML?';
+$lang['rss_update'] = 'Intervalo de atualização da fonte XML (seg)';
+$lang['recent_days'] = 'Quantas mudanças recentes devem ser mantidas (dias)?';
+$lang['rss_show_summary'] = 'Resumo de exibição da fonte XML no título';
+$lang['target____wiki'] = 'Parâmetro "target" para links internos';
+$lang['target____interwiki'] = 'Parâmetro "target" para links interwiki';
+$lang['target____extern'] = 'Parâmetro "target" para links externos';
+$lang['target____media'] = 'Parâmetro "target" para links de mídia';
+$lang['target____windows'] = 'Parâmetro "target" para links do Windows';
+$lang['proxy____host'] = 'Nome do servidor proxy';
+$lang['proxy____port'] = 'Porta do proxy';
+$lang['proxy____user'] = 'Nome de usuário do proxy';
+$lang['proxy____pass'] = 'Senha do proxy';
+$lang['proxy____ssl'] = 'Usar SSL para conectar ao proxy';
+$lang['proxy____except'] = 'Expressões regulares de URL para excessão de proxy.';
+$lang['safemodehack'] = 'Habilitar o contorno de segurança';
+$lang['ftp____host'] = 'Servidor FTP para o contorno de segurança';
+$lang['ftp____port'] = 'Porta do FTP para o contorno de segurança';
+$lang['ftp____user'] = 'Nome do usuário FTP para o contorno de segurança';
+$lang['ftp____pass'] = 'Senha do usuário FTP para o contorno de segurança';
+$lang['ftp____root'] = 'Diretório raiz do FTP para o contorno de segurança';
+$lang['license_o_'] = 'Nenhuma escolha';
+$lang['typography_o_0'] = 'nenhuma';
+$lang['typography_o_1'] = 'excluir aspas simples';
+$lang['typography_o_2'] = 'incluir aspas simples (nem sempre funciona)';
+$lang['userewrite_o_0'] = 'não';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'interno do DokuWiki';
+$lang['deaccent_o_0'] = 'não';
+$lang['deaccent_o_1'] = 'remover acentos';
+$lang['deaccent_o_2'] = 'romanizar';
+$lang['gdlib_o_0'] = 'a "GD Lib" não está disponível';
+$lang['gdlib_o_1'] = 'versão 1.x';
+$lang['gdlib_o_2'] = 'detecção automática';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'resumo';
+$lang['rss_content_o_diff'] = 'diff unificado';
+$lang['rss_content_o_htmldiff'] = 'tabela de diff formatada em HTML';
+$lang['rss_content_o_html'] = 'conteúdo completo da página em HTML';
+$lang['rss_linkto_o_diff'] = 'visualização das diferenças';
+$lang['rss_linkto_o_page'] = 'página revisada';
+$lang['rss_linkto_o_rev'] = 'lista de revisões';
+$lang['rss_linkto_o_current'] = 'página atual';
+$lang['compression_o_0'] = 'nenhum';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'não usar';
+$lang['xsendfile_o_1'] = 'cabeçalho proprietário lighttpd (anterior à versão 1.5)';
+$lang['xsendfile_o_2'] = 'cabeçalho "X-Sendfile" padrão';
+$lang['xsendfile_o_3'] = 'cabeçalho proprietário "Nginx X-Accel-Redirect"';
+$lang['showuseras_o_loginname'] = 'nome de usuário';
+$lang['showuseras_o_username'] = 'nome completo do usuário';
+$lang['showuseras_o_email'] = 'endereço de e-mail do usuário (obscurecido segundo a definição anterior)';
+$lang['showuseras_o_email_link'] = 'endereço de e-mail de usuário como um link "mailto:"';
+$lang['useheading_o_0'] = 'nunca';
+$lang['useheading_o_navigation'] = 'somente a navegação';
+$lang['useheading_o_content'] = 'somente o conteúdo do wiki';
+$lang['useheading_o_1'] = 'sempre';
+$lang['readdircache'] = 'Tempo máximo para cache readdir (segundos)';
diff --git a/lib/plugins/config/lang/pt/intro.txt b/lib/plugins/config/lang/pt/intro.txt
new file mode 100644
index 000000000..2010dadaf
--- /dev/null
+++ b/lib/plugins/config/lang/pt/intro.txt
@@ -0,0 +1,7 @@
+====== Gerenciador de Configurações ======
+
+Use esta página para controlar as definições da instalação do seu DokuWiki. Para ajuda acerca dos itens, consulte [[doku>config]]. Para mais detalhes sobre este plugin, veja [[doku>plugin:config]].
+
+Definições que apresentem um fundo vermelho claro são protegidas e não podem ser alteradas com este plugin. Definições com um fundo azul são padrão e definições com um fundo branco foram configuradas localmente para essa instalação em particular. Tanto as definições em azul como em branco podem ser alteradas.
+
+Lembre-se de pressionar o botão **Guardar** antes de sair desta página, caso contrário, as suas definições serão perdidas. \ No newline at end of file
diff --git a/lib/plugins/config/lang/pt/lang.php b/lib/plugins/config/lang/pt/lang.php
new file mode 100644
index 000000000..fe05bd281
--- /dev/null
+++ b/lib/plugins/config/lang/pt/lang.php
@@ -0,0 +1,189 @@
+<?php
+/**
+ * Portugueselanguage file
+ *
+ * @author José Monteiro <Jose.Monteiro@DoWeDo-IT.com>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Fil <fil@meteopt.com>
+ * @author André Neves <drakferion@gmail.com>
+ * @author José Campos zecarlosdecampos@gmail.com
+ */
+$lang['menu'] = 'Configuração';
+$lang['error'] = 'Parâmetros de Configuração não actualizados devido a valores inválidos. Por favor, reveja as modificações que pretende efectuar antes de re-submetê-las.<br /> Os valores incorrectos serão mostrados dentro de uma "moldura" vermelha.';
+$lang['updated'] = 'Parâmetros de Configuração actualizados com sucesso.';
+$lang['nochoice'] = '(não existem outras escolhas disponíveis)';
+$lang['locked'] = 'O ficheiro de configuração não pôde ser actualizado, se isso foi não intencional, <br />certifique-se que o nome e as permissões do ficheiro de configuração estejam correctas.
+';
+$lang['danger'] = 'Perigo: Alterar esta opção poderá tornar o seu wiki e o menu de configuração inacessíveis.';
+$lang['warning'] = 'Aviso: A alteração desta opção poderá causar comportamento involuntário.';
+$lang['security'] = 'Aviso de segurança: Alterar esta opção pode apresentar um risco de segurança.';
+$lang['_configuration_manager'] = 'Gestor de Parâmetros de Configuração';
+$lang['_header_dokuwiki'] = 'Parâmetros DokuWiki';
+$lang['_header_plugin'] = 'Parâmetros dos Plugins';
+$lang['_header_template'] = 'Parâmetros das Templates';
+$lang['_header_undefined'] = 'Parâmetros não definidos';
+$lang['_basic'] = 'Configurações Básicas';
+$lang['_display'] = 'Configuração de Apresentação';
+$lang['_authentication'] = 'Configuração de Autenticação';
+$lang['_anti_spam'] = 'Configuração Anti-Spam';
+$lang['_editing'] = 'Configuração de Edição';
+$lang['_links'] = 'Configuração de Ligações';
+$lang['_media'] = 'Configuração de Media';
+$lang['_advanced'] = 'Configurações Avançadas';
+$lang['_network'] = 'Configuração de Rede';
+$lang['_plugin_sufix'] = 'Configuração dos Plugins';
+$lang['_template_sufix'] = 'Configuração das Templates';
+$lang['_msg_setting_undefined'] = 'Nenhum metadado configurado.';
+$lang['_msg_setting_no_class'] = 'Nenhuma classe definida.';
+$lang['_msg_setting_no_default'] = 'Sem valor por omissão.';
+$lang['fmode'] = 'Modo de criação de ficheiros.';
+$lang['dmode'] = 'Modo de criação de pastas.';
+$lang['lang'] = 'Idioma';
+$lang['basedir'] = 'Pasta Base';
+$lang['baseurl'] = 'URL Base';
+$lang['savedir'] = 'Pasta para guardar dados';
+$lang['start'] = 'Nome da Página Inicial';
+$lang['title'] = 'Título deste Wiki';
+$lang['template'] = 'Template';
+$lang['license'] = 'Sob que licença o seu conteúdo deverá ser disponibilizado?';
+$lang['fullpath'] = 'Revelar caminho completo no rodapé';
+$lang['recent'] = 'Alterações recentes';
+$lang['breadcrumbs'] = 'Número máximo de breadcrumbs';
+$lang['youarehere'] = 'Breadcrumbs hierárquicas';
+$lang['typography'] = 'Executar substituições tipográficas';
+$lang['htmlok'] = 'Permitir embeber HTML';
+$lang['phpok'] = 'Permitir embeber PHP';
+$lang['dformat'] = 'Formato de Data (ver função PHP\'s <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Assinatura';
+$lang['toptoclevel'] = 'Nível de topo para a tabela de conteúdo';
+$lang['tocminheads'] = 'Quantidade mínima de cabeçalhos para a construção da tabela de conteúdos.';
+$lang['maxtoclevel'] = 'Máximo nível para a tabela de conteúdo';
+$lang['maxseclevel'] = 'Máximo nível para editar secção';
+$lang['camelcase'] = 'Usar CamelCase';
+$lang['deaccent'] = 'Nomes das páginas sem acentos';
+$lang['useheading'] = 'Usar o primeiro cabeçalho para o nome da página';
+$lang['refcheck'] = 'Verificação de referência da media';
+$lang['refshow'] = 'Número de referências de media a exibir';
+$lang['allowdebug'] = 'Permitir depuração <b>desabilite se não for necessário!</b>';
+$lang['usewordblock'] = 'Bloquear spam baseado em lista de palavras (wordlist)';
+$lang['indexdelay'] = 'Tempo de espera antes da indexação (seg)';
+$lang['relnofollow'] = 'Usar rel="nofollow" em links externos';
+$lang['mailguard'] = 'Obscurecer endereços de email';
+$lang['iexssprotect'] = 'Verificar os arquivos enviados contra possíveis códigos maliciosos em HTML ou JavaScript';
+$lang['showuseras'] = 'O que exibir quando mostrar o utilizador que editou a página pela última vez';
+$lang['useacl'] = 'Usar ACL - Listas de Controlo de Acessos';
+$lang['autopasswd'] = 'Auto-gerar senhas';
+$lang['authtype'] = 'Método de autenticação';
+$lang['passcrypt'] = 'Método de cifragem da senha';
+$lang['defaultgroup'] = 'Grupo por omissão';
+$lang['superuser'] = 'Superutilizador - um grupo, utilizador ou uma lista separada por vírgulas usuário1,@grupo1,usuário2 que tem acesso completo a todas as páginas e funções, independente das definições da ACL';
+$lang['manager'] = 'Gestor - um grupo, utilizador ou uma lista separada por vírgulas usuário1,@grupo1,usuário2 que tem acesso a certas funções de gestão';
+$lang['profileconfirm'] = 'Confirmar mudanças no perfil com a senha';
+$lang['disableactions'] = 'Desactivar acções DokuWiki';
+$lang['disableactions_check'] = 'Checar';
+$lang['disableactions_subscription'] = 'Subscrever/Não Subscrver';
+$lang['disableactions_wikicode'] = 'Ver fonte/Exportar em bruto';
+$lang['disableactions_other'] = 'Outras acções (separadas por vírgula)';
+$lang['sneaky_index'] = 'Por norma, o DokuWiki irá exibir todos os espaços de nomes na visualização do índice. Ao habilitar essa opção, serão escondidos aqueles em que o utilizador não tenha permissão de leitura. Isto pode resultar na omissão de sub-ramos acessíveis, que poderá tornar o índice inútil para certas configurações de ACL.';
+$lang['auth_security_timeout'] = 'Tempo limite de segurança para autenticações (seg)';
+$lang['securecookie'] = 'Os cookies definidos via HTTPS deverão ser enviados para o navegador somente via HTTPS? Desabilite essa opção quando somente a autenticação do seu wiki for realizada de maneira segura via SSL e a navegação de maneira insegura.';
+$lang['xmlrpc'] = 'Habilitar/desabilitar interface XML-RPC.';
+$lang['xmlrpcuser'] = 'Restringir acesso XML-RPC para os grupos separados por vírgula ou utilizadores inseridos aqui. Deixar vazio para dar acesso a todos.';
+$lang['updatecheck'] = 'Verificar por actualizações e avisos de segurança? O DokuWiki precisa contactar o "splitbrain.org" para efectuar esta verificação.';
+$lang['userewrite'] = 'Usar URLs SEO';
+$lang['useslash'] = 'Usar a barra como separador de espaços de nomes nas URLs';
+$lang['usedraft'] = 'Guardar o rascunho automaticamente durante a edição';
+$lang['sepchar'] = 'Separador de palavras no nome da página';
+$lang['canonical'] = 'Usar URLs absolutas (http://servidor/caminho)';
+$lang['fnencode'] = 'Método de codificar nomes de ficheiro não-ASCII.';
+$lang['autoplural'] = 'Verificar formas plurais nos links';
+$lang['compression'] = 'Método de compressão para histórico';
+$lang['cachetime'] = 'Idade máxima para cache (seg.)';
+$lang['locktime'] = 'Idade máxima para locks (seg.)';
+$lang['fetchsize'] = 'Tamanho máximo (bytes) que o fetch.php pode transferir do exterior';
+$lang['notify'] = 'Enviar notificações de mudanças para este endereço de email';
+$lang['registernotify'] = 'Enviar informações de utilizadores registados para este endereço de email';
+$lang['mailfrom'] = 'Endereço de email a ser utilizado para mensagens automáticas';
+$lang['mailprefix'] = 'Prefixo de email a ser utilizado para mensagens automáticas';
+$lang['gzip_output'] = 'Usar "Content-Encoding" do gzip para o código xhtml';
+$lang['gdlib'] = 'Versão GD Lib';
+$lang['im_convert'] = 'Caminho para a ferramenta "convert" do ImageMagick';
+$lang['jpg_quality'] = 'Compressão/Qualidade JPG (0-100)';
+$lang['subscribers'] = 'Habilitar o suporte a subscrição de páginas ';
+$lang['subscribe_time'] = 'Tempo após o qual as listas de subscrição e "digests" são enviados (seg.); Isto deve ser inferior ao tempo especificado em recent_days.';
+$lang['compress'] = 'Compactar as saídas de CSS e JavaScript';
+$lang['cssdatauri'] = 'Tamanho em bytes até ao qual as imagens referenciadas em ficheiros CSS devem ser embutidas diretamente no CSS para reduzir a carga de pedidos HTTP extra. Esta técnica não funciona em IE 7 e abaixo! <code>400</code> a <code>600</code> bytes é um bom valor. Escolher <code>0</code> para desativar.';
+$lang['hidepages'] = 'Esconder páginas correspondentes (expressões regulares)';
+$lang['send404'] = 'Enviar "HTTP 404/Página não encontrada" para páginas não existentes';
+$lang['sitemap'] = 'Gerar Sitemap Google (dias)';
+$lang['broken_iua'] = 'A função "ignore_user_abort" não está a funcionar no seu sistema? Isso pode causar um índice de busca defeituoso. Sistemas com IIS+PHP/CGI são conhecidos por possuírem este problema. Veja o <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">bug 852</a> para mais informações.';
+$lang['xsendfile'] = 'Usar o cabeçalho "X-Sendfile" para permitir o servidor de internet encaminhar ficheiros estáticos? O seu servidor de internet precisa ter suporte a isso.';
+$lang['renderer_xhtml'] = 'Renderizador a ser utilizado para a saída principal do wiki (xhtml)';
+$lang['renderer__core'] = '%s (núcleo dokuwiki)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Permitir cookies de autenticação permanentes (Memorizar?)';
+$lang['rss_type'] = 'Tipo de feed XML';
+$lang['rss_linkto'] = 'Links de feed XML ara';
+$lang['rss_content'] = 'O que deve ser exibido nos itens do alimentador XML?';
+$lang['rss_update'] = 'Intervalo de actualização do alimentador XML (seg)';
+$lang['recent_days'] = 'Quantas mudanças recentes devem ser mantidas? (dias)';
+$lang['rss_show_summary'] = 'Resumo de exibição do alimentador XML no título';
+$lang['target____wiki'] = 'Parâmetro "target" para links internos';
+$lang['target____interwiki'] = 'Parâmetro "target" para links entre wikis';
+$lang['target____extern'] = 'Parâmetro "target" para links externos';
+$lang['target____media'] = 'Parâmetro "target" para links de media';
+$lang['target____windows'] = 'Parâmetro "target" para links do Windows';
+$lang['proxy____host'] = 'Nome do servidor proxy';
+$lang['proxy____port'] = 'Porta de Proxy';
+$lang['proxy____user'] = 'Nome de utilizador Proxy';
+$lang['proxy____pass'] = 'Password de Proxy ';
+$lang['proxy____ssl'] = 'Usar SSL para conectar ao proxy';
+$lang['proxy____except'] = 'Expressão regular para condizer URLs para os quais o proxy deve ser saltado.';
+$lang['safemodehack'] = 'Habilitar modo de segurança';
+$lang['ftp____host'] = 'Servidor FTP para o modo de segurança';
+$lang['ftp____port'] = 'Porta de FTP para o modo de segurança';
+$lang['ftp____user'] = 'Nome do utilizador FTP para o modo de segurança';
+$lang['ftp____pass'] = 'Senha do utilizador FTP para o modo de segurança';
+$lang['ftp____root'] = 'Directoria raiz do FTP para o modo de segurança';
+$lang['license_o_'] = 'Nenhuma escolha';
+$lang['typography_o_0'] = 'nenhum';
+$lang['typography_o_1'] = 'Apenas entre aspas';
+$lang['typography_o_2'] = 'Entre aspas e apóstrofes';
+$lang['userewrite_o_0'] = 'nenhum';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'interno (DokuWiki)';
+$lang['deaccent_o_0'] = 'desligado';
+$lang['deaccent_o_1'] = 'remover acentos';
+$lang['deaccent_o_2'] = 'romanizar';
+$lang['gdlib_o_0'] = 'A GD Lib não está disponível';
+$lang['gdlib_o_1'] = 'Versão 1.x';
+$lang['gdlib_o_2'] = 'Auto-detecção';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Abstracto';
+$lang['rss_content_o_diff'] = 'Diferenças Unificadas';
+$lang['rss_content_o_htmldiff'] = 'Tabela de diff formatada em HTML';
+$lang['rss_content_o_html'] = 'Conteúdo completo da página em HTML';
+$lang['rss_linkto_o_diff'] = 'vista de diferenças';
+$lang['rss_linkto_o_page'] = 'página revista';
+$lang['rss_linkto_o_rev'] = 'lista de revisões';
+$lang['rss_linkto_o_current'] = 'página actual';
+$lang['compression_o_0'] = 'Sem Compressão';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'não usar';
+$lang['xsendfile_o_1'] = 'Cabeçalho proprietário lighttpd (anterior à versão 1.5)';
+$lang['xsendfile_o_2'] = 'Cabeçalho "X-Sendfile" padrão';
+$lang['xsendfile_o_3'] = 'Cabeçalho proprietário "Nginx X-Accel-Redirect"';
+$lang['showuseras_o_loginname'] = 'Nome de utilizador';
+$lang['showuseras_o_username'] = 'Nome completo do utilizador';
+$lang['showuseras_o_email'] = 'Endereço email do utilizador (ofuscado de acordo com a configuração mailguard)';
+$lang['showuseras_o_email_link'] = 'Endereço de e-mail de usuário como um link "mailto:"';
+$lang['useheading_o_0'] = 'Nunca';
+$lang['useheading_o_navigation'] = 'Apenas Navegação';
+$lang['useheading_o_content'] = 'Apenas Conteúdo Wiki';
+$lang['useheading_o_1'] = 'Sempre';
+$lang['readdircache'] = 'Idade máxima para a cache de "readdir" (seg)';
diff --git a/lib/plugins/config/lang/ro/intro.txt b/lib/plugins/config/lang/ro/intro.txt
new file mode 100644
index 000000000..f5cbbe81e
--- /dev/null
+++ b/lib/plugins/config/lang/ro/intro.txt
@@ -0,0 +1,7 @@
+====== Manager Configurare ======
+
+Folosiţi această pagină pentru a controla setările instalării DokuWiki. Pentru ajutor la probleme punctuale, consultaţi [[doku>config]]. Pentru mai multe detalii privind acest plugin, consultaţi [[doku>plugin:config]].
+
+Setările pe un fond roşu-deschis sunt protejate şi nu pot fi modificate cu acest plugin. Setările pe un fond albastru sunt valori implicite iar cele pe fond alb au fost setate local pentru această instalare individualizată. Setările pe fond albastru şi alb pot fi modificate.
+
+Nu uitaţi să apăsaţi butonul **SALVEAZĂ** înainte de a părăsi această pagină; altfel, modificările aduse se vor pierde.
diff --git a/lib/plugins/config/lang/ro/lang.php b/lib/plugins/config/lang/ro/lang.php
new file mode 100644
index 000000000..5845e3c35
--- /dev/null
+++ b/lib/plugins/config/lang/ro/lang.php
@@ -0,0 +1,193 @@
+<?php
+/**
+ * Romanian language file
+ *
+ * @author Sergiu Baltariu <s_baltariu@yahoo.com>
+ * @author s_baltariu@yahoo.com
+ * @author Emanuel-Emeric Andrasi <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrași <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andraşi <em.andrasi@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrasi <em.andrasi@mandrivausers.ro>
+ * @author Marius OLAR <olarmariusalex@gmail.com>
+ * @author Emanuel-Emeric Andrași <em.andrasi@mandrivausers.ro>
+ */
+$lang['menu'] = 'Setări de Configurare';
+$lang['error'] = 'Setări nu au fost actualizate datorită unei valori incorecte; verificaţi modificările şi încercaţi din nou. <br /> Valorile incorecte vor apărea într-un chenar roşu.';
+$lang['updated'] = 'Setările au fost actualizate cu succes.';
+$lang['nochoice'] = '(nici o altă opţiune nu este disponibilă)';
+$lang['locked'] = 'Fişierul de setări nu poate fi actualizat. Dacă nu s-a dorit aceasta, asiguraţi-vă că numele şi drepturile de acces ale fişierului de setări localizate sunt corecte.';
+$lang['danger'] = 'Pericol: Modificarea aceastei opțiuni poate conduce la imposibilitatea accesării wiki-ului și a meniului de configurare!';
+$lang['warning'] = 'Atenție: Modificarea aceastei opțiuni poate duce la evenimente nedorite!';
+$lang['security'] = 'Alertă de securitate: Modificarea acestei opțiuni poate prezenta un risc de securitate!';
+$lang['_configuration_manager'] = 'Manager Configurare';
+$lang['_header_dokuwiki'] = 'Setări DokuWiki';
+$lang['_header_plugin'] = 'Setări Plugin-uri';
+$lang['_header_template'] = 'Setări Şabloane';
+$lang['_header_undefined'] = 'Setări Nedefinite';
+$lang['_basic'] = 'Setări de Bază';
+$lang['_display'] = 'Setări Afişare';
+$lang['_authentication'] = 'Setări Autentificare';
+$lang['_anti_spam'] = 'Setări Anti-Spam';
+$lang['_editing'] = 'Setări Editare';
+$lang['_links'] = 'Setări Legături';
+$lang['_media'] = 'Setări Media';
+$lang['_advanced'] = 'Setări Avansate';
+$lang['_network'] = 'Setări Reţea';
+$lang['_plugin_sufix'] = 'Setări Plugin-uri';
+$lang['_template_sufix'] = 'Setări Şabloane';
+$lang['_msg_setting_undefined'] = 'Nesetat metadata';
+$lang['_msg_setting_no_class'] = 'Nesetat class';
+$lang['_msg_setting_no_default'] = 'Nici o valoare implicită';
+$lang['fmode'] = 'Mod creare fişier';
+$lang['dmode'] = 'Mod creare director';
+$lang['lang'] = 'Limbă';
+$lang['basedir'] = 'Director bază';
+$lang['baseurl'] = 'URL bază ';
+$lang['savedir'] = 'Director pentru salvarea datelor';
+$lang['cookiedir'] = 'Cale Cookie. Lăsați gol pentru a utiliza baseurl.';
+$lang['start'] = 'Numele paginii de start';
+$lang['title'] = 'Titlul wiki';
+$lang['template'] = 'Şablon';
+$lang['license'] = 'Sub ce licenţă va fi publicat conţinutul?';
+$lang['fullpath'] = 'Arată calea completă a paginii în subsol';
+$lang['recent'] = 'Modificări recente';
+$lang['breadcrumbs'] = 'Numărul de "urme" lăsate';
+$lang['youarehere'] = 'Structura ierarhică a "urmelor" lăsate';
+$lang['typography'] = 'Fă înlocuiri topografice';
+$lang['htmlok'] = 'Permite intercalare cod HTML';
+$lang['phpok'] = 'Permite intercalare cod PHP';
+$lang['dformat'] = 'Format dată (vezi funcţia PHP <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Semnătura';
+$lang['toptoclevel'] = 'Primul nivel pentru cuprins';
+$lang['tocminheads'] = 'Numărul minim de titluri ce determină dacă se alcătuieşte Tabelul de Cuprins (TOC)';
+$lang['maxtoclevel'] = 'Nivelul maxim pentru cuprins';
+$lang['maxseclevel'] = 'Nivelul maxim de editare al secţiunii';
+$lang['camelcase'] = 'Foloseşte CamelCase pentru legături';
+$lang['deaccent'] = 'numedepagină curate';
+$lang['useheading'] = 'Foloseşte primul titlu pentru numele paginii';
+$lang['refcheck'] = 'Verificare referinţă media';
+$lang['refshow'] = 'Numărul de referinţe media de arătat';
+$lang['allowdebug'] = 'Permite depanarea <b>dezactivaţi dacă cu e necesar!</b>';
+$lang['mediarevisions'] = 'Activează revizii media?';
+$lang['usewordblock'] = 'Blochează spam-ul pe baza listei de cuvinte';
+$lang['indexdelay'] = 'Timpul de întârziere înainte de indexare (sec)';
+$lang['relnofollow'] = 'Folosiţi rel="nofollow" pentru legăturile externe';
+$lang['mailguard'] = 'Adrese de email acoperite';
+$lang['iexssprotect'] = 'Verifică fişierele încărcate pentru posibil cod periculos JavaScript sau HTML';
+$lang['showuseras'] = 'Ce se afişează la indicarea utilizatorului care a editat ultimul o pagină';
+$lang['useacl'] = 'Utilizează liste de control al accesului';
+$lang['autopasswd'] = 'Parole autogenerate';
+$lang['authtype'] = 'Autentificare backend';
+$lang['passcrypt'] = 'Metoda de criptare a parolei';
+$lang['defaultgroup'] = 'Grup implicit';
+$lang['superuser'] = 'Superuser - un grup sau un utilizator cu acces complet la toate paginile şi funcţiile indiferent de setările ACL';
+$lang['manager'] = 'Manager - un grup sau un utilizator cu acces la anumite funcţii de management';
+$lang['profileconfirm'] = 'Confirmă schimbarea profilului cu parola';
+$lang['disableactions'] = 'Dezactivează acţiunile DokuWiki';
+$lang['disableactions_check'] = 'Verifică';
+$lang['disableactions_subscription'] = 'Subscrie/Anulează subscrierea';
+$lang['disableactions_wikicode'] = 'Vizualizează sursa/Export Raw';
+$lang['disableactions_other'] = 'Alte acţiuni (separate prin virgulă)';
+$lang['sneaky_index'] = 'Implicit, DokuWiki va arăta toate numele de spaţii la vizualizarea indexului. Activând această opţiune vor fi ascunse acelea la care utilizatorul nu are drepturi de citire. Aceasta poate determina ascunderea sub-numelor de spaţii accesibile. Aceasta poate face index-ul inutilizabil cu anumite setări ale ACL';
+$lang['auth_security_timeout'] = 'Timpul de expirare al Autentificării Securizate (secunde)';
+$lang['securecookie'] = 'Cookies-urile setate via HTTPS să fie trimise doar via HTTPS de către browser? Dezactivaţi această opţiune numai când login-ul wiki-ului este securizat cu SSL dar navigarea wiki-ului se realizează nesecurizat.';
+$lang['xmlrpc'] = 'Activează/dezactivează interfaţa XML-RPC';
+$lang['xmlrpcuser'] = 'Restricţionaţi accesul XML-RPC la grupurile sau utilizatorii separaţi prin virgulă daţi aici. Lasaţi gol pentru a da acces tuturor.';
+$lang['updatecheck'] = 'Verificare actualizări şi avertismente privind securitatea? DokuWiki trebuie să contacteze update.dokuwiki.org pentru această facilitate.';
+$lang['userewrite'] = 'Folosire URL-uri "nice"';
+$lang['useslash'] = 'Foloseşte slash-ul ca separator de spaţii de nume în URL-uri';
+$lang['usedraft'] = 'Salvează automat o schiţă în timpul editării';
+$lang['sepchar'] = 'Separator cuvinte în numele paginii';
+$lang['canonical'] = 'Foloseşte URL-uri canonice';
+$lang['fnencode'] = 'Metoda de encodare a numelor fişierelor non-ASCII.';
+$lang['autoplural'] = 'Verifică formele de plural în legături';
+$lang['compression'] = 'Metoda de criptare a fişierelor pod';
+$lang['cachetime'] = 'Durata maximă pentru cache (secunde)';
+$lang['locktime'] = 'Durata maximă pentru blocarea fişierelor (secunde)';
+$lang['fetchsize'] = 'Dimensiunea maximă (byte) pe care fetch.php poate să descarce din exterior';
+$lang['notify'] = 'Trimite notificări privind modificările pe această adresă de email';
+$lang['registernotify'] = 'Trimite informare noilor utilizatori înregistraţi pe această adresă de email';
+$lang['mailfrom'] = 'Adresa de email utilizată pentru mailuri automate';
+$lang['mailprefix'] = 'Prefix subiect e-mail de folosit pentru mail-uri automate';
+$lang['gzip_output'] = 'Foloseşte gzip pentru codarea conţinutului xhtml';
+$lang['gdlib'] = 'Versiunea GD Lib';
+$lang['im_convert'] = 'Calea către instrumentul de conversie ImageMagick';
+$lang['jpg_quality'] = 'Calitatea compresiei JPG (0-100)';
+$lang['subscribers'] = 'Activează suportul pentru subscrierea paginii';
+$lang['subscribe_time'] = 'Timpul după care lista de abonare şi digestie sunt trimise (sec); Aceasta ar trebui să fie mai mic decât timpul specificat în recent_days.';
+$lang['compress'] = 'Compactează codul CSS şi javascript produs';
+$lang['cssdatauri'] = 'Dimensiunea în octeți până la care imaginile regasite în fișierele CSS ar trebui să fie incluse direct în stylesheet pentru a reduce supraîncărcarea antetului cererii HTTP. Această tehnică nu va funcționa în IE < 8! <code>400</code> până la <code>600</code> octeți sunt suficienți. Introduceți <code>0</code> pentru a dezactiva această opțiune.';
+$lang['hidepages'] = 'Ascunde paginile pereche (expresii regulate)';
+$lang['send404'] = 'Trimite mesajul "HTTP 404/Page Not Found" pentru paginile inexistente';
+$lang['sitemap'] = 'Generează Google sitemap (zile)';
+$lang['broken_iua'] = 'Funcţia ignore_user_abort nu funcţionează pe sistemul dumneavoastră? Aceasta poate determina nefuncţionarea indexului de căutare. IIS+PHP/CGI sunt cunoscute ca fiind nefuncţionale. Mai multe detalii găsiţi la <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>';
+$lang['xsendfile'] = 'Folosiţi header-ul X-Send pentru a-i permite serverului web să trimită fişiere statice? Serverul web trebuie să permită aceasta.';
+$lang['renderer_xhtml'] = 'Motorul de randare principal folosit pentru afişarea wiki în format xhtml';
+$lang['renderer__core'] = '%s (nucleu dokuwiki)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Permiteţi cookies permanente la login (ţine-mă minte)';
+$lang['rss_type'] = 'Tip flux XML';
+$lang['rss_linkto'] = 'Fluxul XML se leagă la';
+$lang['rss_content'] = 'Ce să afişez în obiectele fluxurilor XML';
+$lang['rss_update'] = 'Intervalul de actualizare a fluxului XML (sec)';
+$lang['recent_days'] = 'Câte modificări recente să se păstreze?';
+$lang['rss_show_summary'] = 'Fluxul XML arată rezumat în titlu';
+$lang['target____wiki'] = 'Fereastra ţintă pentru legăturile interne';
+$lang['target____interwiki'] = 'Fereastra ţintă pentru legăturile interwiki';
+$lang['target____extern'] = 'Fereastra ţintă pentru legăturile externe';
+$lang['target____media'] = 'Fereastra ţintă pentru legăturile media';
+$lang['target____windows'] = 'Fereastra ţintă pentru legăturile windows';
+$lang['proxy____host'] = 'Nume server Proxy';
+$lang['proxy____port'] = 'Port Proxy';
+$lang['proxy____user'] = 'Nume utilizator Proxy';
+$lang['proxy____pass'] = 'Parolă Proxy';
+$lang['proxy____ssl'] = 'Foloseşte SSL pentru conectare la Proxy';
+$lang['proxy____except'] = 'Expresie regulară de potrivit cu URL-uri pentru care proxy-ul trebuie păsuit.';
+$lang['safemodehack'] = 'Activează safemode hack';
+$lang['ftp____host'] = 'Server FTP pentru safemode hack';
+$lang['ftp____port'] = 'Port FTP pentru safemode hack';
+$lang['ftp____user'] = 'Nume utilizator pentru safemode hack';
+$lang['ftp____pass'] = 'Parolă FTP pentru safemode hack';
+$lang['ftp____root'] = 'Director rădăcină FTP pentru safemode hack';
+$lang['license_o_'] = 'Nici una aleasă';
+$lang['typography_o_0'] = 'nimic';
+$lang['typography_o_1'] = 'Numai ghilimele duble';
+$lang['typography_o_2'] = 'Toate ghilimelele (s-ar putea să nu fucţioneze întotdeauna)';
+$lang['userewrite_o_0'] = 'nimic';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki intern';
+$lang['deaccent_o_0'] = 'închis';
+$lang['deaccent_o_1'] = 'înlătură accentele';
+$lang['deaccent_o_2'] = 'romanizează';
+$lang['gdlib_o_0'] = 'biblioteca GD Lib nu este disponibilă';
+$lang['gdlib_o_1'] = 'Versiunea 1.x';
+$lang['gdlib_o_2'] = 'Detectare automată';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Abstract';
+$lang['rss_content_o_diff'] = 'Diferenţe unificate';
+$lang['rss_content_o_htmldiff'] = 'Tabel diferenţe în format HTML';
+$lang['rss_content_o_html'] = 'Conţinut pagină complet HTML';
+$lang['rss_linkto_o_diff'] = 'vizualizare diferenţe';
+$lang['rss_linkto_o_page'] = 'pagina revizuită';
+$lang['rss_linkto_o_rev'] = 'lista revizuirilor';
+$lang['rss_linkto_o_current'] = 'pagina curentă';
+$lang['compression_o_0'] = 'nici una';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nu se foloseşte';
+$lang['xsendfile_o_1'] = 'Header proprietar lighttpd (înaintea versiunii 1.5)';
+$lang['xsendfile_o_2'] = 'Header standard X-Sendfile';
+$lang['xsendfile_o_3'] = 'Header proprietar Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Numele de login';
+$lang['showuseras_o_username'] = 'Numele complet al utilizatorului';
+$lang['showuseras_o_email'] = 'Adresa de e-mail a utilizatorului (mascată conform setărilor de protecţie)';
+$lang['showuseras_o_email_link'] = 'Adresa de e-mail a utilizatorului ca mailto: link';
+$lang['useheading_o_0'] = 'Niciodată';
+$lang['useheading_o_navigation'] = 'Doar navigare';
+$lang['useheading_o_content'] = 'Doar conţinutul Wiki';
+$lang['useheading_o_1'] = 'Întotdeauna';
+$lang['readdircache'] = 'Vârsta maximă depozitare readdir (sec)';
diff --git a/lib/plugins/config/lang/ru/intro.txt b/lib/plugins/config/lang/ru/intro.txt
new file mode 100644
index 000000000..a629d9332
--- /dev/null
+++ b/lib/plugins/config/lang/ru/intro.txt
@@ -0,0 +1,9 @@
+====== Настройки вики ======
+
+Здесь вы можете изменить настройки своей «ДокуВики». Для справки по поводу конкретных опций смотрите [[doku>config]]. Дополнительные детали об этом плагине доступны здесь: [[doku>plugin:config]].
+
+Настройки, отображаемые на светло-красном фоне, защищены от изменений и не могут быть отредактированы с помощью этого плагина. Голубым фоном отмечены настройки со значениями по умолчанию, а белым фоном — настройки, которые были локально изменены для этой конкретной «ДокуВики». Как голубые, так и белые настройки доступны для изменения.
+
+Не забудьте нажать кнопку «**Сохранить**» перед тем, как покинуть эту страницу, иначе все ваши изменения будут потеряны.
+
+
diff --git a/lib/plugins/config/lang/ru/lang.php b/lib/plugins/config/lang/ru/lang.php
new file mode 100644
index 000000000..f29257a28
--- /dev/null
+++ b/lib/plugins/config/lang/ru/lang.php
@@ -0,0 +1,196 @@
+<?php
+/**
+ * Russian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Denis Simakov <akinoame1@gmail.com>
+ * @author Andrew Pleshakov <beotiger@mail.ru>
+ * @author Змей Этерийский evil_snake@eternion.ru
+ * @author Hikaru Nakajima <jisatsu@mail.ru>
+ * @author Alexei Tereschenko <alexeitlex@yahoo.com>
+ * @author Irina Ponomareva irinaponomareva@webperfectionist.com
+ * @author Alexander Sorkin <kibizoid@gmail.com>
+ * @author Kirill Krasnov <krasnovforum@gmail.com>
+ * @author Vlad Tsybenko <vlad.development@gmail.com>
+ * @author Aleksey Osadchiy <rfc@nm.ru>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Ladyko Andrey <fylh@succexy.spb.ru>
+ * @author Eugene <windy.wanderer@gmail.com>
+ */
+$lang['menu'] = 'Настройки вики';
+$lang['error'] = 'Настройки не были сохранены из-за ошибки в одном из значений. Пожалуйста, проверьте свои изменения и попробуйте ещё раз.<br />Неправильные значения будут обведены красной рамкой.';
+$lang['updated'] = 'Настройки успешно сохранены.';
+$lang['nochoice'] = '(нет других вариантов)';
+$lang['locked'] = 'Файл настройки недоступен для изменения. Если это не специально, <br />убедитесь, что файл локальной настройки имеет правильное имя и права доступа.';
+$lang['danger'] = 'Внимание: изменение этой опции может сделать вашу вики и меню конфигурации недоступными.';
+$lang['warning'] = 'Предостережение: изменение этой опции может вызвать непредсказуемое поведение.';
+$lang['security'] = 'Предостережение по безопасности: изменение этой опции может вызвать риск, связанный с безопасностью.';
+$lang['_configuration_manager'] = 'Настройки вики';
+$lang['_header_dokuwiki'] = 'Параметры «ДокуВики»';
+$lang['_header_plugin'] = 'Параметры плагинов';
+$lang['_header_template'] = 'Параметры шаблонов';
+$lang['_header_undefined'] = 'Прочие параметры';
+$lang['_basic'] = 'Основные параметры';
+$lang['_display'] = 'Параметры отображения';
+$lang['_authentication'] = 'Параметры аутентификации';
+$lang['_anti_spam'] = 'Параметры блокировки спама';
+$lang['_editing'] = 'Параметры правки';
+$lang['_links'] = 'Параметры ссылок';
+$lang['_media'] = 'Параметры медиафайлов';
+$lang['_advanced'] = 'Тонкая настройка';
+$lang['_network'] = 'Параметры сети';
+$lang['_plugin_sufix'] = 'Параметры плагина';
+$lang['_template_sufix'] = 'Параметры шаблона';
+$lang['_msg_setting_undefined'] = 'Не найдены метаданные настроек.';
+$lang['_msg_setting_no_class'] = 'Не найден класс настроек.';
+$lang['_msg_setting_no_default'] = 'Не задано значение по умолчанию.';
+$lang['fmode'] = 'Права для создаваемых файлов';
+$lang['dmode'] = 'Права для создаваемых директорий';
+$lang['lang'] = 'Язык';
+$lang['basedir'] = 'Корневая директория (например, <code>/dokuwiki/</code>). Оставьте пустым для автоопределения.';
+$lang['baseurl'] = 'Корневой адрес (URL) (например, <code>http://www.yourserver.ru</code>). Оставьте пустым для автоопределения.';
+$lang['savedir'] = 'Директория для данных';
+$lang['start'] = 'Имя стартовой страницы';
+$lang['title'] = 'Название вики';
+$lang['template'] = 'Шаблон';
+$lang['license'] = 'На условиях какой лицензии будет предоставляться содержимое вики?';
+$lang['fullpath'] = 'Полный путь к документу';
+$lang['recent'] = 'Недавние изменения (кол-во)';
+$lang['breadcrumbs'] = 'Вы посетили (кол-во)';
+$lang['youarehere'] = 'Показывать «Вы находитесь здесь»';
+$lang['typography'] = 'Типографские символы';
+$lang['htmlok'] = 'Разрешить HTML';
+$lang['phpok'] = 'Разрешить PHP';
+$lang['dformat'] = 'Формат даты и времени';
+$lang['signature'] = 'Шаблон подписи';
+$lang['toptoclevel'] = 'Мин. уровень в содержании';
+$lang['tocminheads'] = 'Мин. количество заголовков, при котором будет составлено содержание';
+$lang['maxtoclevel'] = 'Макс. уровень в содержании';
+$lang['maxseclevel'] = 'Макс. уровень для правки';
+$lang['camelcase'] = 'Использовать ВикиРегистр для ссылок';
+$lang['deaccent'] = 'Транслитерация в именах страниц';
+$lang['useheading'] = 'Первый заголовок вместо имени';
+$lang['refcheck'] = 'Проверять ссылки на медиафайлы';
+$lang['refshow'] = 'Показывать ссылок на медиафайлы';
+$lang['allowdebug'] = 'Включить отладку (отключите!)';
+$lang['usewordblock'] = 'Блокировать спам по ключевым словам';
+$lang['indexdelay'] = 'Задержка перед индексированием';
+$lang['relnofollow'] = 'rel="nofollow" для внешних ссылок';
+$lang['mailguard'] = 'Кодировать адреса электронной почты';
+$lang['iexssprotect'] = 'Проверять закачанные файлы на наличие потенциально опасного кода JavaScript или HTML';
+$lang['showuseras'] = 'Что отображать при показе пользователя, редактировавшего страницу последним';
+$lang['useacl'] = 'Использовать списки прав доступа';
+$lang['autopasswd'] = 'Автогенерация паролей';
+$lang['authtype'] = 'Механизм аутентификации';
+$lang['passcrypt'] = 'Метод шифрования пароля';
+$lang['defaultgroup'] = 'Группа по умолчанию';
+$lang['superuser'] = 'Суперпользователь — группа или пользователь с полным доступом ко всем страницам и функциям администрирования, независимо от установок ACL. Перечень разделяйте запятыми: user1,@group1,user2';
+$lang['manager'] = 'Менеджер — группа или пользователь с доступом к определённым функциям управления. Перечень разделяйте запятыми: user1,@group1,user2';
+$lang['profileconfirm'] = 'Пароль для изменения профиля';
+$lang['disableactions'] = 'Заблокировать операции «ДокуВики»';
+$lang['disableactions_check'] = 'Проверка';
+$lang['disableactions_subscription'] = 'Подписка/Отмена подписки';
+$lang['disableactions_wikicode'] = 'Показ/экспорт исходного текста';
+$lang['disableactions_other'] = 'Другие операции (через запятую)';
+$lang['sneaky_index'] = 'По умолчанию, «ДокуВики» показывает в индексе страниц все пространства имён. Включение этой опции скроет пространства имён, для которых пользователь не имеет прав чтения. Это может привести к скрытию доступных вложенных пространств имён и потере функциональности индекса страниц при некоторых конфигурациях прав доступа.';
+$lang['auth_security_timeout'] = 'Интервал для безопасности авторизации (сек.)';
+$lang['securecookie'] = 'Должны ли куки (cookies), выставленные через HTTPS, отправляться браузером только через HTTPS. Отключите эту опцию в случае, когда только логин вашей вики передаётся через SSL, а обычный просмотр осуществляется в небезопасном режиме.';
+$lang['xmlrpc'] = 'Включить/выключить XML-RPC интерфейс.';
+$lang['xmlrpcuser'] = 'Запретить XML-RPC-доступ для списка групп и пользователей, перечисленных через запятую. Оставьте пустым, если хотите оставить доступ всем.';
+$lang['updatecheck'] = 'Проверять наличие обновлений и предупреждений о безопасности? Для этого «ДокуВики» потребуется связываться с сайтом <a href="http://www.splitbrain.org/">splitbrain.org</a>.';
+$lang['userewrite'] = 'Удобочитаемые адреса (URL)';
+$lang['useslash'] = 'Использовать слэш';
+$lang['usedraft'] = 'Автоматически сохранять черновик во время правки';
+$lang['sepchar'] = 'Разделитель слов в имени страницы';
+$lang['canonical'] = 'Полные канонические адреса (URL)';
+$lang['fnencode'] = 'Метод кодирования имён файлов, записанных не ASCII-символами.';
+$lang['autoplural'] = 'Автоматическое мн. число';
+$lang['compression'] = 'Метод сжатия для архивных файлов';
+$lang['cachetime'] = 'Время жизни кэш-файла (сек.)';
+$lang['locktime'] = 'Время блокировки страницы (сек.)';
+$lang['fetchsize'] = 'Максимальный размер файла (в байтах), который fetch.php может скачивать с внешнего источника';
+$lang['notify'] = 'Электронный адрес для извещений';
+$lang['registernotify'] = 'Посылать информацию о новых зарегистрированных пользователях на этот электронный адрес';
+$lang['mailfrom'] = 'Электронный адрес вики (От:)';
+$lang['mailprefix'] = 'Префикс используемый для автоматического письма станет темой сообщений';
+$lang['gzip_output'] = 'Использовать gzip-сжатие для xhtml';
+$lang['gdlib'] = 'Версия LibGD';
+$lang['im_convert'] = 'Путь к ImageMagick';
+$lang['jpg_quality'] = 'Качество сжатия JPG (0–100). Значение по умолчанию — 70.';
+$lang['subscribers'] = 'Разрешить подписку на изменения';
+$lang['subscribe_time'] = 'Интервал рассылки подписок и сводок (сек.). Должен быть меньше, чем значение, указанное в recent_days.';
+$lang['compress'] = 'Сжимать файлы CSS и javascript';
+$lang['hidepages'] = 'Скрыть страницы (рег. выражение)';
+$lang['send404'] = 'Посылать «HTTP404/Page Not Found»';
+$lang['sitemap'] = 'Число дней, через которое нужно создавать (обновлять) карту сайта для поисковиков (Гугл, Яндекс и др.)';
+$lang['broken_iua'] = 'Возможно, функция ignore_user_abort не работает в вашей системе? Это может привести к потере функциональности индексирования поиска. Эта проблема присутствует, например, в IIS+PHP/CGI. Для дополнительной информации смотрите <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">баг 852</a>.';
+$lang['xsendfile'] = 'Используете заголовок X-Sendfile для загрузки файлов на веб-сервер? Ваш веб-сервер должен поддерживать это.';
+$lang['renderer_xhtml'] = 'Обработчик основного (xhtml) вывода вики';
+$lang['renderer__core'] = '%s (ядро dokuwiki)';
+$lang['renderer__plugin'] = '%s (плагин)';
+$lang['rememberme'] = 'Разрешить перманентные куки (cookies) для входа («запомнить меня»)';
+$lang['rss_type'] = 'Тип RSS';
+$lang['rss_linkto'] = 'Ссылки в RSS';
+$lang['rss_content'] = 'Что отображать в строках XML-ленты?';
+$lang['rss_update'] = 'Интервал обновления XML-ленты (сек.)';
+$lang['recent_days'] = 'На сколько дней назад сохранять недавние изменения';
+$lang['rss_show_summary'] = 'Показывать краткую выдержку в заголовках XML-ленты';
+$lang['target____wiki'] = 'target для внутренних ссылок';
+$lang['target____interwiki'] = 'target для ссылок между вики';
+$lang['target____extern'] = 'target для внешних ссылок';
+$lang['target____media'] = 'target для ссылок на медиафайлы';
+$lang['target____windows'] = 'target для ссылок на сетевые каталоги';
+$lang['proxy____host'] = 'proxy-адрес';
+$lang['proxy____port'] = 'proxy-порт';
+$lang['proxy____user'] = 'proxy-имя пользователя';
+$lang['proxy____pass'] = 'proxy-пароль';
+$lang['proxy____ssl'] = 'proxy-ssl';
+$lang['proxy____except'] = 'Регулярное выражение для адресов (URL), для которых прокси должен быть пропущен.';
+$lang['safemodehack'] = 'Включить обход safemode (хак)';
+$lang['ftp____host'] = 'ftp-адрес';
+$lang['ftp____port'] = 'ftp-порт';
+$lang['ftp____user'] = 'ftp-имя пользователя';
+$lang['ftp____pass'] = 'ftp-пароль';
+$lang['ftp____root'] = 'ftp-корневая директория';
+$lang['license_o_'] = 'Не выбрано';
+$lang['typography_o_0'] = 'нет';
+$lang['typography_o_1'] = 'Только двойные кавычки';
+$lang['typography_o_2'] = 'Все кавычки (может не всегда работать)';
+$lang['userewrite_o_0'] = '(нет)';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'средствами «ДокуВики»';
+$lang['deaccent_o_0'] = 'отключить';
+$lang['deaccent_o_1'] = 'убирать только диакр. знаки';
+$lang['deaccent_o_2'] = 'полная транслитерация';
+$lang['gdlib_o_0'] = 'LibGD недоступна';
+$lang['gdlib_o_1'] = 'версия 1.x';
+$lang['gdlib_o_2'] = 'автоопределение';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Абстрактный';
+$lang['rss_content_o_diff'] = 'Объединённый diff';
+$lang['rss_content_o_htmldiff'] = 'HTML-форматированная таблица diff';
+$lang['rss_content_o_html'] = 'Полное содержимое HTML-страницы';
+$lang['rss_linkto_o_diff'] = 'отличия от текущей';
+$lang['rss_linkto_o_page'] = 'текст страницы';
+$lang['rss_linkto_o_rev'] = 'история правок';
+$lang['rss_linkto_o_current'] = 'текущая версия';
+$lang['compression_o_0'] = 'без сжатия';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'не используется';
+$lang['xsendfile_o_1'] = 'Проприетарный lighttpd-заголовок (перед релизом 1.5)';
+$lang['xsendfile_o_2'] = 'Стандартный заголовок X-Sendfile';
+$lang['xsendfile_o_3'] = 'Проприетарный заголовок Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Логин';
+$lang['showuseras_o_username'] = 'Полное имя пользователя';
+$lang['showuseras_o_email'] = 'Адрес электропочты в шифрованном виде (см. mailguard)';
+$lang['showuseras_o_email_link'] = 'Адрес электропочты в виде ссылки mailto:';
+$lang['useheading_o_0'] = 'Никогда';
+$lang['useheading_o_navigation'] = 'Только навигация';
+$lang['useheading_o_content'] = 'Только содержимое вики';
+$lang['useheading_o_1'] = 'Всегда';
+$lang['readdircache'] = 'Максимальное время жизни кэша readdir (сек.)';
diff --git a/lib/plugins/config/lang/sk/intro.txt b/lib/plugins/config/lang/sk/intro.txt
new file mode 100644
index 000000000..5de62a315
--- /dev/null
+++ b/lib/plugins/config/lang/sk/intro.txt
@@ -0,0 +1,7 @@
+====== Správa konfigurácie ======
+
+Túto stránku môžete používať na zmenu nastavení Vašej DokuWiki inštalácie. Popis jednotlivých nastavení je uvedený v [[doku>config]]. Viac detailov o tomto plugine nájdete v [[doku>plugin:config]].
+
+Nastavenia zobrazené na červenom pozadí sú neprístupné a nemôžu byť týmto pluginom zmenené. Nastavenia s modrým pozadím obsahujú prednastavené hodnoty a nastavenia s bielym pozadím boli nastavené lokálne pre túto konkrétnu inštaláciu. Nastavenia s modrým a bielym pozadím môžu byť zmenené.
+
+Nezabudnite stlačiť tlačidlo **Uložiť** pred opustením stránky, inak budú vaše zmeny stratené. \ No newline at end of file
diff --git a/lib/plugins/config/lang/sk/lang.php b/lib/plugins/config/lang/sk/lang.php
new file mode 100644
index 000000000..9f55248a3
--- /dev/null
+++ b/lib/plugins/config/lang/sk/lang.php
@@ -0,0 +1,189 @@
+<?php
+/**
+ * Slovaklanguage file
+ *
+ * @author Michal Mesko <michal.mesko@gmail.com>
+ * @author exusik@gmail.com
+ * @author Martin Michalek <michalek.dev@gmail.com>
+ */
+$lang['menu'] = 'Nastavenia konfigurácie';
+$lang['error'] = 'Nastavenia neboli aktualizované kvôli neplatnej hodnote, prosím skontrolujte vaše zmeny a znovu ich pošlite. <br />Nesprávna hodnota(y) bude ohraničená červeným okrajom.';
+$lang['updated'] = 'Nastavenia úspešne aktualizované.';
+$lang['nochoice'] = '(žiadne ďalšie dostupné voľby)';
+$lang['locked'] = 'Súbor s nastaveniami nemôže byť aktualizovaný, ak toto nie je zámerom, <br />
+uistite sa, že názov a práva lokálneho súboru sú správne.';
+$lang['danger'] = 'Nebezpečie: Zmeny tohto nastavenia môžu spôsobiť nedostupnosť wiki a nastavovacieho menu.';
+$lang['warning'] = 'Varovanie: Zmena tohto nastavenia môže viesť neželanému správaniu.';
+$lang['security'] = 'Bezpečnostné riziko: Zmenou tohto nastavenie môže vzniknúť bezpečnostné riziko.';
+$lang['_configuration_manager'] = 'Správa konfigurácie';
+$lang['_header_dokuwiki'] = 'Nastavenia DokuWiki';
+$lang['_header_plugin'] = 'Nastavenia plug-inov';
+$lang['_header_template'] = 'Nastavenia šablóny';
+$lang['_header_undefined'] = 'Nešpecifikované nastavenia';
+$lang['_basic'] = 'Základné nastavenia';
+$lang['_display'] = 'Nastavenia zobrazovania';
+$lang['_authentication'] = 'Nastavenia zabezpečenia';
+$lang['_anti_spam'] = 'Nastavenia anti-spamu';
+$lang['_editing'] = 'Nastavenia úprav';
+$lang['_links'] = 'Nastavenia odkazov';
+$lang['_media'] = 'Nastavenia médií';
+$lang['_advanced'] = 'Rozšírené nastavenia';
+$lang['_network'] = 'Nastavenia siete';
+$lang['_plugin_sufix'] = 'Nastavenia plug-inu';
+$lang['_template_sufix'] = 'Nastavenia šablóny';
+$lang['_msg_setting_undefined'] = 'Nenastavené metadata.';
+$lang['_msg_setting_no_class'] = 'Nenastavená trieda.';
+$lang['_msg_setting_no_default'] = 'Žiadna predvolená hodnota.';
+$lang['fmode'] = 'Spôsob vytvárania súborov';
+$lang['dmode'] = 'Spôsob vytvárania adresárov';
+$lang['lang'] = 'Jazyk';
+$lang['basedir'] = 'Hlavný adresár (napr. <code>/dokuwiki/</code>). Prázdna hodnota znamená použitie autodetekcie.';
+$lang['baseurl'] = 'Adresa servera (napr. <code>http://www.yourserver.com</code>). Prázdna hodnota znamená použitie autodetekcie.';
+$lang['savedir'] = 'Adresár pre ukladanie dát';
+$lang['cookiedir'] = 'Cesta k cookies. Prázdna hodnota znamená použitie adresy servera.';
+$lang['start'] = 'Názov štartovacej stránky';
+$lang['title'] = 'Názov wiki';
+$lang['template'] = 'Šablóna';
+$lang['license'] = 'Pod ktorou licenciou bude publikovaný obsah stránky?';
+$lang['fullpath'] = 'Zobrazovať plnú cestu k stránkam v pätičke';
+$lang['recent'] = 'Posledné zmeny';
+$lang['breadcrumbs'] = 'Počet záznamov histórie';
+$lang['youarehere'] = 'Nachádzate sa';
+$lang['typography'] = 'Vykonať typografické zmeny';
+$lang['htmlok'] = 'Umožniť vkladanie HTML';
+$lang['phpok'] = 'Umožniť vkladanie PHP';
+$lang['dformat'] = 'Formát dátumu (pozri funkciu PHP <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Podpis';
+$lang['toptoclevel'] = 'Najvyššia úroveň pre generovanie obsahu.';
+$lang['tocminheads'] = 'Minimálny počet nadpisov pre generovanie obsahu';
+$lang['maxtoclevel'] = 'Maximálna úroveň pre generovanie obsahu.';
+$lang['maxseclevel'] = 'Maximálna úroveň sekcie pre editáciu';
+$lang['camelcase'] = 'Použiť CamelCase pre odkazy';
+$lang['deaccent'] = 'Upraviť názvy stránok';
+$lang['useheading'] = 'Použiť nadpis pre názov stránky';
+$lang['refcheck'] = 'Kontrolovať odkazy na médiá (pred vymazaním)';
+$lang['refshow'] = 'Počet zobrazených odkazov na médiá';
+$lang['allowdebug'] = 'Povoliť ladenie chýb <b>deaktivujte, ak nie je potrebné!</b>';
+$lang['mediarevisions'] = 'Povoliť verzie súborov?';
+$lang['usewordblock'] = 'Blokovať spam na základe zoznamu známych slov';
+$lang['indexdelay'] = 'Časové oneskorenie pred indexovaním (sek)';
+$lang['relnofollow'] = 'Používať rel="nofollow" pre externé odkazy';
+$lang['mailguard'] = 'Zamaskovať e-mailovú adresu';
+$lang['iexssprotect'] = 'Kontrolovať nahraté súbory na prítomnosť nebezpečného JavaScript alebo HTML kódu';
+$lang['showuseras'] = 'Čo použiť pri zobrazení používateľa, ktorý posledný upravoval stránku';
+$lang['useacl'] = 'Použiť kontrolu prístupu (ACL)';
+$lang['autopasswd'] = 'Autogenerovanie hesla';
+$lang['authtype'] = 'Systém autentifikácie (back-end)';
+$lang['passcrypt'] = 'Spôsob šifrovania hesiel';
+$lang['defaultgroup'] = 'Predvolená skupina';
+$lang['superuser'] = 'Správca - skupina, používateľ alebo čiarkou oddelený zoznam "pouzivatel1,@skupina1,pouzivatel2" s plným prístupom ku všetkým stránkam a funkciám nezávisle od ACL nastavení';
+$lang['manager'] = 'Manažér - skupina, používateľ alebo čiarkou oddelený zoznam "pouzivatel1,@skupina1,pouzivatel2" s prístupom k vybraným správcovským funkciám';
+$lang['profileconfirm'] = 'Potvrdzovať zmeny profilu heslom';
+$lang['disableactions'] = 'Zakázať DokuWiki akcie';
+$lang['disableactions_check'] = 'Skontrolovať';
+$lang['disableactions_subscription'] = 'Povoliť/Zrušiť informovanie o zmenách stránky';
+$lang['disableactions_wikicode'] = 'Pozrieť zdroj/Exportovať zdroj';
+$lang['disableactions_other'] = 'Iné akcie (oddelené čiarkou)';
+$lang['sneaky_index'] = 'DokuWiki implicitne ukazuje v indexe všetky menné priestory. Povolením tejto voľby sa nezobrazia menné priestory, ku ktorým nemá používateľ právo na čítanie. Dôsledkom môže byť nezobrazenie vnorených prístupných menných priestorov. Táto voľba môže mať za následok nepoužiteľnosť indexu s určitými ACL nastaveniami.';
+$lang['auth_security_timeout'] = 'Časový limit pri prihlasovaní (v sekundách)';
+$lang['securecookie'] = 'Mal by prehliadač posielať cookies nastavené cez HTTPS posielať iba cez HTTPS (bezpečné) pripojenie? Vypnite túto voľbu iba v prípade, ak je prihlasovanie do Vašej wiki zabezpečené SSL, ale prezeranie wiki je nezabezpečené.';
+$lang['xmlrpc'] = 'Povoliť/zakázať XML-RPC rozhranie.';
+$lang['xmlrpcuser'] = 'Obmedziť XML-RPC prístup iba pre uvedené skupiny alebo používateľov (oddelených čiarkami).';
+$lang['updatecheck'] = 'Kontrolovať aktualizácie a bezpečnostné upozornenia? DokuWiki potrebuje pre túto funkciu prístup k update.dokuwiki.org.';
+$lang['userewrite'] = 'Používať nice URLs';
+$lang['useslash'] = 'Používať lomku (/) ako oddeľovač v URL';
+$lang['usedraft'] = 'Automaticky ukladať koncept počas úpravy stránky';
+$lang['sepchar'] = 'Oddeľovač slov v názvoch stránok';
+$lang['canonical'] = 'Používať plne kanonické URL názvy';
+$lang['fnencode'] = 'Spôsob kódovania non-ASCII mien súborov.';
+$lang['autoplural'] = 'Kontrolovať množné číslo v odkazoch';
+$lang['compression'] = 'Metóda kompresie pre staré verzie stránok';
+$lang['cachetime'] = 'Maximálne trvanie cache (sek)';
+$lang['locktime'] = 'Maximálne trvanie blokovacích súborov (sek)';
+$lang['fetchsize'] = 'Maximálna veľkosť (v bajtoch) pri sťahovaní z externých zdrojov';
+$lang['notify'] = 'Posielať upozornenia na zmeny na túto e-mailovú adresu';
+$lang['registernotify'] = 'Posielať informáciu o nových užívateľoch na túto e-mailovú adresu';
+$lang['mailfrom'] = 'E-mailová adresa na automatické e-maily';
+$lang['mailprefix'] = 'Prefix predmetu emailovej spravy zasielanej automaticky';
+$lang['gzip_output'] = 'Používať gzip Content-Encoding pre xhtml';
+$lang['gdlib'] = 'Verzia GD Lib';
+$lang['im_convert'] = 'Cesta k ImageMagick convert tool';
+$lang['jpg_quality'] = 'Kvalita JPG kompresie (0-100)';
+$lang['subscribers'] = 'Povoliť podporu informovania o zmenách stránky';
+$lang['subscribe_time'] = 'Časový inteval, po uplynutí ktorého sú zasielané informácie o zmenách stránky alebo menného priestoru (sek); hodnota by mala byť menšia ako čas zadaný pri položke recent_days.';
+$lang['compress'] = 'Komprimovať CSS a javascript výstup';
+$lang['cssdatauri'] = 'Veľkosť v bytoch, do ktorej by mali byť obrázky s odkazom v CSS vložené priamo do štýlu z dôvodu obmedzenia HTTP požiadaviek. Tento postup nefunguje v IE verzie 7 a nižšie! Vhodná hodnota je od <code>400</code> do <code>600</code> bytov. Hodnota <code>0</code> deaktivuje túto metódu.';
+$lang['hidepages'] = 'Skryť zodpovedajúce stránky (regulárne výrazy)';
+$lang['send404'] = 'Poslať "HTTP 404/Page Not Found" pre neexistujúce stránky';
+$lang['sitemap'] = 'Generovať Google sitemap (dni)';
+$lang['broken_iua'] = 'Je vo Vašom systéme funkcia ignore_user_abort poškodená? Môže to mať za následok nefunkčnosť vyhľadávania v indexe. IIS+PHP/CGI je známy tým, že nefunguje správne. Pozrite <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> pre dalšie informácie.';
+$lang['xsendfile'] = 'Používať X-Sendfile hlavičku pre doručenie statických súborov webserverom? Webserver musí túto funkcionalitu podporovať.';
+$lang['renderer_xhtml'] = 'Používané vykresľovacie jadro pre hlavný (xhtml) wiki výstup';
+$lang['renderer__core'] = '%s (dokuwiki jadro)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Povoliť trvalé prihlasovacie cookies (zapamätaj si ma)';
+$lang['rss_type'] = 'Typ XML feedu';
+$lang['rss_linkto'] = 'XML zdroj odkazuje na';
+$lang['rss_content'] = 'Čo zobrazovať v XML feede?';
+$lang['rss_update'] = 'Časový interval obnovy XML feedu (sek.)';
+$lang['recent_days'] = 'Koľko posledných zmien uchovávať (dni)';
+$lang['rss_show_summary'] = 'XML zdroj ukáže prehľad v názve';
+$lang['target____wiki'] = 'Cieľové okno (target) pre interné odkazy';
+$lang['target____interwiki'] = 'Cieľové okno (target) pre interwiki odkazy';
+$lang['target____extern'] = 'Cieľové okno (target) pre externé odkazy';
+$lang['target____media'] = 'Cieľové okno (target) pre media odkazy';
+$lang['target____windows'] = 'Cieľové okno (target) pre windows odkazy';
+$lang['proxy____host'] = 'Proxy server - názov';
+$lang['proxy____port'] = 'Proxy server - port';
+$lang['proxy____user'] = 'Proxy server - užívateľské meno';
+$lang['proxy____pass'] = 'Proxy server - heslo';
+$lang['proxy____ssl'] = 'Proxy server - použiť SSL';
+$lang['proxy____except'] = 'Regulárny výraz popisujúci URL odkazy, pre ktoré by proxy nemala byť použitá.';
+$lang['safemodehack'] = 'Povoliť "safemode hack"';
+$lang['ftp____host'] = 'FTP server pre "safemode hack"';
+$lang['ftp____port'] = 'FTP port pre "safemode hack"';
+$lang['ftp____user'] = 'FTP používateľ pre "safemode hack"';
+$lang['ftp____pass'] = 'FTP heslo pre "safemode hack"';
+$lang['ftp____root'] = 'FTP hlavný adresár pre "safemode hack"';
+$lang['license_o_'] = 'žiadna';
+$lang['typography_o_0'] = 'žiadne';
+$lang['typography_o_1'] = 'okrem jednoduchých úvodzoviek';
+$lang['typography_o_2'] = 'vrátane jednoduchých úvodzoviek (nemusí to vždy fungovať)';
+$lang['userewrite_o_0'] = 'žiadne';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki interné';
+$lang['deaccent_o_0'] = 'vypnuté';
+$lang['deaccent_o_1'] = 'odstrániť diakritiku';
+$lang['deaccent_o_2'] = 'romanizovať (do latinky)';
+$lang['gdlib_o_0'] = 'GD Lib nie je dostupná';
+$lang['gdlib_o_1'] = 'Verzia 1.x';
+$lang['gdlib_o_2'] = 'Autodetekcia';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Abstrakt';
+$lang['rss_content_o_diff'] = 'Normalizovaný Diff';
+$lang['rss_content_o_htmldiff'] = 'Tabuľka zmien v HTML formáte';
+$lang['rss_content_o_html'] = 'Obsah stránky v HTML formáte';
+$lang['rss_linkto_o_diff'] = 'prehľad zmien';
+$lang['rss_linkto_o_page'] = 'upravená stránka';
+$lang['rss_linkto_o_rev'] = 'zoznam zmien';
+$lang['rss_linkto_o_current'] = 'aktuálna stránka';
+$lang['compression_o_0'] = 'žiadna';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nepoužívať';
+$lang['xsendfile_o_1'] = 'Proprietárna lighttpd hlavička (pre vydaním 1.5)';
+$lang['xsendfile_o_2'] = 'Štandardná X-Sendfile hlavička';
+$lang['xsendfile_o_3'] = 'Proprietárna Nginx X-Accel-Redirect hlavička';
+$lang['showuseras_o_loginname'] = 'Prihlasovacie meno';
+$lang['showuseras_o_username'] = 'Celé meno používateľa';
+$lang['showuseras_o_email'] = 'E-mailová adresa používateľa (zamaskovaná podľa nastavenia)';
+$lang['showuseras_o_email_link'] = 'E-mailová adresa používateľa vo forme odkazu mailto:';
+$lang['useheading_o_0'] = 'Nikdy';
+$lang['useheading_o_navigation'] = 'Iba navigácia';
+$lang['useheading_o_content'] = 'Iba Wiki obsah';
+$lang['useheading_o_1'] = 'Vždy';
+$lang['readdircache'] = 'Maximálne trvanie readdir cache (sek)';
diff --git a/lib/plugins/config/lang/sl/intro.txt b/lib/plugins/config/lang/sl/intro.txt
new file mode 100644
index 000000000..506cd34bd
--- /dev/null
+++ b/lib/plugins/config/lang/sl/intro.txt
@@ -0,0 +1,7 @@
+====== Splošne nastavitve ======
+
+Na tej strani je mogoče spreminjati nastavitve sistema DokuWiki. Pomoč o posameznih nastavitvah je na voljo med [[doku>config|nastavitvami]]. Več podrobnosti o vstavku je na voljo na [[doku>plugin:config|nastavitvami vstavka]].
+
+Nastavitve označene s svetlo rdečim ozadjem so zaščitene in jih s tem vstavkom ni mogoče spreminjati. Nastavitve označene s svetlo modrim ozadjem so privzete vrednosti in nastavitve z belim ozadjem so tiste, ki so bile določene krajevno posebej za to nastavitev. Spreminjati je mogoče vrednosti označene z modrimi in belim ozadjem.
+
+Spremembe je treba **shraniti**, da se uveljavijo, sicer se spremembe prezrejo.
diff --git a/lib/plugins/config/lang/sl/lang.php b/lib/plugins/config/lang/sl/lang.php
new file mode 100644
index 000000000..ba4836823
--- /dev/null
+++ b/lib/plugins/config/lang/sl/lang.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * Slovenian language file
+ *
+ * @author Dejan Levec <webphp@gmail.com>
+ * @author Boštjan Seničar <senicar@gmail.com>
+ * @author Gregor Skumavc (grega.skumavc@gmail.com)
+ * @author Matej Urbančič (mateju@svn.gnome.org)
+ */
+$lang['menu'] = 'Splošne nastavitve';
+$lang['error'] = 'Nastavitve niso shranjene zaradi neveljavne vrednosti.<br />Neveljavna vrednost je označena z rdečim robom vnosnega polja.';
+$lang['updated'] = 'Nastavitve so uspešno posodobljene.';
+$lang['nochoice'] = '(ni drugih možnosti na voljo)';
+$lang['locked'] = 'Nastavitvene datoteke ni mogoče posodobiti.<br />Preverite dovoljenja za spreminjanje in ime nastavitvene datoteke.';
+$lang['danger'] = 'Opozorilo: spreminjanje te možnosti lahko povzroči težave v delovanju sistema wiki.';
+$lang['warning'] = 'Opozorilo: spreminjanje te možnosti lahko vpliva na pravilno delovanje sistema wiki.';
+$lang['security'] = 'Varnostno opozorilo: spreminjanje te možnosti lahko vpliva na varnost sistema.';
+$lang['_configuration_manager'] = 'Upravljalnik nastavitev';
+$lang['_header_dokuwiki'] = 'Nastavitve DokuWiki';
+$lang['_header_plugin'] = 'Nastavitve vstavkov';
+$lang['_header_template'] = 'Nastavitve predlog';
+$lang['_header_undefined'] = 'Neopredeljene nastavitve';
+$lang['_basic'] = 'Osnovne nastavitve';
+$lang['_display'] = 'Nastavitve prikazovanja';
+$lang['_authentication'] = 'Nastavitve overjanja';
+$lang['_anti_spam'] = 'Nastavitve neželenih sporočil (Anti-Spam)';
+$lang['_editing'] = 'Nastavitve urejanja';
+$lang['_links'] = 'Nastavitve povezav';
+$lang['_media'] = 'Predstavne nastavitve';
+$lang['_advanced'] = 'Napredne nastavitve';
+$lang['_network'] = 'Omrežne nastavitve';
+$lang['_plugin_sufix'] = 'nastavitve';
+$lang['_template_sufix'] = 'nastavitve';
+$lang['_msg_setting_undefined'] = 'Ni nastavitvenih metapodatkov.';
+$lang['_msg_setting_no_class'] = 'Ni nastavitvenega razreda.';
+$lang['_msg_setting_no_default'] = 'Ni privzete vrednosti.';
+$lang['fmode'] = 'Način ustvarjanja datotek';
+$lang['dmode'] = 'Način ustvarjanja map';
+$lang['lang'] = 'Jezik vmesnika';
+$lang['basedir'] = 'Pot do strežnika (npr. /dokuwiki/). Prazno polje določa samodejno zaznavanje';
+$lang['baseurl'] = 'Naslov URL strežnika (npr. http://www.streznik.si). Prazno polje določa samodejno zaznavanje';
+$lang['savedir'] = 'Mapa za shranjevanje podatkov';
+$lang['cookiedir'] = 'Pot do piškotka. Prazno polje določa uporabo osnovnega naslova (baseurl)';
+$lang['start'] = 'Ime začetne strani wiki';
+$lang['title'] = 'Naslov Wiki spletišča';
+$lang['template'] = 'Predloga';
+$lang['tagline'] = 'Označna vrstica (ob podpori predloge)';
+$lang['sidebar'] = 'Ime strani stranske vrstice (ob podpori predloge); prazno polje onemogoči stransko vrstico.';
+$lang['license'] = 'Pod pogoji katerega dovoljenja je objavljena vsebina?';
+$lang['fullpath'] = 'Pokaži polno pot strani v nogi strani';
+$lang['recent'] = 'Nedavne spremembe';
+$lang['breadcrumbs'] = 'Število drobtinic poti';
+$lang['youarehere'] = 'Hierarhične drobtinice poti';
+$lang['typography'] = 'Omogoči tipografske zamenjave';
+$lang['htmlok'] = 'Dovoli vstavljeno kodo HTML';
+$lang['phpok'] = 'Dovoli vstavljeno kodo PHP';
+$lang['dformat'] = 'Oblika zapisa časa (funkcija PHP <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Podpis';
+$lang['toptoclevel'] = 'Vrhnja raven kazala';
+$lang['tocminheads'] = 'Najmanjše število naslovov za izgradnjo kazala';
+$lang['maxtoclevel'] = 'Najvišja raven kazala';
+$lang['maxseclevel'] = 'Največja raven urejanja odseka';
+$lang['camelcase'] = 'Uporabi EnoBesedni zapisa za povezave';
+$lang['deaccent'] = 'Počisti imena strani';
+$lang['useheading'] = 'Uporabi prvi naslov za ime strani';
+$lang['refcheck'] = 'Preverjanje sklica predstavnih datotek';
+$lang['refshow'] = 'Število predstavih sklicev za prikaz';
+$lang['allowdebug'] = 'Dovoli razhroščevanje (po potrebi!)';
+$lang['mediarevisions'] = 'Ali naj se omogočijo objave predstavnih vsebin?';
+$lang['usewordblock'] = 'Zaustavi neželeno besedilo glede na seznam besed';
+$lang['indexdelay'] = 'Časovni zamik pred ustvarjanjem kazala (v sekundah)';
+$lang['relnofollow'] = 'Uporabni možnost rel="nofollow" pri zunanjih povezavah';
+$lang['mailguard'] = 'Šifriraj elektronske naslove';
+$lang['iexssprotect'] = 'Preveri poslane datoteke za zlonamerno kodo JavaScript ali HTML';
+$lang['showuseras'] = 'Kaj prikazati za prikaz uporabnika, ki je zadnji urejal stran';
+$lang['useacl'] = 'Uporabi seznam nadzora dostopa (ACL)';
+$lang['autopasswd'] = 'Samodejno ustvari gesla';
+$lang['authtype'] = 'Ozadnji način overitve';
+$lang['passcrypt'] = 'Način šifriranja gesel';
+$lang['defaultgroup'] = 'Privzeta skupina';
+$lang['superuser'] = 'Skrbnik - skupina, uporabnik ali z vejico ločen seznam uporabnik1,@skupina1,uporabnik2 s polnim dostopom do vseh strani in možnosti, neodvisno od nastavitev nadzora dostopa ACL';
+$lang['manager'] = 'Upravljavec - skupina, uporabnik ali z vejico ločen seznam uporabnik1,@skupina1,uporabnik2 z dovoljenji za dostop do nekaterih možnosti upravljanja';
+$lang['profileconfirm'] = 'Potrdi spremembe profila z geslom';
+$lang['disableactions'] = 'Onemogoči dejanja DokuWiki';
+$lang['disableactions_check'] = 'Preveri';
+$lang['disableactions_subscription'] = 'Naročanje/Preklic naročnine';
+$lang['disableactions_wikicode'] = 'Pogled izvorne kode/Surovi izvoz';
+$lang['disableactions_other'] = 'Druga dejanja (z vejico ločen seznam)';
+$lang['sneaky_index'] = 'Privzeto pokaže sistem DokuWiki vse imenske prostore v pogledu kazala. Z omogočanjem te možnosti bodo skriti vsi imenski prostori, v katere prijavljen uporabnik nima dovoljenj dostopa. S tem je mogoče preprečiti dostop do podrejenih strani. Možnost lahko vpliva na uporabnost nastavitev nadzora dostopa ACL.';
+$lang['auth_security_timeout'] = 'Varnostna časovna omejitev overitve (v sekundah)';
+$lang['securecookie'] = 'Ali naj se piškotki poslani preko varne povezave HTTPS v brskalniku pošiljajo le preko HTTPS? Onemogočanje možnosti je priporočljivo le takrat, ko je prijava varovana s protokolom SSL, brskanje po strani pa ni posebej zavarovano.';
+$lang['xmlrpc'] = 'Omogoči/Onemogoči vmesnik XML-RPC.';
+$lang['xmlrpcuser'] = 'Omejitev dostopa do vmesnika XML-RPC z vejico ločenim seznamom skupin in uporabnikov. Prazno polje pomeni, prost dostop za vse uporabnike.';
+$lang['updatecheck'] = 'Ali naj sistem preveri za posodobitve in varnostna opozorila.';
+$lang['userewrite'] = 'Uporabi olepšan zapis naslovov URL';
+$lang['useslash'] = 'Uporabi poševnico kot ločilnik imenskih prostorov v naslovih URL';
+$lang['usedraft'] = 'Samodejno shrani osnutek med urejanjem strani';
+$lang['sepchar'] = 'Ločilnik besed imen strani';
+$lang['canonical'] = 'Uporabi polni kanonični zapis naslova URL';
+$lang['fnencode'] = 'Način kodiranja ne-ASCII imen datotek.';
+$lang['autoplural'] = 'Preveri množinske oblike povezav';
+$lang['compression'] = 'Način stiskanja za arhivirane datoteke';
+$lang['cachetime'] = 'Največja dovoljena starost predpomnilnika (v sekundah)';
+$lang['locktime'] = 'Največja dovoljena starost datotek zaklepa (v sekundah)';
+$lang['fetchsize'] = 'največja dovoljena velikost zunanjega prejemanja z datoteko fetch.php (v bajtih)';
+$lang['notify'] = 'Pošlji obvestila o spremembah na določen elektronski naslov';
+$lang['registernotify'] = 'Pošlji obvestila o novih vpisanih uporabnikih na določen elektronski naslov';
+$lang['mailfrom'] = 'Elektronski naslov za samodejno poslana sporočila';
+$lang['mailprefix'] = 'Predpona zadeve elektronskega sporočila za samodejna sporočila.';
+$lang['gzip_output'] = 'Uporabi stiskanje gzip vsebine za xhtml';
+$lang['gdlib'] = 'Različica GD Lib';
+$lang['im_convert'] = 'Pot do orodja za pretvarjanje slik ImageMagick';
+$lang['jpg_quality'] = 'Kakovost stiskanja datotek JPG (0-100)';
+$lang['subscribers'] = 'Omogoči podporo naročanju na strani';
+$lang['subscribe_time'] = 'Čas po katerem so poslani povzetki sprememb (v sekundah); Vrednost mora biti krajša od časa, ki je določen z nedavno_dni.';
+$lang['compress'] = 'Združi odvod CSS in JavaScript v brskalniku';
+$lang['cssdatauri'] = 'Velikost sklicanih slik v bajtih, ki so navedene v datotekah CSS za zmanjšanje zahtev osveževanja strežnika HTTP. Ta možnost ni podprta v brskalniku MS IE 7 in nižjih različicah! Ustrezne vrednosti so <code>400</code> do <code>600</code> bajtov. Vrednost <code>0</code> onemogoči možnost.';
+$lang['hidepages'] = 'Skrij skladne strani (logični izraz)';
+$lang['send404'] = 'Pošlji "HTTP 404/Strani ni mogoče najti" pri dostopu do neobstoječih strani';
+$lang['sitemap'] = 'Ustvari Google kazalo strani (v dnevih)';
+$lang['broken_iua'] = 'Ali je možnost ignore_user_abort okvarjena na sistemu? Napaka lahko vpliva na delovanje iskalnika. Napake so pogoste ob uporabi IIS+PHP/CGI. Več o tem si je mogoče prebrati v <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">poročilu o hrošču 852</a>.';
+$lang['xsendfile'] = 'Uporabi glavo X-Sendfile za prejemanje statičnih datotek. Spletni strežnik mora možnost podpirati.';
+$lang['renderer_xhtml'] = 'Izrisovalnik za odvod Wiki strani (xhtml)';
+$lang['renderer__core'] = '%s (jedro dokuwiki)';
+$lang['renderer__plugin'] = '%s (vstavek)';
+$lang['rememberme'] = 'Dovoli trajne prijavne piškotke (trajno pomnenje prijave)';
+$lang['rss_type'] = 'Vrsta virov XML';
+$lang['rss_linkto'] = 'XML viri so povezani z';
+$lang['rss_content'] = 'Kaj prikazati med predmeti virov XML?';
+$lang['rss_update'] = 'Časovni razmik posodobitve virov XML (v sekundah)';
+$lang['recent_days'] = 'Koliko nedavnih sprememb naj se ohrani (v dnevih)';
+$lang['rss_show_summary'] = 'Viri XML so povzeti v naslovu';
+$lang['target____wiki'] = 'Ciljno okno za notranje povezave';
+$lang['target____interwiki'] = 'Ciljno okno za notranje wiki povezave';
+$lang['target____extern'] = 'Ciljno okno za zunanje povezave';
+$lang['target____media'] = 'Ciljno okno za predstavne povezave';
+$lang['target____windows'] = 'Ciljno okno za povezave oken';
+$lang['proxy____host'] = 'Ime posredniškega strežnika';
+$lang['proxy____port'] = 'Vrata posredniškega strežnika';
+$lang['proxy____user'] = 'Uporabniško ime posredniškega strežnika';
+$lang['proxy____pass'] = 'Geslo posredniškega strežnika';
+$lang['proxy____ssl'] = 'Uporabi varno povezavo SSL za povezavo z posredniškim strežnikom';
+$lang['proxy____except'] = 'Logični izrazi morajo biti skladni z naslovi URL, ki gredo mimo posredniškega strežnika.';
+$lang['safemodehack'] = 'Omogoči obhod načina SafeMode PHP';
+$lang['ftp____host'] = 'Strežnik FTP za obhod načina SafeMode';
+$lang['ftp____port'] = 'Vrata strežnika FTP za obhod načina SafeMode';
+$lang['ftp____user'] = 'Uporabniško ime za FTP za obhod načina SafeMode';
+$lang['ftp____pass'] = 'Geslo za strežnik FTP za obhod načina SafeMode';
+$lang['ftp____root'] = 'Korenska mapa FTP za obhod načina SafeMode';
+$lang['license_o_'] = 'Ni izbranega dovoljenja';
+$lang['typography_o_0'] = 'brez';
+$lang['typography_o_1'] = 'izloči enojne narekovaje';
+$lang['typography_o_2'] = 'z enojnimi narekovaji (lahko včasih ne deluje)';
+$lang['userewrite_o_0'] = 'brez';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'notranji DokuWiki';
+$lang['deaccent_o_0'] = 'onemogočeno';
+$lang['deaccent_o_1'] = 'odstrani naglasne oznake';
+$lang['deaccent_o_2'] = 'pretvori v romanski zapis';
+$lang['gdlib_o_0'] = 'Knjižnica GD Lib ni na voljo';
+$lang['gdlib_o_1'] = 'Različica 1.x';
+$lang['gdlib_o_2'] = 'Samodejno zaznavanje';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Povzetek';
+$lang['rss_content_o_diff'] = 'Poenotena primerjava';
+$lang['rss_content_o_htmldiff'] = 'HTML oblikovana preglednica primerjave';
+$lang['rss_content_o_html'] = 'Polna HTML vsebina strani';
+$lang['rss_linkto_o_diff'] = 'primerjalni pogled';
+$lang['rss_linkto_o_page'] = 'pregledana stran';
+$lang['rss_linkto_o_rev'] = 'seznam pregledovanj';
+$lang['rss_linkto_o_current'] = 'trenutna stran';
+$lang['compression_o_0'] = 'brez';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ne uporabi';
+$lang['xsendfile_o_1'] = 'lastniška glava lighttpd (pred različico 1.5)';
+$lang['xsendfile_o_2'] = 'običajna glava X-Sendfile';
+$lang['xsendfile_o_3'] = 'lastniška glava Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Prijavno ime';
+$lang['showuseras_o_username'] = 'Polno ime uporabnika';
+$lang['showuseras_o_email'] = 'Elektronski naslov uporabnika (šifriran po določilih varovanja)';
+$lang['showuseras_o_email_link'] = 'Elektronski naslov uporabnika kot povezava mailto:';
+$lang['useheading_o_0'] = 'nikoli';
+$lang['useheading_o_navigation'] = 'le za krmarjenje';
+$lang['useheading_o_content'] = 'le za vsebino Wiki';
+$lang['useheading_o_1'] = 'vedno';
+$lang['readdircache'] = 'Največja dovoljena starost predpomnilnika prebranih map (v sekundah)';
diff --git a/lib/plugins/config/lang/sq/intro.txt b/lib/plugins/config/lang/sq/intro.txt
new file mode 100644
index 000000000..687b497c9
--- /dev/null
+++ b/lib/plugins/config/lang/sq/intro.txt
@@ -0,0 +1,7 @@
+====== Menaxheri Konfigurimit ======
+
+Përdoreni këtë faqe për të kontrolluar kuadrot e instalimit të DokuWiki-t tuaj. Për ndihmë mbi kuadro individuale referojuni [[doku>config]]. Për më tepër detaje rreth këtij plugin-i shih [[doku>plugin:config]].
+
+Kuadrot e treguara me një backgroudn me një ngjyrë të kuqe të lehtë janë të mbrojtura dhe nuk mund të ndryshohen me këtë plugin. Kuadrot e treguara me një background blu janë vlerat default dhe kuadrot e treguara me një background të bardhë janë vendosur lokalisht për këtë instalim të caktuar. Si kuadrot blu, ashtu edhe ato të bardhë mund të ndryshohen.
+
+Kujtohuni të shtypni butonin **Ruaj** para se të dilni nga kjo faqe ose ndryshimet tuaja do të humbasin. \ No newline at end of file
diff --git a/lib/plugins/config/lang/sq/lang.php b/lib/plugins/config/lang/sq/lang.php
new file mode 100644
index 000000000..adeb2a47d
--- /dev/null
+++ b/lib/plugins/config/lang/sq/lang.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ * Albanian language file
+ *
+ * @author Leonard Elezi leonard.elezi@depinfo.info
+ */
+$lang['menu'] = 'Konfigurimi i Kuadrove';
+$lang['error'] = 'Kuadrot nuk u përditësuan për shkak të një vlere të palejuar, ju lutem rishikoni ndryshimet tuaja dhe ridorëzojeni.
+<br />Vlerat e pasakta tregohen të rrethuara nga një kornizë e kuqe.';
+$lang['updated'] = 'Kuadrot u përditësuan me sukses.';
+$lang['nochoice'] = '(asnjë zgjedhje tjetër e disponueshme)';
+$lang['locked'] = 'Skedari i kuadrove nuk mund të përditësohet, nëse kjo është e paqëllimshme, <br /> sigurohuni që emri i skedarit të kuadrove lokale dhe të drejtat të jenë të sakta.';
+$lang['danger'] = 'Rrezik: Ndrishimi i kësaj alternative mund ta bëjë wiki-n dhe menunë tuaj të konfigurimit të pa aksesueshme.';
+$lang['warning'] = 'Paralajmërim: Ndryshimi i kësaj alternative mund të shkaktojë sjellje të padëshiruara.';
+$lang['security'] = 'Paralajmërim Sigurie: Ndryshimi i kësaj alternative mund të paraqesë një rrezik në siguri.';
+$lang['_configuration_manager'] = 'Menaxhuesi i Kuadrove';
+$lang['_header_dokuwiki'] = 'Kuadrot e DokuWiki-t';
+$lang['_header_plugin'] = 'Kuadrot e Plugin-eve';
+$lang['_header_template'] = 'Kuadrot e Template-eve';
+$lang['_header_undefined'] = 'Kuadro të Papërcaktuara';
+$lang['_basic'] = 'Kuadro Elementare';
+$lang['_display'] = 'Kuadrot e Shfaqjes';
+$lang['_authentication'] = 'Kuadrot e Autentikimit';
+$lang['_anti_spam'] = 'Kuadrot Anti-Spam';
+$lang['_editing'] = 'Kuadrot e Redaktimit';
+$lang['_links'] = 'Kuadrot e Link-eve';
+$lang['_media'] = 'Kuadrot e Medias';
+$lang['_advanced'] = 'Kuadro të Avancuara';
+$lang['_network'] = 'Kuadrot e Rrjetit';
+$lang['_plugin_sufix'] = 'Kuadrot e Plugin-eve';
+$lang['_template_sufix'] = 'Kuadrot e Template-eve';
+$lang['_msg_setting_undefined'] = 'Metadata pa kuadro.';
+$lang['_msg_setting_no_class'] = 'Klasë pa kuadro.';
+$lang['_msg_setting_no_default'] = 'Asnjë vlerë default.';
+$lang['fmode'] = 'Mënyra krijim skedari';
+$lang['dmode'] = 'Mënyra krijim dosjeje.';
+$lang['lang'] = 'Gjuha e ndërfaqes';
+$lang['basedir'] = 'Path-i i Serverit (psh <code>/dokuwiki/</code>). Lëre bosh për ta gjetur automatikisht.';
+$lang['baseurl'] = 'URL-ja serverit (psh <code>http://www.serveriyt.com</code>). Lëre bosh për ta gjetur automatikisht.';
+$lang['savedir'] = 'Direktoria për të ruajtur të dhënat';
+$lang['start'] = 'Emri i faqes së fillimit';
+$lang['title'] = 'Titulli i Wiki-t';
+$lang['template'] = 'Template';
+$lang['license'] = 'Nën cilën liçensë duhet të vihet përmbajtja juar?';
+$lang['fullpath'] = 'Trego adresën e plotë të faqeve në footer.';
+$lang['recent'] = 'Ndryshimet më të fundit';
+$lang['breadcrumbs'] = 'Numri i gjurmëve';
+$lang['youarehere'] = 'Gjurmë hierarkike';
+$lang['typography'] = 'Bëj zëvendësime tipografike';
+$lang['htmlok'] = 'Lejo HTML të ngulitura';
+$lang['phpok'] = 'Lejo PHP të ngulitura';
+$lang['dformat'] = 'Formati i Datës (shiko funksionin <a href="http://www.php.net/strftime">strftime</a> e PHP-së)';
+$lang['signature'] = 'Firma';
+$lang['toptoclevel'] = 'Niveli i Kreut për tabelën e përmbajtjes';
+$lang['tocminheads'] = 'Sasia minimum e titrave që përcaktojnë nëse TOC ndërtohet ose jo';
+$lang['maxtoclevel'] = 'Niveli maksimum për tabelën e përmbajtjes';
+$lang['maxseclevel'] = 'Niveli maksimum për redaktim të seksionit';
+$lang['camelcase'] = 'Përdor CamelCase (shkronja e parë e çdo fjale është kapitale) për linke-t';
+$lang['deaccent'] = 'Emra faqesh të pastër';
+$lang['useheading'] = 'Përdor titra të nivelit të parë për faqet e emrave';
+$lang['refcheck'] = 'Kontroll për referim mediash';
+$lang['refshow'] = 'Numri i referimeve të medias që duhet të tregohet';
+$lang['allowdebug'] = 'Lejo debug <b>çaktivizoje nëse nuk nevojitet!</b>';
+$lang['usewordblock'] = 'Blloko spam-in duke u bazuar mbi listë fjalësh';
+$lang['indexdelay'] = 'Vonesa në kohë para index-imit (sekonda)';
+$lang['relnofollow'] = 'Përdor rel="nofollow" në linke të jashtëm';
+$lang['mailguard'] = 'Errëso adresat e email-it';
+$lang['iexssprotect'] = 'Kontrollo skedarët e ngarkuar për kod të mundshëm dashakeqës JavaScript ose HTML';
+$lang['showuseras'] = 'Cfarë të shfaqësh kur t\'i tregosh përdoruesit faqen e fundit të redaktuar';
+$lang['useacl'] = 'Përdor lista kontrolli të aksesit';
+$lang['autopasswd'] = 'Autogjenero fjalëkalime';
+$lang['authtype'] = 'Backend autentikimi';
+$lang['passcrypt'] = 'Metoda e enkriptimit të fjalëkalimit';
+$lang['defaultgroup'] = 'Grupi default';
+$lang['superuser'] = 'Superpërdorues - grup, përdorues ose listë e ndarë me presje user1, @group1,user2 me akses të plotë në të gjitha faqet dhe funksionet pavarësisht kuadrove të ACL';
+$lang['manager'] = 'Menaxher - grup, përdorues ose listë e ndarë me presje user1,@group1,user2 me akses në disa funksione të caktuara menaxhimi';
+$lang['profileconfirm'] = 'Konfirmo ndryshimet ne profil me fjalëkalim';
+$lang['disableactions'] = 'Caktivizo veprimet e DokuWiki-it';
+$lang['disableactions_check'] = 'Kontrollo';
+$lang['disableactions_subscription'] = 'Abonohu/Fshi Abonim';
+$lang['disableactions_wikicode'] = 'Shiku kodin burim/ Eksportoje të Papërpunuar';
+$lang['disableactions_other'] = 'Veprime të tjera (të ndarë me presje)';
+$lang['sneaky_index'] = 'Vetiu DokuWiki tregon të gjithë hapësirat e emrit në shikimin e index-it. Aktivizimi i kësaj alternative do të fshehë ato ku përdoruesi nuk ka të drejta leximi. Kjo mund të përfundojë në fshehje të nënhapësirave të emrit të aksesueshme. Kjo mund ta bëjë index-in të papërdorshëm me disa konfigurime të caktuara të ACL-së.';
+$lang['auth_security_timeout'] = 'Koha e Përfundimit për Autentikim (sekonda)';
+$lang['securecookie'] = 'A duhet që cookies të vendosura nëpërmjet HTTPS të dërgohen vetëm nëpërmjet HTTPS nga shfletuesit? Caktivizojeni këtë alternativë kur vetëm hyrja në wiki-n tuaj sigurohet me SSL por shfletimi i wiki-t bëhet në mënyrë të pasigurtë.';
+$lang['xmlrpc'] = 'Aktivizo/Caktivizo ndërfaqen XML-RPC';
+$lang['xmlrpcuser'] = 'Kufizo aksesin XML-RPC vetëm tek grupet ose përdoruesit e ndarë me presje të dhënë këtu. Lëre bosh për t\'i dhënë akses të gjithëve.';
+$lang['updatecheck'] = 'Kontrollo për përditësime dhe paralajmërime sigurie? DokuWiki duhet të kontaktojë me update.dokuwiki.org për këtë veti.';
+$lang['userewrite'] = 'Përdor URL të këndshme.';
+$lang['useslash'] = 'Përdor / si ndarës të hapësirave të emrit në URL';
+$lang['usedraft'] = 'Ruaj automatikisht një skicë gjatë redaktimit';
+$lang['sepchar'] = 'Fjala ndarëse për emrin e faqes';
+$lang['canonical'] = 'Përdor URL kanonike të plota';
+$lang['autoplural'] = 'Kontrollo për forma shumës në link-e';
+$lang['compression'] = 'Metoda kompresimit për skedarët atikë';
+$lang['cachetime'] = 'Mosha maksimale për cache (sekonda)';
+$lang['locktime'] = 'Mosha maksimale për kyçjen e skedarëve (sekonda)';
+$lang['fetchsize'] = 'Madhësia maksimale (bytes) që fetch.php mund të shkarkojë nga jashtë';
+$lang['notify'] = 'Dërgo lajmërim për ndryshime te kjo adresë email-i';
+$lang['registernotify'] = 'Dërgo info për përdoruesit e sapo regjistruar te kjo adresë email-i';
+$lang['mailfrom'] = 'Adresa e email-it që do të përdoret për dërgimin e email-eve automatikë';
+$lang['gzip_output'] = 'Përdor gzip Content-Encoding për xhtml';
+$lang['gdlib'] = 'Versioni i GD Lib';
+$lang['im_convert'] = 'Path-i për tek mjeti i konvertimit ImageMagick';
+$lang['jpg_quality'] = 'Cilësia e kompresimit JPG (0-100)';
+$lang['subscribers'] = 'Aktivizo suportin për abonim faqesh';
+$lang['subscribe_time'] = 'Koha pas së cilës listat e abonimeve dhe konsumimet dërgohen (sekonda); Kjo duhet të jetë më e vogël se koha e specifikuar në ditët më të fundit';
+$lang['compress'] = 'Kompaktëso daljet CSS dhe JavaScript ';
+$lang['hidepages'] = 'Fshi faqet që përkojnë (shprehjet e rregullta)';
+$lang['send404'] = 'Dërgo "HTTP 404/Page Not Found" për faqe që nuk ekzistojnë';
+$lang['sitemap'] = 'Gjenero Google sitemap (ditë)';
+$lang['broken_iua'] = 'Funksioni ignore_user_abort është i prishur në sistemin tuaj? Kjo mund të shkaktojë një indeks kërkimi jo funksional. IIS+PHP/CGI njihen si të prishura. Shiko <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> për më shumë info.';
+$lang['xsendfile'] = 'Përdor kokën X-Sendfile për të lejuar webserver-in të dërgojë skedarë statikë? Kjo duhet të suportohet nga webserver-i juaj.';
+$lang['renderer_xhtml'] = 'Riprodhuesi i përdorur për daljen wiki kryesore (xhtml)';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Lejo cookies hyrjeje të përhershme (më kujto mua)';
+$lang['rss_type'] = 'Tipi feed XML';
+$lang['rss_linkto'] = 'XML feed lidhet me';
+$lang['rss_content'] = 'Cfarë të shfaqësh në objektet XML feed?';
+$lang['rss_update'] = 'Intervali i përditësimit XML feed (sekonda)';
+$lang['recent_days'] = 'Sa ndryshime të fundit duhen mbajtur (ditë)';
+$lang['rss_show_summary'] = 'XML feed trego përmbledhjen në titull';
+$lang['target____wiki'] = 'Dritarja target për link-e të brendshëm';
+$lang['target____interwiki'] = 'Dritarja target për link-e interwiki';
+$lang['target____extern'] = 'Dritarja target për link-e të jashtme';
+$lang['target____media'] = 'Dritarja target për link-e mediash';
+$lang['target____windows'] = 'Dritarja target për link-e windows-i';
+$lang['proxy____host'] = 'Emri i serverit të proxy-t';
+$lang['proxy____port'] = 'Porta e proxy-t';
+$lang['proxy____user'] = 'Emri i përdoruesit për proxy-n';
+$lang['proxy____pass'] = 'Fjalëkalimi proxy-t';
+$lang['proxy____ssl'] = 'Përdor SSL për tu lidhur me proxy-n';
+$lang['safemodehack'] = 'Aktivizo hack në safemode';
+$lang['ftp____host'] = 'Server FTP për safemode hack';
+$lang['ftp____port'] = 'Porta FTP për safemode hack';
+$lang['ftp____user'] = 'Emri përdoruesit për safemode hack';
+$lang['ftp____pass'] = 'Fjalëkalimi FTP për safemode hack';
+$lang['ftp____root'] = 'Direktoria rrënjë për safemode hack';
+$lang['license_o_'] = 'Nuk u zgjodh asgjë';
+$lang['typography_o_0'] = 'Asgjë';
+$lang['typography_o_1'] = 'përjashtim i thonjëzave teke';
+$lang['typography_o_2'] = 'përfshirje e thonjëzave teke (nuk punon gjithmonë) ';
+$lang['userewrite_o_0'] = 'asgjë';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Brendësia DokuWiki';
+$lang['deaccent_o_0'] = 'fikur';
+$lang['deaccent_o_1'] = 'hiq theksin';
+$lang['deaccent_o_2'] = 'romanizo';
+$lang['gdlib_o_0'] = 'GD Lib nuk është e disponueshme';
+$lang['gdlib_o_1'] = 'Versioni 1.x';
+$lang['gdlib_o_2'] = 'Dallim automatik';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Abstrakte';
+$lang['rss_content_o_diff'] = 'Ndryshime të njësuara';
+$lang['rss_content_o_htmldiff'] = 'Tabelë ndryshimesh e formatuar në HTML';
+$lang['rss_content_o_html'] = 'Përmbajtje e plotë faqeje HTML';
+$lang['rss_linkto_o_diff'] = 'shikimi ndryshimit';
+$lang['rss_linkto_o_page'] = 'faqja e rishikuar';
+$lang['rss_linkto_o_rev'] = 'lista e rishikimeve';
+$lang['rss_linkto_o_current'] = 'faqja aktuale';
+$lang['compression_o_0'] = 'asgjë';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'mos e përdor';
+$lang['xsendfile_o_1'] = 'Proprietary lighttpd header (para lëshimit 1.5)';
+$lang['xsendfile_o_2'] = 'X-Sendfile header standard';
+$lang['xsendfile_o_3'] = 'Proprietary Nginx X-Accel-Redirect header';
+$lang['showuseras_o_loginname'] = 'Emri hyrjes';
+$lang['showuseras_o_username'] = 'Emri i plotë i përdoruesit';
+$lang['showuseras_o_email'] = 'Adresa e email-it e përdoruesit (errësuar sipas kuadros mailguard)';
+$lang['showuseras_o_email_link'] = 'Adresa email e përdoruesit si një mailto: link';
+$lang['useheading_o_0'] = 'Kurrë';
+$lang['useheading_o_navigation'] = 'Vetëm për Navigim';
+$lang['useheading_o_content'] = 'Vetëm për Përmbajtje Wiki';
+$lang['useheading_o_1'] = 'Gjithmonë';
diff --git a/lib/plugins/config/lang/sr/intro.txt b/lib/plugins/config/lang/sr/intro.txt
new file mode 100644
index 000000000..0ee76edcd
--- /dev/null
+++ b/lib/plugins/config/lang/sr/intro.txt
@@ -0,0 +1,7 @@
+====== Управљач подешавањима ======
+
+Ову страну користите за контролу подешавања вашег DokuWiki-ја. За помоћ о индивидуалним поставкама погледајте [[doku>config]]. За више информација о додацима погледајте [[doku>plugin:config]].
+
+Подешавања која имају светло црвену позадину су заштићена и не могу се мењати овим додатком. Подешавања која имају светло плаву позадину су подразумеване вредности и подешавања са белом позадином су локална за ову вики инсталацију. И плава и бела подешавања се могу мењати.
+
+Не заборавите да притиснете дугме **Сачувај** када завршите са изменама, у супротном ће ваше измене бити изгубљене.
diff --git a/lib/plugins/config/lang/sr/lang.php b/lib/plugins/config/lang/sr/lang.php
new file mode 100644
index 000000000..5906dcd7e
--- /dev/null
+++ b/lib/plugins/config/lang/sr/lang.php
@@ -0,0 +1,184 @@
+<?php
+/**
+ * Serbian language file
+ *
+ * @author Иван Петровић petrovicivan@ubuntusrbija.org
+ * @author Ivan Petrovic <petrovicivan@ubuntusrbija.org>
+ * @author Miroslav Šolti <solti.miroslav@gmail.com>
+ */
+$lang['menu'] = 'Подешавања';
+$lang['error'] = 'Подешавања нису прихваћена јер постоји вредност са грешком, проверите измене које сте извршили и поновите слање.<br />Вредност(и) са грешком су приказане са црвеним оквиром.';
+$lang['updated'] = 'Измене су сачуване.';
+$lang['nochoice'] = '(не постоји други избор)';
+$lang['locked'] = 'Датотека са подешавањима не може да се ажурира, ако вам то није намера проверите да ли су дозволе исправно постављене.';
+$lang['danger'] = 'Опасно: Променом ове опције може се десити да ваш вики и мени за подешавања буде недоступан.';
+$lang['warning'] = 'Упозорење: Промена ове опције може проузроковати нежељене ефекте.';
+$lang['security'] = 'Сигурносно упозорење: Промена ове опције може да проузрокује сигурносни ризик.';
+$lang['_configuration_manager'] = 'Управљач подешавањима';
+$lang['_header_dokuwiki'] = 'Подешавања Dokuwiki-ја';
+$lang['_header_plugin'] = 'Подешавања за додатке';
+$lang['_header_template'] = 'Подешавања за шаблоне';
+$lang['_header_undefined'] = 'Неразврстана подешавања';
+$lang['_basic'] = 'Основна подешавања';
+$lang['_display'] = 'Подешавања приказа';
+$lang['_authentication'] = 'Подешавања провере';
+$lang['_anti_spam'] = 'Подешавања за борбу против спама';
+$lang['_editing'] = 'Подешавања измена';
+$lang['_links'] = 'Подешавања линковања';
+$lang['_media'] = 'Подешавања медија';
+$lang['_advanced'] = 'Напредна подешавања';
+$lang['_network'] = 'Подешавања мреже';
+$lang['_plugin_sufix'] = 'Подешавања за додатке';
+$lang['_template_sufix'] = 'Подешавања за шаблоне';
+$lang['_msg_setting_undefined'] = 'Нема метаподатака подешавања';
+$lang['_msg_setting_no_class'] = 'Нема класе подешавања';
+$lang['_msg_setting_no_default'] = 'Нема подразумеване вредности';
+$lang['fmode'] = 'Начин прављења датотека';
+$lang['dmode'] = 'Начин прављења фасцикла';
+$lang['lang'] = 'Језик';
+$lang['basedir'] = 'Основна фасцикла';
+$lang['baseurl'] = 'Основни УРЛ';
+$lang['savedir'] = 'Фасцикла у којој ће се чувати подаци';
+$lang['start'] = 'Назив почетне странице';
+$lang['title'] = 'Назив викија';
+$lang['template'] = 'Шаблон';
+$lang['license'] = 'Под којом лиценцом желите да ваш материјал буде објављен?';
+$lang['fullpath'] = 'Објави целу путању странице у заглављу на дну стране';
+$lang['recent'] = 'Последње промене';
+$lang['breadcrumbs'] = 'Број пређених корака (страница)';
+$lang['youarehere'] = 'Хиерархијске кораке (странице)';
+$lang['typography'] = 'Уради типографске замене';
+$lang['htmlok'] = 'Дозволи угњежђени ХТМЛ';
+$lang['phpok'] = 'Дозволи угњежђени ПХП';
+$lang['dformat'] = 'Облик датума (погледајте ПХПову <a href="http://www.php.net/strftime">strftime</a> функцију)';
+$lang['signature'] = 'Потпис';
+$lang['toptoclevel'] = 'Највиши ниво за садржај';
+$lang['tocminheads'] = 'Минималан број наслова који одређују да ли ће Садржај бити направљен';
+$lang['maxtoclevel'] = 'Максимални ниво за садржај';
+$lang['maxseclevel'] = 'Максималан број секција које се мењају';
+$lang['camelcase'] = 'Користи CamelCase за линкове';
+$lang['deaccent'] = 'Чисти имена страница';
+$lang['useheading'] = 'Преузми наслов првог нивоа за назив странице';
+$lang['refcheck'] = 'Провери референце медијских датотека';
+$lang['refshow'] = 'Број референци које се приказују за медијске датотеке';
+$lang['allowdebug'] = 'Укључи дебаговање <b>искључи ако није потребно!</b>';
+$lang['usewordblock'] = 'Блокирај спам на основу листе речи';
+$lang['indexdelay'] = 'Одлагање индексирања (секунде)';
+$lang['relnofollow'] = 'Користи rel="nofollow" за спољне линкове';
+$lang['mailguard'] = 'Замутити Е-адресе';
+$lang['iexssprotect'] = 'Провера потенцијално малициозног кода у Јаваскрипт или ХТМЛ коду';
+$lang['showuseras'] = 'Шта приказати за исписивање корисника који је последњи вршио измене';
+$lang['useacl'] = 'Користи листу права приступа';
+$lang['autopasswd'] = 'Аутогенерисане лозинки';
+$lang['authtype'] = 'Позадински систем аутентификације';
+$lang['passcrypt'] = 'Метода енкрипције лозинки';
+$lang['defaultgroup'] = 'Подразумевана група';
+$lang['superuser'] = 'Суперкорисник - група, корисник или зарезом одвојена листа корисника корисник1,@група1,корисник2 са отвореним проступом свим страницама и функцијама без обзира на поставке Контроле приступа';
+$lang['manager'] = 'Управник - група, корисник или зарезом одвојена листа корисника корисник1,@група1,корисник2 са отвореним проступом неким функцијама за управљање';
+$lang['profileconfirm'] = 'Потврди промене у профилу куцањем лозинке';
+$lang['disableactions'] = 'Искључи DokuWiki наредбе';
+$lang['disableactions_check'] = 'Провера';
+$lang['disableactions_subscription'] = 'Претплата';
+$lang['disableactions_wikicode'] = 'Прикажи извор/Извези сирово';
+$lang['disableactions_other'] = 'Остале наредбе (раздвојене зарезом)';
+$lang['sneaky_index'] = 'По инсталацији DokuWiki ће у индексу приказати све именске просторе. Укључивањем ове опције именски простори у којима корисник нема право читања ће бити сакривени. Консеквенца је да ће и доступни подпростори бити сакривени. Ово доводи до неупотребљивости Права приступа у неким поставкама.';
+$lang['auth_security_timeout'] = 'Временска пауза у аутентификацији (секунде)';
+$lang['securecookie'] = 'Да ли колачићи који су постављени преко ХТТПС треба слати веб читачу само преко ХТТПС? Искључите ову опцију само ако је пријављивање на вики заштићено ССЛом а остали део викија незаштићен.';
+$lang['xmlrpc'] = 'Укључи/искључи ИксМЛ-РПЦ интерфејс';
+$lang['xmlrpcuser'] = 'Ограничи ИксМЛ-РПЦ приступ на наведене групе корисника раздвојене зарезом. Остави празно да би свима дао приступ.';
+$lang['updatecheck'] = 'Провера надоградњи и сигурносних упозорења? Dokuwiki мора да контактира update.dokuwiki.org ради добијања информација.';
+$lang['userewrite'] = 'Направи леп УРЛ';
+$lang['useslash'] = 'Користи косу црту у УРЛу за раздвајање именских простора ';
+$lang['usedraft'] = 'Аутоматски сачувај скицу у току писања измена';
+$lang['sepchar'] = 'Раздвајање речи у називу странице';
+$lang['canonical'] = 'Користи правилне УРЛове';
+$lang['fnencode'] = 'Метод кодирања не-ASCII имена фајлова:';
+$lang['autoplural'] = 'Провери облик множине у линковима';
+$lang['compression'] = 'Метод компресије за attic датотеке';
+$lang['cachetime'] = 'Максимално трајање оставе (сек)';
+$lang['locktime'] = 'МАксимално трајање закључавања датотека (сек)';
+$lang['fetchsize'] = 'Максимална величина (у бајтима) коју може да преузме fetch.php од споља';
+$lang['notify'] = 'Пошаљи обавештења о променама на ову е-адресу';
+$lang['registernotify'] = 'Пошаљи обавештење о новорегистрованим корисницима на ову е-адресу';
+$lang['mailfrom'] = 'Е-адреса која се користи као пошиљаоц за аутоматске е-поруке';
+$lang['gzip_output'] = 'Користи гзип шифрирање за иксХТМЛ';
+$lang['gdlib'] = 'ГД Либ верзија';
+$lang['im_convert'] = 'Путања до алатке за коверзију ИмиџМеџик ';
+$lang['jpg_quality'] = 'ЈПГ квалитет компресије (0-100)';
+$lang['subscribers'] = 'Укључи могућност претплате за странице';
+$lang['subscribe_time'] = 'Време након ког се спискови претплатника и сижеи шаљу (у секундама); Ова цифра би требало да буде мања од цифре наведене под recent_days';
+$lang['compress'] = 'Сажимај ЦСС и јаваскрипт';
+$lang['hidepages'] = 'Сакриј подударне странице (на основу регуларних израза)';
+$lang['send404'] = 'Пошаљи поруку "ХТТП 404/Страница не постоји" за непостојеће странице';
+$lang['sitemap'] = 'Генериши Гугл мапу сајта (дан)';
+$lang['broken_iua'] = 'Да ли је функција ignore_user_abort function не ради на вашем систему? Ово може проузроковати неиндексирање података за претрагу. ИИС+ПХП/ЦГИ је често ван функције. Погледајте <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">баг 852</a> за више информација.';
+$lang['xsendfile'] = 'Користи заглавље X-Sendfile да би веб сервер могао да испоручује статичке датотеке? Веб сервер треба да подржава ову функцију.';
+$lang['renderer_xhtml'] = 'Исцртавање користи главни (xhtml) вики испис';
+$lang['renderer__core'] = '%s (dokuwiki језгро)';
+$lang['renderer__plugin'] = '%s (додатак)';
+$lang['rememberme'] = 'Дозволи стални колачић за пријављивање (запамти ме)';
+$lang['rss_type'] = 'Врста ИксМЛ довода';
+$lang['rss_linkto'] = 'ИксМЛ довод линкује на';
+$lang['rss_content'] = 'Шта треба приказати у ИксМЛ доводу?';
+$lang['rss_update'] = 'ИксМЛ';
+$lang['recent_days'] = 'Колико последњих промена чувати (дани)';
+$lang['rss_show_summary'] = 'ИксМЛ довод приказује збир у наслову';
+$lang['target____wiki'] = 'Циљни прозор за интерне линкове';
+$lang['target____interwiki'] = 'Циљни прозор за међувики линкове';
+$lang['target____extern'] = 'Циљни прозор за спољне линкове';
+$lang['target____media'] = 'Циљни прозор за медијске линкове';
+$lang['target____windows'] = 'Циљни прозор за Виндоуз линкове';
+$lang['proxy____host'] = 'Назив посредника (проксија)';
+$lang['proxy____port'] = 'Порт посредника (проксија)';
+$lang['proxy____user'] = 'Корисничко име на посреднику (проксију)';
+$lang['proxy____pass'] = 'Лозинка на посреднику (проксију)';
+$lang['proxy____ssl'] = 'Користи ССЛ за повезивање са посредником (проксијем)';
+$lang['proxy____except'] = 'Редован израз који би требало да се подудара са веб адресом странице за коју треба прескочити посредника (прокси).';
+$lang['safemodehack'] = 'Укључи преправку за безбедни режим';
+$lang['ftp____host'] = 'ФТП сервер за безбедни режим';
+$lang['ftp____port'] = 'ФТП порт за безбедни режим';
+$lang['ftp____user'] = 'ФТП корисничко име за безбедни режим';
+$lang['ftp____pass'] = 'ФТП лозинка за безбедни режим';
+$lang['ftp____root'] = 'ФТП основна фасцикла за безбедни режим';
+$lang['license_o_'] = 'Није одабрано';
+$lang['typography_o_0'] = 'не';
+$lang['typography_o_1'] = 'Само дупли наводници';
+$lang['typography_o_2'] = 'Сви наводници (неће увек радити)';
+$lang['userewrite_o_0'] = 'не';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki интерно';
+$lang['deaccent_o_0'] = 'искључено';
+$lang['deaccent_o_1'] = 'уклони акценте';
+$lang['deaccent_o_2'] = 'романизуј';
+$lang['gdlib_o_0'] = 'ГД Либ није доступан';
+$lang['gdlib_o_1'] = 'Верзија 1.*';
+$lang['gdlib_o_2'] = 'Аутопроналажење';
+$lang['rss_type_o_rss'] = 'РСС 0.91';
+$lang['rss_type_o_rss1'] = 'РСС 1.0';
+$lang['rss_type_o_rss2'] = 'РСС 2.0';
+$lang['rss_type_o_atom'] = 'Атом 0.3';
+$lang['rss_type_o_atom1'] = 'Атом 1.0';
+$lang['rss_content_o_abstract'] = 'Издвојити';
+$lang['rss_content_o_diff'] = 'Једностране разлике';
+$lang['rss_content_o_htmldiff'] = 'ХТМЛ форматирана табела разлика';
+$lang['rss_content_o_html'] = 'ХТМЛ садржај странице';
+$lang['rss_linkto_o_diff'] = 'приказ разлика';
+$lang['rss_linkto_o_page'] = 'исправљена страница';
+$lang['rss_linkto_o_rev'] = 'листа исправки';
+$lang['rss_linkto_o_current'] = 'тренутна страница';
+$lang['compression_o_0'] = 'не';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'не';
+$lang['xsendfile_o_1'] = 'Власничко lighttpd заглавље (пре верзије 1.5)';
+$lang['xsendfile_o_2'] = 'Стандардно заглавље X-Sendfile';
+$lang['xsendfile_o_3'] = 'Власничко заглавље Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Корисничко име';
+$lang['showuseras_o_username'] = 'Име и презиме корисника';
+$lang['showuseras_o_email'] = 'Е-адреса (замућено по подешавањима mailguard-а)';
+$lang['showuseras_o_email_link'] = 'Корисничка Е-адреса као mailto: веза';
+$lang['useheading_o_0'] = 'Никада';
+$lang['useheading_o_navigation'] = 'Сами навигација';
+$lang['useheading_o_content'] = 'Само за садржај викија';
+$lang['useheading_o_1'] = 'Увек';
+$lang['readdircache'] = 'Максимално време трајања за readdir cache (у секундама)';
diff --git a/lib/plugins/config/lang/sv/intro.txt b/lib/plugins/config/lang/sv/intro.txt
new file mode 100644
index 000000000..8887d4a7b
--- /dev/null
+++ b/lib/plugins/config/lang/sv/intro.txt
@@ -0,0 +1,9 @@
+====== Hantera inställningar ======
+
+Använd den här sidan för att göra inställningar i din Dokuwiki. För hjälp angående specifika inställningar, se [[doku>config]]. För mer detaljer om den här insticksmodulen, se [[doku>plugin:config]].
+
+Inställningar med en rosa bakgrund är skyddade och kan inte ändras med den här insticksmodulen. Inställningar med en blå bakgrund är standardvärden, och inställningar som visas med en vit bakgrund har ändrats i den här installationen. Både blåa och vita inställningar kan ändras.
+
+Kom i håg att trycka på knappen **Spara** innan du lämnar den här sidan, annars kommer ändringarna att gå förlorade.
+
+
diff --git a/lib/plugins/config/lang/sv/lang.php b/lib/plugins/config/lang/sv/lang.php
new file mode 100644
index 000000000..dfd93d37d
--- /dev/null
+++ b/lib/plugins/config/lang/sv/lang.php
@@ -0,0 +1,194 @@
+<?php
+/**
+ * swedish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Per Foreby <per@foreby.se>
+ * @author Nicklas Henriksson <nicklas[at]nihe.se>
+ * @author Håkan Sandell <hakan.sandell[at]mydata.se>
+ * @author Dennis Karlsson
+ * @author Tormod Otter Johansson <tormod@latast.se>
+ * @author emil@sys.nu
+ * @author Pontus Bergendahl <pontus.bergendahl@gmail.com>
+ * @author Tormod Johansson tormod.otter.johansson@gmail.com
+ * @author Emil Lind <emil@sys.nu>
+ * @author Bogge Bogge <bogge@bogge.com>
+ * @author Peter Åström <eaustreum@gmail.com>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ * @author mikael@mallander.net
+ */
+$lang['menu'] = 'Hantera inställningar';
+$lang['error'] = 'Inställningarna uppdaterades inte på grund av ett felaktigt värde. Titta igenom dina ändringar och försök sedan spara igen.
+ <br />Felaktiga värden är omgivna av en röd ram.';
+$lang['updated'] = 'Inställningarna uppdaterade.';
+$lang['nochoice'] = '(inga andra val tillgängliga)';
+$lang['locked'] = 'Filen med inställningar kan inte uppdateras. Om det inte är meningen att det ska vara så, <br />
+ kontrollera att filen med lokala inställningar har rätt namn och filskydd.';
+$lang['danger'] = 'Risk: Denna förändring kan göra wikin och inställningarna otillgängliga.';
+$lang['warning'] = 'Varning: Denna förändring kan orsaka icke åsyftade resultat.';
+$lang['security'] = 'Säkerhetsvarning: Denna förändring kan innebära en säkerhetsrisk.';
+$lang['_configuration_manager'] = 'Hantera inställningar';
+$lang['_header_dokuwiki'] = 'Inställningar för DokuWiki';
+$lang['_header_plugin'] = 'Inställningar för insticksmoduler';
+$lang['_header_template'] = 'Inställningar för mallar';
+$lang['_header_undefined'] = 'Odefinierade inställningar';
+$lang['_basic'] = 'Grundläggande inställningar';
+$lang['_display'] = 'Inställningar för presentation';
+$lang['_authentication'] = 'Inställningar för autentisering';
+$lang['_anti_spam'] = 'Inställningar för anti-spam';
+$lang['_editing'] = 'Inställningar för redigering';
+$lang['_links'] = 'Inställningar för länkar';
+$lang['_media'] = 'Inställningar för medier';
+$lang['_advanced'] = 'Avancerade inställningar';
+$lang['_network'] = 'Nätverksinställningar';
+$lang['_plugin_sufix'] = '(inställningar för insticksmodul)';
+$lang['_template_sufix'] = '(inställningar för mall)';
+$lang['_msg_setting_undefined'] = 'Ingen inställningsmetadata.';
+$lang['_msg_setting_no_class'] = 'Ingen inställningsklass.';
+$lang['_msg_setting_no_default'] = 'Inget standardvärde.';
+$lang['fmode'] = 'Filskydd för nya filer';
+$lang['dmode'] = 'Filskydd för nya kataloger';
+$lang['lang'] = 'Språk';
+$lang['basedir'] = 'Grundkatalog';
+$lang['baseurl'] = 'Grund-webbadress';
+$lang['savedir'] = 'Katalog för att spara data';
+$lang['start'] = 'Startsidans namn';
+$lang['title'] = 'Wikins namn';
+$lang['template'] = 'Mall';
+$lang['license'] = 'Under vilken licens skall ditt innehåll publiceras?';
+$lang['fullpath'] = 'Visa fullständig sökväg i sidfoten';
+$lang['recent'] = 'Antal poster under "Nyligen ändrat"';
+$lang['breadcrumbs'] = 'Antal spår';
+$lang['youarehere'] = 'Hierarkiska spår';
+$lang['typography'] = 'Aktivera typografiska ersättningar';
+$lang['htmlok'] = 'Tillåt inbäddad HTML';
+$lang['phpok'] = 'Tillåt inbäddad PHP';
+$lang['dformat'] = 'Datumformat (se PHP:s <a href="http://www.php.net/strftime">strftime</a>-funktion)';
+$lang['signature'] = 'Signatur';
+$lang['toptoclevel'] = 'Toppnivå för innehållsförteckning';
+$lang['tocminheads'] = 'Minimalt antal rubriker för att avgöra om innehållsförteckning byggs';
+$lang['maxtoclevel'] = 'Maximal nivå för innehållsförteckning';
+$lang['maxseclevel'] = 'Maximal nivå för redigering av rubriker';
+$lang['camelcase'] = 'Använd CamelCase för länkar';
+$lang['deaccent'] = 'Rena sidnamn';
+$lang['useheading'] = 'Använda första rubriken som sidnamn';
+$lang['refcheck'] = 'Kontrollera referenser till mediafiler';
+$lang['refshow'] = 'Antal mediareferenser som ska visas';
+$lang['allowdebug'] = 'Tillåt felsökning <b>stäng av om det inte behövs!</b>';
+$lang['usewordblock'] = 'Blockera spam baserat på ordlista';
+$lang['indexdelay'] = 'Tidsfördröjning före indexering (sek)';
+$lang['relnofollow'] = 'Använd rel="nofollow" för externa länkar';
+$lang['mailguard'] = 'Koda e-postadresser';
+$lang['iexssprotect'] = 'Kontrollera om uppladdade filer innehåller eventuellt skadlig JavaScript eller HTML-kod';
+$lang['showuseras'] = 'Vad som skall visas när man visar den användare som senast redigerade en sida';
+$lang['useacl'] = 'Använd behörighetslista (ACL)';
+$lang['autopasswd'] = 'Autogenerera lösenord';
+$lang['authtype'] = 'System för autentisering';
+$lang['passcrypt'] = 'Metod för kryptering av lösenord';
+$lang['defaultgroup'] = 'Förvald grupp';
+$lang['superuser'] = 'Huvudadministratör - en grupp eller en användare med full tillgång till alla sidor och funktioner, oavsett behörighetsinställningars';
+$lang['manager'] = 'Administratör -- en grupp eller användare med tillgång till vissa administrativa funktioner.';
+$lang['profileconfirm'] = 'Bekräfta ändringarna i profilen med lösenordet';
+$lang['disableactions'] = 'Stäng av funktioner i DokuWiki';
+$lang['disableactions_check'] = 'Kontroll';
+$lang['disableactions_subscription'] = 'Prenumerera/Säg upp prenumeration';
+$lang['disableactions_wikicode'] = 'Visa källkod/Exportera råtext';
+$lang['disableactions_other'] = 'Andra funktioner (kommaseparerade)';
+$lang['sneaky_index'] = 'Som standard visar DokuWiki alla namnrymder på indexsidan. Genom att aktivera det här valet döljer man namnrymder som användaren inte har behörighet att läsa. Det kan leda till att man döljer åtkomliga undernamnrymder, och gör indexet oanvändbart med vissa ACL-inställningar.';
+$lang['auth_security_timeout'] = 'Autentisieringssäkerhets timeout (sekunder)';
+$lang['securecookie'] = 'Skall cookies som sätts via HTTPS endast skickas via HTTPS från webbläsaren? Avaktivera detta alternativ endast om inloggningen till din wiki är säkrad med SSL men läsning av wikin är osäkrad.';
+$lang['xmlrpc'] = 'Aktivera/avaktivera XML-RPC-gränssnitt';
+$lang['xmlrpcuser'] = 'Begränsa XML-RPC tillträde till komma separerade grupper eller användare som ges här. Lämna tomt för att ge tillgång till alla.';
+$lang['updatecheck'] = 'Kontrollera uppdateringar och säkerhetsvarningar? DokuWiki behöver kontakta update.dokuwiki.org för den här funktionen.';
+$lang['userewrite'] = 'Använd rena webbadresser';
+$lang['useslash'] = 'Använd snedstreck för att separera namnrymder i webbadresser';
+$lang['usedraft'] = 'Spara utkast automatiskt under redigering';
+$lang['sepchar'] = 'Ersätt blanktecken i webbadresser med';
+$lang['canonical'] = 'Använd fullständiga webbadresser';
+$lang['autoplural'] = 'Leta efter pluralformer av länkar';
+$lang['compression'] = 'Metod för komprimering av gamla versioner';
+$lang['cachetime'] = 'Maximal livslängd för cache (sek)';
+$lang['locktime'] = 'Maximal livslängd för fillåsning (sek)';
+$lang['fetchsize'] = 'Maximal storlek (bytes) som fetch.php får ladda ned externt';
+$lang['notify'] = 'Skicka meddelande om ändrade sidor till den här e-postadressen';
+$lang['registernotify'] = 'Skicka meddelande om nyregistrerade användare till en här e-postadressen';
+$lang['mailfrom'] = 'Avsändaradress i automatiska e-postmeddelanden';
+$lang['mailprefix'] = 'Prefix i början på ämnesraden vid automatiska e-postmeddelanden';
+$lang['gzip_output'] = 'Använd gzip Content-Encoding för xhtml';
+$lang['gdlib'] = 'Version av GD-biblioteket';
+$lang['im_convert'] = 'Sökväg till ImageMagicks konverteringsverktyg';
+$lang['jpg_quality'] = 'Kvalitet för JPG-komprimering (0-100)';
+$lang['subscribers'] = 'Aktivera stöd för prenumeration på ändringar';
+$lang['compress'] = 'Komprimera CSS och javascript';
+$lang['hidepages'] = 'Dölj matchande sidor (reguljära uttryck)';
+$lang['send404'] = 'Skicka "HTTP 404/Page Not Found" för sidor som inte finns';
+$lang['sitemap'] = 'Skapa Google sitemap (dagar)';
+$lang['broken_iua'] = 'Är funktionen ignore_user_abort trasig på ditt system? Det kan i så fall leda till att indexering av sökningar inte fungerar. Detta är ett känt problem med IIS+PHP/CGI. Se <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> för mer info.';
+$lang['xsendfile'] = 'Använd X-Sendfile huvudet för att låta webservern leverera statiska filer? Din webserver behöver stöd för detta.';
+$lang['renderer_xhtml'] = 'Generera för användning i huvudwikipresentation (xhtml)';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Tillåt permanenta inloggningscookies (kom ihåg mig)';
+$lang['rss_type'] = 'Typ av XML-flöde';
+$lang['rss_linkto'] = 'XML-flöde pekar på';
+$lang['rss_content'] = 'Vad ska visas för saker i XML-flödet?';
+$lang['rss_update'] = 'Uppdateringsintervall för XML-flöde (sek)';
+$lang['recent_days'] = 'Hur många ändringar som ska sparas (dagar)';
+$lang['rss_show_summary'] = 'XML-flöde visar sammanfattning i rubriken';
+$lang['target____wiki'] = 'Målfönster för interna länkar';
+$lang['target____interwiki'] = 'Målfönster för interwiki-länkar';
+$lang['target____extern'] = 'Målfönster för externa länkar';
+$lang['target____media'] = 'Målfönster för medialänkar';
+$lang['target____windows'] = 'Målfönster för windowslänkar';
+$lang['proxy____host'] = 'Proxyserver';
+$lang['proxy____port'] = 'Proxyport';
+$lang['proxy____user'] = 'Användarnamn för proxy';
+$lang['proxy____pass'] = 'Lösenord för proxy';
+$lang['proxy____ssl'] = 'Använd ssl för anslutning till proxy';
+$lang['safemodehack'] = 'Aktivera safemode hack';
+$lang['ftp____host'] = 'FTP-server för safemode hack';
+$lang['ftp____port'] = 'FTP-port för safemode hack';
+$lang['ftp____user'] = 'FTP-användarnamn för safemode hack';
+$lang['ftp____pass'] = 'FTP-lösenord för safemode hack';
+$lang['ftp____root'] = 'FTP-rotkatalog för safemode hack';
+$lang['license_o_'] = 'Ingen vald';
+$lang['typography_o_0'] = 'Inga';
+$lang['typography_o_1'] = 'enbart dubbla citattecken';
+$lang['typography_o_2'] = 'både dubbla och enkla citattecken (fungerar inte alltid)';
+$lang['userewrite_o_0'] = 'av';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki internt';
+$lang['deaccent_o_0'] = 'av';
+$lang['deaccent_o_1'] = 'ta bort accenter';
+$lang['deaccent_o_2'] = 'romanisera';
+$lang['gdlib_o_0'] = 'GD-bibliotek inte tillgängligt';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Automatisk detektering';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Abstrakt';
+$lang['rss_content_o_diff'] = 'Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML formaterad diff tabell';
+$lang['rss_content_o_html'] = 'Sidans innehåll i full HTML';
+$lang['rss_linkto_o_diff'] = 'lista på skillnader';
+$lang['rss_linkto_o_page'] = 'den reviderade sidan';
+$lang['rss_linkto_o_rev'] = 'lista över ändringar';
+$lang['rss_linkto_o_current'] = 'den aktuella sidan';
+$lang['compression_o_0'] = 'ingen';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'använd ej';
+$lang['xsendfile_o_1'] = 'Proprietär lighttpd-header (före version 1.5)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile-huvud';
+$lang['xsendfile_o_3'] = 'Proprietär Nginx X-Accel-Redirect header';
+$lang['showuseras_o_loginname'] = 'Användarnamn';
+$lang['showuseras_o_username'] = 'Namn';
+$lang['showuseras_o_email'] = 'Användarens e-postadress (obfuskerad enligt inställningarna i mailguard)';
+$lang['showuseras_o_email_link'] = 'Användarens e-postadress som mailto: länk';
+$lang['useheading_o_0'] = 'Aldrig';
+$lang['useheading_o_navigation'] = 'Endst navigering';
+$lang['useheading_o_content'] = 'Endast innehåll i wiki';
+$lang['useheading_o_1'] = 'Alltid';
diff --git a/lib/plugins/config/lang/th/lang.php b/lib/plugins/config/lang/th/lang.php
new file mode 100644
index 000000000..ce7c55e91
--- /dev/null
+++ b/lib/plugins/config/lang/th/lang.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Thai language file
+ *
+ * @author Komgrit Niyomrath <n.komgrit@gmail.com>
+ * @author Kittithat Arnontavilas mrtomyum@gmail.com
+ * @author Arthit Suriyawongkul <arthit@gmail.com>
+ * @author Kittithat Arnontavilas <mrtomyum@gmail.com>
+ * @author Thanasak Sompaisansin <jombthep@gmail.com>
+ */
+$lang['menu'] = 'ตั้งค่าการปรับแต่ง';
+$lang['updated'] = 'การปรับแต่งค่าถูกบันทึกเรียบร้อย';
+$lang['_configuration_manager'] = 'จัดการการปรับตั้งค่า';
+$lang['_header_dokuwiki'] = 'การตั้งค่า DokuWiki';
+$lang['_header_plugin'] = 'การตั้งค่า Plugin';
+$lang['_header_template'] = 'การตั้งค่าเทมเพลต';
+$lang['_basic'] = 'การตั้งค่าพื้นฐาน';
+$lang['_display'] = 'การตั้งค่าการแสดงผล';
+$lang['_authentication'] = 'การตั้งค่าสิทธิ์การเข้าถึง';
+$lang['_anti_spam'] = 'การตั้งค่าป้องกันสแปม';
+$lang['_editing'] = 'การตั้งค่าการแก้ไขปรับปรุง';
+$lang['_links'] = 'การตั้งค่าลิงก์';
+$lang['_media'] = 'การตั้งค่าภาพ-เสียง';
+$lang['_advanced'] = 'การตั้งค่าขั้นสูง';
+$lang['_network'] = 'การตั้งค่าเครือข่าย';
+$lang['_plugin_sufix'] = 'การตั้งค่าโปรแกรมเสริม (plugin)';
+$lang['lang'] = 'ภาษา';
+$lang['basedir'] = 'ไดเรคทอรีพื้นฐาน';
+$lang['baseurl'] = 'URL พื้นฐาน';
+$lang['savedir'] = 'ไดเรคทอรีที่บันทึกข้อมูล';
+$lang['start'] = 'ชื่อหน้าเริ่มต้น';
+$lang['recent'] = 'การเปลี่ยนแปลงล่าสุด';
+$lang['htmlok'] = 'อนุญาตให้ใช้ HTML';
+$lang['phpok'] = 'อนุญาตให้ใช้ PHP';
+$lang['signature'] = 'ลายเซนต์';
+$lang['usewordblock'] = 'คำที่จะถือว่าเป็นสแปม';
+$lang['relnofollow'] = 'ใช้ rel="nofollow" สำหรับลิงก์ภายนอก';
+$lang['autopasswd'] = 'สร้างรหัสผ่านให้อัตโนมัติ';
+$lang['passcrypt'] = 'กระบวนการเข้ารหัส สำหรับเก็บบันทึกรหัสผ่าน';
+$lang['defaultgroup'] = 'กลุ่มมาตรฐาน';
+$lang['profileconfirm'] = 'ใส่รหัสผ่านเพื่อยืนยันการเปลี่ยนแปลงข้อมูล';
+$lang['disableactions_check'] = 'ตรวจสอบ';
+$lang['auth_security_timeout'] = 'ระยะเวลาที่จะตัดการเชื่อมต่อแบบการใช้งานด้วยสิทธิ์ผู้ใช้ (วินาที)';
+$lang['xmlrpc'] = 'ใช้งาน/ยกเลิก การเชื่อมต่อแบบ XML-RPC';
+$lang['userewrite'] = 'แสดงที่อยู่เว็บ (URL) แบบอ่านเข้าใจง่าย';
+$lang['cachetime'] = 'ระยะเวลาสำหรับการเก็บแคช (วินาที)';
+$lang['locktime'] = 'ระยะเวลานานสุด ที่จะล็อคไม่ให้แก้ไขไฟล์ (วินาที)';
+$lang['fetchsize'] = 'ขนาดไฟล์ใหญ่สุด (bytes) fetch.php ที่จะดาวน์โหลดจากภายนอก';
+$lang['notify'] = 'ส่งการแจ้งเตือนไปยังที่อยู่อีเมลนี้';
+$lang['gzip_output'] = 'ใช้ gzip Content-Encoding สำหรับ xhtml';
+$lang['gdlib'] = 'เลขรุ่นของ GD Library';
+$lang['compress'] = 'บีบย่อ CSS และ javascript (เพื่อให้แสดงหน้าเว็บเร็วขึ้น)';
+$lang['hidepages'] = 'ซ่อนหน้าที่เข้ากันได้ (regular expressions)';
+$lang['send404'] = 'ให้แสดง "HTTP 404/Page Not Found" เมื่อไม่พบข้อมูลหน้านั้น';
+$lang['sitemap'] = 'สร้าง กูเกิ้ล ไซต์แมพ (จำนวนวัน)';
+$lang['renderer__core'] = '%s (แกนหลักของ dokuwiki)';
+$lang['renderer__plugin'] = '%s (โปรแกรมเสริม - plugin)';
+$lang['rememberme'] = 'อนุญาตให้จดจำการ login แบบถาวร';
+$lang['rss_type'] = 'ชนิดของ XML feed';
+$lang['rss_linkto'] = 'ลิงก์เชื่อมโยงไปยัง XML feed';
+$lang['rss_content'] = 'ต้องการให้มีอะไรแสดงอยู่ใน XML feed บ้าง?';
+$lang['rss_update'] = 'ความถี่ในการอัพเดท XML feed (เป็นวินาที)';
+$lang['recent_days'] = 'จำนวนวันที่เก็บรายการที่ถูกแก้ไขล่าสุด';
+$lang['rss_show_summary'] = 'ไตเติ้ลของบทสรุปย่อของ XML feed';
+$lang['target____wiki'] = 'เปิดแสดงลิงก์ภายใน ในหน้าเว็บแบบใด';
+$lang['target____interwiki'] = 'เปิดแสดงลิงก์ interwiki ในหน้าเว็บแบบใด';
+$lang['target____extern'] = 'เปิดแสดงลิงก์ภายนอก ในหน้าเว็บแบบใด';
+$lang['target____media'] = 'เปิดแสดงลิงก์ของมีเดีย ในหน้าเว็บแบบใด';
+$lang['target____windows'] = 'เปิดแสดงลิงก์ของวินโดวส์ ในหน้าเว็บแบบใด';
+$lang['proxy____host'] = 'ชื่อ server ของ proxy';
+$lang['proxy____port'] = 'port ของ proxy';
+$lang['proxy____user'] = 'user name ของ proxy';
+$lang['proxy____pass'] = 'รหัสผ่านของ proxy';
+$lang['proxy____ssl'] = 'ใช้ ssl ในการเชื่อมต่อกับ proxy';
+$lang['license_o_'] = 'ไม่ถูกเลือก';
+$lang['typography_o_0'] = 'ไม่มี';
+$lang['typography_o_1'] = 'ไม่รวมเครื่องหมายอัญประกาศเดี่ยว';
+$lang['typography_o_2'] = 'รวมเครื่องหมายอัญประกาศเดี่ยว (อาจใช้ไม่ได้ในบางครั้ง)';
+$lang['userewrite_o_0'] = 'ไม่มี';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['deaccent_o_0'] = 'ปิด';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'ตรวจสอบอัตโนมัติ';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'บทคัดย่อ';
+$lang['rss_content_o_html'] = 'หน้าเนื้อหาแบบแสดง HTML เต็มรูปแบบ';
+$lang['rss_linkto_o_diff'] = 'มุมมองที่แตกต่าง';
+$lang['rss_linkto_o_rev'] = 'รายการของการปรับแก้ไข';
+$lang['rss_linkto_o_current'] = 'หน้าปัจจุบัน';
+$lang['compression_o_0'] = 'ไม่มีการบีบอัด';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ไม่ใช้';
+$lang['xsendfile_o_2'] = 'หัวเอกสารแบบ Standard X-Sendfile';
+$lang['xsendfile_o_3'] = 'หัวเอกสารแบบ Proprietary Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'ชื่อผู้ใช้';
+$lang['showuseras_o_username'] = 'ชื่อ-นามสกุล';
+$lang['showuseras_o_email_link'] = 'อีเมลของผู้ใช้ ที่จะปรากฏ ณ mailto: link';
+$lang['useheading_o_0'] = 'ไม่เลย';
+$lang['useheading_o_navigation'] = 'เฉพาะตัวนำทาง';
+$lang['useheading_o_content'] = 'เฉพาะเนื้อหาวิกิ';
+$lang['useheading_o_1'] = 'เสมอ';
diff --git a/lib/plugins/config/lang/tr/intro.txt b/lib/plugins/config/lang/tr/intro.txt
new file mode 100644
index 000000000..4a9654222
--- /dev/null
+++ b/lib/plugins/config/lang/tr/intro.txt
@@ -0,0 +1,7 @@
+====== Site Ayarları Yönetimi ======
+
+Bu sayfayı DokuWiki kurulumunun ayarlarını değiştirmek için kullanabilirsiniz. Ayarların ayrıntıları için [[doku>config]] sayfasını kullanınız. Bu eklenti ile ilgili daha ayrıntılı bilgi için [[doku>plugin:config]] sayfasına bakınız.
+
+Açık kırmızı renkle gösterilenler bu eklenti ile değiştirilemez. Mavi ile gösterilenler varsayılan değerlerdir. Beyaz altyazı ile gösterilenler is bu kuruluma özel değiştirilmiş ayarlardır. Mavi ve beyaz ayarlar değiştirilebilir.
+
+Değişiklik yapmanız durumunda **Kaydet** tuşuna basmayı unutmayınız. Aksi takdirde sayfayı kapattığınızda tüm ayarlar silinecektir. \ No newline at end of file
diff --git a/lib/plugins/config/lang/tr/lang.php b/lib/plugins/config/lang/tr/lang.php
new file mode 100644
index 000000000..6d7d7cc2e
--- /dev/null
+++ b/lib/plugins/config/lang/tr/lang.php
@@ -0,0 +1,135 @@
+<?php
+/**
+ * Turkish language file
+ *
+ * @author Aydın Coşkuner <aydinweb@gmail.com>
+ * @author Cihan Kahveci <kahvecicihan@gmail.com>
+ * @author Yavuz Selim <yavuzselim@gmail.com>
+ * @author Caleb Maclennan <caleb@alerque.com>
+ */
+$lang['menu'] = 'Site Ayarları';
+$lang['error'] = 'Ayarlar yanlış bir değer girildiği için güncellenemedi. Lütfen değişikliklerinizi gözden geçirin ve tekrar gönderin.
+<br />Yanlış değer(ler) kırmızı çerçeve içinde gösterilecektir.';
+$lang['updated'] = 'Ayarlar başarıyla güncellendi.';
+$lang['nochoice'] = '(başka seçim bulunmamaktadır)';
+$lang['locked'] = 'Ayar dosyası güncellenemedi. <br />
+dosya adı ve yetkilerininin doğru olduğuna emin olun.';
+$lang['danger'] = 'Tehlike: Bu özelliği değiştirirseniz, wiki\'nize ve konfigürasyon menunüze ulaşamayabilirsiniz.';
+$lang['warning'] = 'Uyarı: Bu özelliği değiştirmek istenmeyen davranışa sebep olabilir.';
+$lang['security'] = 'Güvenlik Uyarısı: Bu özelliği değiştirmek güvenlik riski çıkartabilir.';
+$lang['_configuration_manager'] = 'Site Ayarları Yönetimi';
+$lang['_header_dokuwiki'] = 'DokuWiki Ayarları';
+$lang['_header_plugin'] = 'Eklenti Ayarları';
+$lang['_header_template'] = 'Şablon (Template) Ayarları';
+$lang['_header_undefined'] = 'Tanımsız Ayarlar';
+$lang['_basic'] = 'Ana Ayarlar';
+$lang['_display'] = 'Gösterim Ayarları';
+$lang['_authentication'] = 'Onaylama Ayarları';
+$lang['_anti_spam'] = 'Spam Engelleme Ayarları';
+$lang['_editing'] = 'Sayfa Yazımı Ayarları';
+$lang['_links'] = 'Bağlantı Ayarları';
+$lang['_media'] = 'Medya Ayarları';
+$lang['_advanced'] = 'Gelişmiş Ayarlar';
+$lang['_network'] = 'Ağ Ayarları';
+$lang['_plugin_sufix'] = 'Eklenti Ayarları';
+$lang['_template_sufix'] = 'Şablon (Template) Ayarları';
+$lang['_msg_setting_undefined'] = 'Ayar üstverisi yok.';
+$lang['_msg_setting_no_class'] = 'Ayar sınıfı yok.';
+$lang['_msg_setting_no_default'] = 'Varsayılan değer yok.';
+$lang['fmode'] = 'Dosya oluşturma yetkisi';
+$lang['dmode'] = 'Klasör oluşturma yetkisi';
+$lang['lang'] = 'Dil';
+$lang['basedir'] = 'Kök dizin';
+$lang['baseurl'] = 'Kök URL';
+$lang['savedir'] = 'Verileri kaydetmek için kullanılacak klasör';
+$lang['start'] = 'Ana sayfa adı';
+$lang['title'] = 'Wiki başlığı';
+$lang['template'] = 'Şablon (Template)';
+$lang['license'] = 'İçeriğinizi hangi lisans altında yayınlansın?';
+$lang['fullpath'] = 'sayfaların tüm patikasını (full path) göster';
+$lang['recent'] = 'En son değiştirilenler';
+$lang['breadcrumbs'] = 'Ekmek kırıntıların sayısı';
+$lang['youarehere'] = 'hiyerarşik ekmek kırıntıları';
+$lang['typography'] = 'Tipografik değiştirmeleri yap';
+$lang['htmlok'] = 'Gömülü HTML koduna izin ver';
+$lang['phpok'] = 'Gömülü PHP koduna izin ver';
+$lang['dformat'] = 'Tarih biçimi (PHP\'nin <a href="http://www.php.net/strftime">strftime</a> fonksiyonuna bakın)';
+$lang['signature'] = 'İmza';
+$lang['toptoclevel'] = 'İçindekiler için en üst seviye';
+$lang['tocminheads'] = 'İçindekilerin oluşturulması için gereken (en az) başlık sayısı';
+$lang['maxtoclevel'] = 'İçindekiler için en fazla seviye';
+$lang['maxseclevel'] = 'Bölümün azami düzenleme düzeyi';
+$lang['camelcase'] = 'Linkler için CamelCase kullan';
+$lang['deaccent'] = 'Sayfa adlarınız temizle';
+$lang['useheading'] = 'Sayfa isimleri için ilk başlığı kullan';
+$lang['refcheck'] = 'Araç kaynak denetimi';
+$lang['refshow'] = 'Gösterilecek araç kaynağı sayısı';
+$lang['allowdebug'] = 'Yanlış ayıklamasına izin ver <b>lazım değilse etkisiz kıl!</b>';
+$lang['usewordblock'] = 'Wordlistesine göre spam engelle';
+$lang['indexdelay'] = 'Indekslemeden evvel zaman gecikmesi (saniye)';
+$lang['relnofollow'] = 'Dışsal linkler rel="nofollow" kullan';
+$lang['mailguard'] = 'Email adreslerini karart';
+$lang['iexssprotect'] = 'Yüklenmiş dosyaları muhtemel kötu niyetli JavaScript veya HTML koduna kontrol et';
+$lang['showuseras'] = 'Bir sayfayı en son düzenleyen kullanıcıya ne gösterilsin';
+$lang['useacl'] = 'Erişim kontrol listesini kullan';
+$lang['autopasswd'] = 'Parolaları otamatikmen üret';
+$lang['authtype'] = 'Kimlik denetleme arka uç';
+$lang['passcrypt'] = 'Parola şifreleme metodu';
+$lang['defaultgroup'] = 'Varsayılan grup';
+$lang['disableactions'] = 'DokuWiki eylemlerini etkisiz kıl';
+$lang['disableactions_check'] = 'Kontrol et';
+$lang['disableactions_subscription'] = 'Abone ol/Abonelikten vazgeç';
+$lang['canonical'] = 'Tamolarak kurallara uygun URL\'leri kullan';
+$lang['mailfrom'] = 'Otomatik e-postalar için kullanılacak e-posta adresi';
+$lang['gdlib'] = 'GD Lib sürümü';
+$lang['jpg_quality'] = 'JPG sıkıştırma kalitesi [0-100]';
+$lang['sitemap'] = 'Google site haritası oluştur (gün)';
+$lang['renderer__core'] = '%s (dokuwiki çekirdeği)';
+$lang['renderer__plugin'] = '%s (eklenti)';
+$lang['rss_content'] = 'XML beslemesinde ne gösterilsin?';
+$lang['rss_update'] = 'XML beslemesini güncelleme aralığı';
+$lang['rss_show_summary'] = 'XML beslemesinde özeti başlıkta göster';
+$lang['proxy____host'] = 'Proxy sunucu adı';
+$lang['proxy____user'] = 'Proxy kullanıcı adı';
+$lang['proxy____pass'] = 'Proxy şifresi';
+$lang['proxy____ssl'] = 'Proxy ile bağlanırken ssl kullan';
+$lang['safemodehack'] = 'Safemod hackını etkili kıl';
+$lang['ftp____host'] = 'Safemod hackı için kullanılacak FTP suncusu';
+$lang['ftp____user'] = 'Safemod hackı için kullanılacak FTP kullanıcı adı';
+$lang['ftp____pass'] = 'Safemod hackı için kullanılacak FTP parolası';
+$lang['license_o_'] = 'Seçilmedi';
+$lang['typography_o_0'] = 'Yok';
+$lang['userewrite_o_0'] = 'hiçbiri';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki dahili';
+$lang['deaccent_o_0'] = 'Kapalı';
+$lang['deaccent_o_1'] = 'aksan işaretlerini kaldır';
+$lang['deaccent_o_2'] = 'roman harfleri kullan';
+$lang['gdlib_o_0'] = 'GD Lib mevcut değil';
+$lang['gdlib_o_1'] = 'Versiyon 1.x';
+$lang['gdlib_o_2'] = 'Otomatik tesbit';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Soyut';
+$lang['rss_content_o_diff'] = 'Birleştirilmiş Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML biçimlendirilmiş diff tablosu';
+$lang['rss_content_o_html'] = 'Tüm HTML sayfa içeriği';
+$lang['rss_linkto_o_diff'] = 'görünümü değiştir';
+$lang['rss_linkto_o_page'] = 'gözden geçirilmiş sayfa';
+$lang['rss_linkto_o_rev'] = 'sürümlerin listesi';
+$lang['rss_linkto_o_current'] = 'Șu anki sayfa';
+$lang['compression_o_0'] = 'hiçbiri';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'kullanma';
+$lang['showuseras_o_loginname'] = 'Kullanıcı adı';
+$lang['showuseras_o_username'] = 'Kullanıcının tam adı';
+$lang['showuseras_o_email'] = 'Kullanıcının mail adresi (mailguard ayarlarına göre karartılıyor)';
+$lang['showuseras_o_email_link'] = 'Kullanıcının mail adresi mailto: linki şeklinde';
+$lang['useheading_o_0'] = 'Hiçbir zaman';
+$lang['useheading_o_navigation'] = 'Sadece Navigasyon';
+$lang['useheading_o_content'] = 'Sadece Wiki içeriği';
+$lang['useheading_o_1'] = 'Her zaman';
diff --git a/lib/plugins/config/lang/uk/intro.txt b/lib/plugins/config/lang/uk/intro.txt
new file mode 100644
index 000000000..7255c30f9
--- /dev/null
+++ b/lib/plugins/config/lang/uk/intro.txt
@@ -0,0 +1,7 @@
+====== Настройка конфігурації ======
+
+Використовуйте цю сторінку для настройки ДокуВікі. Для довідок щодо конкретних параметрів дивіться [[doku>config]]. Для більш детальної інформації про цей доданок дивіться [[doku>plugin:config]].
+
+Параметри, що виділені червоним кольором тла захищені та не можуть бути змінені за допомогою цього доданка. Параметри, з синім кольором тла мають значення по замовчуванню, а параметри з білим тлом були встановлені для цієї локальної інсталяції. Сині та білі параметри можуть бути змінені.
+
+Не забувайте натискати кнопку **ЗБЕРЕГТИ** до того, як покинути цю сторінку, інакше всі зміни буде втрачено.
diff --git a/lib/plugins/config/lang/uk/lang.php b/lib/plugins/config/lang/uk/lang.php
new file mode 100644
index 000000000..72d7e12f5
--- /dev/null
+++ b/lib/plugins/config/lang/uk/lang.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * ukrainian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Oleksiy Voronin <ovoronin@gmail.com>
+ * @author serg_stetsuk@ukr.net
+ * @author okunia@gmail.com
+ * @author Oleksandr Kunytsia <okunia@gmail.com>
+ * @author Uko uko@uar.net
+ * @author Ulrikhe Lukoie <lukoie@gmail>.com
+ * @author Kate Arzamastseva pshns@ukr.net
+ */
+$lang['menu'] = 'Настройка конфігурації';
+$lang['error'] = 'Параметри не збережено через помилкові значення. Будь ласка, перегляньте ваші зміни та спробуйте ще раз
+<br />Помилкові значення будуть виділені червоною рамкою.';
+$lang['updated'] = 'Параметри успішно збережено.';
+$lang['nochoice'] = '(інших варіантів не існує)';
+$lang['locked'] = 'Неможливо записати файл настройки. Переконайтеся, <br />
+що ім\'я та права доступу для локального файлу вказано правильно.';
+$lang['danger'] = 'УВАГА! Зміна цього параметру може призвести до недоступності вашої Вікі та меню конфігурації.';
+$lang['warning'] = 'УВАГА! Зміна цього параметру може призвести до непередбачуваних наслідків.';
+$lang['security'] = 'УВАГА! Зміна цього параметру може призвести до послаблення безпеки вашої Вікі.';
+$lang['_configuration_manager'] = 'Управління конфігурацією';
+$lang['_header_dokuwiki'] = 'Настройки ДокуВікі';
+$lang['_header_plugin'] = 'Настройки Доданків';
+$lang['_header_template'] = 'Настройки шаблонів';
+$lang['_header_undefined'] = 'Невизначені настройки';
+$lang['_basic'] = 'Базові настройки';
+$lang['_display'] = 'Настройки дисплея';
+$lang['_authentication'] = 'Настройки автентифікації';
+$lang['_anti_spam'] = 'Настройки Анти-спаму';
+$lang['_editing'] = 'Настройки редагування';
+$lang['_links'] = 'Настройки посилань';
+$lang['_media'] = 'Настройки медіа';
+$lang['_advanced'] = 'Розширені настройки';
+$lang['_network'] = 'Настройки мережі';
+$lang['_plugin_sufix'] = 'Настройки (доданок)';
+$lang['_template_sufix'] = 'Настройки (шаблон)';
+$lang['_msg_setting_undefined'] = 'Немає метаданих параметру.';
+$lang['_msg_setting_no_class'] = 'Немає класу параметру.';
+$lang['_msg_setting_no_default'] = 'Немає значення за замовчуванням.';
+$lang['fmode'] = 'Права для створених файлів';
+$lang['dmode'] = 'Права для створених папок';
+$lang['lang'] = 'Мова';
+$lang['basedir'] = 'Коренева папка';
+$lang['baseurl'] = 'Кореневий URL';
+$lang['savedir'] = 'Папка для збереження даних';
+$lang['start'] = 'Назва стартової сторінки';
+$lang['title'] = 'Назва Вікі';
+$lang['template'] = 'Шаблон';
+$lang['license'] = 'Під якою ліцензією слід публікувати вміст?';
+$lang['fullpath'] = 'Повний шлях до документу';
+$lang['recent'] = 'Останні зміни';
+$lang['breadcrumbs'] = 'Ви відвідали (кількість сторінок, що показується)';
+$lang['youarehere'] = 'Показувати "Ви тут"';
+$lang['typography'] = 'Замінювати типографські символи';
+$lang['htmlok'] = 'Дозволити HTML';
+$lang['phpok'] = 'Дозволити PHP';
+$lang['dformat'] = 'Формат дати (дивіться функцію <a href="http://www.php.net/strftime">strftime</a> PHP)';
+$lang['signature'] = 'Підпис';
+$lang['toptoclevel'] = 'Мінімальний рівень для змісту';
+$lang['tocminheads'] = 'Мінімальна кількість заголовків, необхідна для створення таблиці змісту';
+$lang['maxtoclevel'] = 'Максимальний рівень для таблиці змісту';
+$lang['maxseclevel'] = 'Максимальний рівень секції для редагування';
+$lang['camelcase'] = 'Використовувати CamelCase';
+$lang['deaccent'] = 'Транслітерація в іменах сторінок';
+$lang['useheading'] = 'Першій заголовок замість імені';
+$lang['refcheck'] = 'Перевіряти посилання на медіа-файлі';
+$lang['refshow'] = 'Показувати кількість медіа-посилань';
+$lang['allowdebug'] = 'Дозволити відлагодження <b>вимкніть, якщо не потрібно!</b>';
+$lang['usewordblock'] = 'Блокувати спам по списку слів';
+$lang['indexdelay'] = 'Затримка перед індексацією';
+$lang['relnofollow'] = 'Використовувати rel="nofollow"';
+$lang['mailguard'] = 'Кодувати адреси e-mail';
+$lang['iexssprotect'] = 'Перевірте оновлені файли на можливі заборонені Javascript чи HTML коди';
+$lang['showuseras'] = 'Що вказувати при відображенні користувача, який востаннє редагував сторінку';
+$lang['useacl'] = 'Використовувати ACL';
+$lang['autopasswd'] = 'Автоматичне створення паролів';
+$lang['authtype'] = 'Аутентифікація';
+$lang['passcrypt'] = 'Метод шифрування паролів';
+$lang['defaultgroup'] = 'Група за замовчуванням';
+$lang['superuser'] = 'Суперкористувач';
+$lang['manager'] = 'Менеджер - група, користувач чи розділений комами список user1,@group1,user2 з правами до певних функцій керування';
+$lang['profileconfirm'] = 'Підтверджувати зміни профілю паролем';
+$lang['disableactions'] = 'Заборонити дії ДокуВікі';
+$lang['disableactions_check'] = 'Перевірити';
+$lang['disableactions_subscription'] = 'Підписатись/Відписатись';
+$lang['disableactions_wikicode'] = 'Переглянути код/Експорт';
+$lang['disableactions_other'] = 'Інші дії (розділені комами)';
+$lang['sneaky_index'] = 'За замовчуванням, ДокуВікі показує всі простори імен в змісті. Активація цієї опції сховає ті простори, де користувач не має прав на читання. Результатом може бути неможливість доступу до певних відкритих просторів імен. Це зробить неможливим використання змісту при певних конфігураціях.';
+$lang['auth_security_timeout'] = 'Таймаут аутентифікації (в секундах)';
+$lang['securecookie'] = 'Чи повинен браузер надсилати файли cookies тільки через HTTPS? Вимкніть цей параметр, лише тоді, якщо вхід до Вікі захищено SSL, але перегляд сторінок відбувається у незахищеному режимі.';
+$lang['xmlrpc'] = 'Дозволити/заборонити XML-RPC інтерфейс';
+$lang['xmlrpcuser'] = 'Заборонити XML-RPC доступ до користувачів або груп поданих тут та розділених комою. Залишіть поле незаповненим, щоб дозволити доступ усім.';
+$lang['updatecheck'] = 'Перевірити наявність оновлень чи попереджень безпеки? Для цього ДокуВікі необхідно зв\'язатися зі update.dokuwiki.org.';
+$lang['userewrite'] = 'Красиві URL';
+$lang['useslash'] = 'Слеш, як розділювач просторів імен в URL';
+$lang['usedraft'] = 'Автоматично зберігати чернетку при редагуванні';
+$lang['sepchar'] = 'Розділювач слів у імені сторінки';
+$lang['canonical'] = 'Канонічні URL';
+$lang['fnencode'] = 'Метод для кодування імен файлів, що містять не ASCII символи.';
+$lang['autoplural'] = 'Перевіряти множину у посиланнях';
+$lang['compression'] = 'Метод стиснення attic файлів';
+$lang['cachetime'] = 'Максимальний вік кешу (сек)';
+$lang['locktime'] = 'Час блокування (сек)';
+$lang['fetchsize'] = 'Максимальний розмір (в байтах), що fetch.php може завантажувати з зовні';
+$lang['notify'] = 'E-mail для сповіщень';
+$lang['registernotify'] = 'Надсилати інформацію про нових користувачів на цю адресу';
+$lang['mailfrom'] = 'E-mail для автоматичних повідомлень';
+$lang['mailprefix'] = 'Префікс теми повідомлення, що використовується в автоматичній розсилці електронних листів';
+$lang['gzip_output'] = 'Використовувати gzip, як Content-Encoding для xhtml';
+$lang['gdlib'] = 'Версія GD Lib';
+$lang['im_convert'] = 'Шлях до ImageMagick';
+$lang['jpg_quality'] = 'Якість компресії JPG (0-100)';
+$lang['subscribers'] = 'Підписка на зміни';
+$lang['subscribe_time'] = 'Час, після якого список підписки та дайджести будуть надіслані (сек.); Має бути меншим за час, вказаний у перемінній recent_days';
+$lang['compress'] = 'Стискати файли CSS та javascript';
+$lang['hidepages'] = 'Ховати сторінки (regular expressions)';
+$lang['send404'] = 'Надсилати "HTTP 404/Сторінка не знайдена " для неіснуючих сторінок';
+$lang['sitemap'] = 'Створювати мапу сайту для Google (дні)';
+$lang['broken_iua'] = 'У вашій системі зіпсована функція ignore_user_abort? Це може зіпсувати пошукову систему. IIS+PHP/CGI не працює. Дивіться <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> для отримання додаткової інформації';
+$lang['xsendfile'] = 'Використовувати заголовок X-Sendfile для доставки статичних файлів веб сервером? Ваш веб сервер повинен підтримувати цю функцію.';
+$lang['renderer_xhtml'] = 'Транслятор (Renderer) для основного виводу wiki (xhtml)';
+$lang['renderer__core'] = '%s (ядро докуВікі)';
+$lang['renderer__plugin'] = '%s (доданок)';
+$lang['rememberme'] = 'Дозволити постійні файли cookies для входу (Запам\'ятати мене)';
+$lang['rss_type'] = 'тип RSS';
+$lang['rss_linkto'] = 'посилання в RSS';
+$lang['rss_content'] = 'Що відображати в пунктах XML-feed';
+$lang['rss_update'] = 'Інтервал оновлення RSS (сек)';
+$lang['recent_days'] = 'Скільки останніх змін пам\'ятати (дні)';
+$lang['rss_show_summary'] = 'Показувати підсумки змін в заголовку XML-feed';
+$lang['target____wiki'] = 'Target для внутрішніх посилань';
+$lang['target____interwiki'] = 'Target для інтерВікі-посилань';
+$lang['target____extern'] = 'Target для зовнішніх посилань';
+$lang['target____media'] = 'Target для медіа-посилань';
+$lang['target____windows'] = 'Target для посилань на мережеві папки';
+$lang['proxy____host'] = 'Адреса Proxy';
+$lang['proxy____port'] = 'Порт Proxy';
+$lang['proxy____user'] = 'Користувач Proxy';
+$lang['proxy____pass'] = 'Пароль Proxy';
+$lang['proxy____ssl'] = 'Використовувати ssl для з\'єднання з Proxy';
+$lang['proxy____except'] = 'Регулярний вираз для веб-адреси, яку проксі-сервер пропустить.';
+$lang['safemodehack'] = 'Увімкнути хак safemode';
+$lang['ftp____host'] = 'FTP-сервер для хаку safemode';
+$lang['ftp____port'] = 'FTP-порт для хаку safemode';
+$lang['ftp____user'] = 'Користувач FTP для хаку safemode';
+$lang['ftp____pass'] = 'Пароль FTP для хаку safemode';
+$lang['ftp____root'] = 'Коренева папка FTP для хаку safemode';
+$lang['license_o_'] = 'не вибрано';
+$lang['typography_o_0'] = 'жодного';
+$lang['typography_o_1'] = 'Лише подвійні лапки';
+$lang['typography_o_2'] = 'Всі лапки (може не завжди працювати)';
+$lang['userewrite_o_0'] = 'немає';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Засобами ДокуВікі';
+$lang['deaccent_o_0'] = 'вимкнено';
+$lang['deaccent_o_1'] = 'вилучати діакритичні знаки';
+$lang['deaccent_o_2'] = 'транслітерація';
+$lang['gdlib_o_0'] = 'GD Lib не доступна';
+$lang['gdlib_o_1'] = 'Версія 1.x';
+$lang['gdlib_o_2'] = 'Автовизначення';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = 'Короткий зміст';
+$lang['rss_content_o_diff'] = 'Уніфіковані зміни (diff)';
+$lang['rss_content_o_htmldiff'] = 'Таблиця змін у форматі HTML';
+$lang['rss_content_o_html'] = 'Повний зміст сторінки HTML';
+$lang['rss_linkto_o_diff'] = 'перегляд відмінностей';
+$lang['rss_linkto_o_page'] = 'текст сторінки';
+$lang['rss_linkto_o_rev'] = 'перелік ревізій';
+$lang['rss_linkto_o_current'] = 'поточна сторінка';
+$lang['compression_o_0'] = 'немає';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'не використовувати';
+$lang['xsendfile_o_1'] = 'Фірмовий заголовок lighthttpd (до версії 1.5)';
+$lang['xsendfile_o_2'] = 'Стандартний X-Sendfile заголовок';
+$lang['xsendfile_o_3'] = 'Фірмовий заголовок Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Логін';
+$lang['showuseras_o_username'] = 'Повне ім’я користувача';
+$lang['showuseras_o_email'] = 'E-mail користувача (прихована відповідно до настройок)';
+$lang['showuseras_o_email_link'] = 'E-mail користувача як посилання mailto:';
+$lang['useheading_o_0'] = 'Ніколи';
+$lang['useheading_o_navigation'] = 'Лише для навігації';
+$lang['useheading_o_content'] = 'Лише у змісті';
+$lang['useheading_o_1'] = 'Завжди';
+$lang['readdircache'] = 'Максимальний вік для файлів кешу (сек.)';
diff --git a/lib/plugins/config/lang/zh-tw/intro.txt b/lib/plugins/config/lang/zh-tw/intro.txt
new file mode 100644
index 000000000..c257947d9
--- /dev/null
+++ b/lib/plugins/config/lang/zh-tw/intro.txt
@@ -0,0 +1,7 @@
+====== 配置管理器 ======
+
+使用本頁控制您的 Dokuwiki 設定。每個獨立設定的相關訊息可參閱 [[doku>config]]。配置管理器的更多訊息請參閱 [[doku>plugin:config]]。
+
+淡紅色背景的項目是被保護的,不能通過這個管理器更改。藍色背景的項目是系統的預設值,白色背景的項目是您更改過的。藍色和白色的設定項目都可以更改。
+
+離開本頁之前不要忘記點擊最下面的 **儲存** 按鈕,否則您的修改將不會生效。
diff --git a/lib/plugins/config/lang/zh-tw/lang.php b/lib/plugins/config/lang/zh-tw/lang.php
new file mode 100644
index 000000000..4f44eb60d
--- /dev/null
+++ b/lib/plugins/config/lang/zh-tw/lang.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * Chinese Traditional language file
+ *
+ * @author Li-Jiun Huang <ljhuang.tw@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-simptrad.html
+ * @author Wayne San <waynesan@zerozone.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmai.com>
+ * @author Cheng-Wei Chien <e.cwchien@gmail.com>
+ * @author Danny Lin
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '系統配置設定';
+$lang['error'] = '設定因為不合法的值而未更新,請檢查您的更改並重新送出。
+<br />不正確的值會被紅色方框包住。';
+$lang['updated'] = '成功地更新設定。';
+$lang['nochoice'] = '(無其他可用選項)';
+$lang['locked'] = '設定檔無法更新,若非故意,請確認本地檔名及權限正確。';
+$lang['danger'] = '危險:改變此選項可能使您無法存取維基及配置選單。';
+$lang['warning'] = '警告:改變此選項可能導致不可預期的行為。';
+$lang['security'] = '安全性警告:改變此選項可能造成安全風險。';
+$lang['_configuration_manager'] = '配置管理';
+$lang['_header_dokuwiki'] = 'DokuWiki 設定';
+$lang['_header_plugin'] = '插件設定';
+$lang['_header_template'] = '樣板設定';
+$lang['_header_undefined'] = '未定義設定';
+$lang['_basic'] = '基本設定';
+$lang['_display'] = '顯示設定';
+$lang['_authentication'] = '認證設定';
+$lang['_anti_spam'] = '反垃圾設定';
+$lang['_editing'] = '編輯設定';
+$lang['_links'] = '連結設定';
+$lang['_media'] = '媒體設定';
+$lang['_advanced'] = '進階設定';
+$lang['_network'] = '網路設定';
+$lang['_plugin_sufix'] = '插件設定';
+$lang['_template_sufix'] = '樣板設定';
+$lang['_msg_setting_undefined'] = '設定的後設數據不存在。';
+$lang['_msg_setting_no_class'] = '設定的分類不存在。';
+$lang['_msg_setting_no_default'] = '無預設值';
+$lang['fmode'] = '檔案建立模式';
+$lang['dmode'] = '目錄建立模式';
+$lang['lang'] = '語系';
+$lang['basedir'] = '根目錄';
+$lang['baseurl'] = '根路徑 (URL)';
+$lang['savedir'] = '儲存資料的目錄';
+$lang['cookiedir'] = 'Cookie 路徑。設定空白則使用 baseurl。';
+$lang['start'] = '開始頁面的名稱';
+$lang['title'] = '維基標題';
+$lang['template'] = '樣板';
+$lang['license'] = '您希望您的內容為何種授權方式?';
+$lang['fullpath'] = '顯示完整的路徑於頁面底部';
+$lang['recent'] = '最近更新';
+$lang['breadcrumbs'] = '導覽鏈數量';
+$lang['youarehere'] = '顯示階層式導覽鏈';
+$lang['typography'] = '進行字元替換';
+$lang['htmlok'] = '允許嵌入式 HTML';
+$lang['phpok'] = '允許嵌入式 PHP';
+$lang['dformat'] = '日期格式 (參見 PHP 的 <a href="http://www.php.net/strftime">strftime</a> 函數)';
+$lang['signature'] = '簽名';
+$lang['toptoclevel'] = '目錄表的最上層級';
+$lang['tocminheads'] = '決定是否建立目錄表的最少標題數量';
+$lang['maxtoclevel'] = '目錄表顯示的最大層級';
+$lang['maxseclevel'] = '可編輯段落的最大層級';
+$lang['camelcase'] = '對連結使用 CamelCase';
+$lang['deaccent'] = '清理頁面名稱';
+$lang['useheading'] = '使用第一個標題作為頁面名稱';
+$lang['refcheck'] = '媒體連結檢查';
+$lang['refshow'] = '媒體連結的顯示數量';
+$lang['allowdebug'] = '允許除錯 <b>(不需要請停用!)</b>';
+$lang['usewordblock'] = '根據字詞表阻擋垃圾訊息';
+$lang['indexdelay'] = '建立索引前的延遲時間 (秒)';
+$lang['relnofollow'] = '外部連結使用 rel="nofollow"';
+$lang['mailguard'] = '混淆 E-mail 位址';
+$lang['iexssprotect'] = '檢查上傳的檔案中是否隱含惡意的 JavaScript 或 HTML 碼';
+$lang['showuseras'] = '將最後編輯頁面的使用者顯示為:';
+$lang['useacl'] = '使用存取控制名單';
+$lang['autopasswd'] = '自動產生密碼';
+$lang['authtype'] = '認證後台管理方式';
+$lang['passcrypt'] = '密碼加密方式';
+$lang['defaultgroup'] = '預設群組';
+$lang['superuser'] = '超級用戶 - 不論 ACL 如何設定,都能訪問所有頁面與功能的用戶組/用戶';
+$lang['manager'] = '管理員 - 能訪問相應管理功能的用戶组/用戶';
+$lang['profileconfirm'] = '修改個人資料時需要確認密碼';
+$lang['disableactions'] = '停用的 DokuWiki 動作';
+$lang['disableactions_check'] = '檢查';
+$lang['disableactions_subscription'] = '訂閱/取消訂閱';
+$lang['disableactions_wikicode'] = '檢視原始碼/匯出原始檔';
+$lang['disableactions_other'] = '其他功能 (逗號分隔)';
+$lang['sneaky_index'] = '預設情況下,DokuWiki 會在索引頁會顯示所有命名空間。啟用此選項會隱藏用戶沒有閱讀權限的頁面,但也可能將能閱讀的子頁面一併隱藏。在特定 ACL 設定下,這可能導致索引無法使用。';
+$lang['auth_security_timeout'] = '安全認證的計時 (秒)';
+$lang['securecookie'] = 'HTTPS 頁面設定的 cookie 是否只能由瀏覽器經 HTTPS 傳送?取消此選項後,只有登入維基會被 SSL 保護而瀏覽時不會。';
+$lang['xmlrpc'] = '啟用/停用 XML-RPC 介面';
+$lang['xmlrpcuser'] = 'XML-RPC 存取權限將局限於在此提供的群組或使用者 (逗號分隔)。若要開放權限給所有人請留白。';
+$lang['updatecheck'] = '檢查更新與安全性警告?DokuWiki 需要聯繫 update.dokuwiki.org 才能使用此功能。';
+$lang['userewrite'] = '使用好看的 URL';
+$lang['useslash'] = '在 URL 中使用斜線作為命名空間的分隔字元';
+$lang['usedraft'] = '編輯時自動儲存草稿';
+$lang['sepchar'] = '頁面名稱中單字的分隔字元';
+$lang['canonical'] = '使用最典型的 URL';
+$lang['fnencode'] = '非 ASCII 文件名稱的編輯方法。';
+$lang['autoplural'] = '檢查複數形式的連結 (英文)';
+$lang['compression'] = 'attic 文件的壓縮方式';
+$lang['cachetime'] = '緩存的最大存在時間 (秒)';
+$lang['locktime'] = '檔案的最大鎖定時間 (秒)';
+$lang['fetchsize'] = 'fetch.php 可以從外部下載的最大檔案尺寸 (bytes)';
+$lang['notify'] = '寄送變更通知信到這個 E-mail 位址';
+$lang['registernotify'] = '寄送新使用者註冊資訊到這個 E-mail 位址';
+$lang['mailfrom'] = '自動發送郵件時使用的郵件地址';
+$lang['mailprefix'] = '自動發送郵件時使用的標題前綴';
+$lang['gzip_output'] = '對 xhtml 使用 gzip 內容編碼';
+$lang['gdlib'] = 'GD Lib 版本';
+$lang['im_convert'] = 'ImageMagick 的轉換工具路徑';
+$lang['jpg_quality'] = 'JPG 壓縮品質(0-100)';
+$lang['subscribers'] = '啟用頁面訂閱';
+$lang['subscribe_time'] = '訂閱列表和摘要發送的時間間隔 (秒);這個值應該小於指定的最近更改保留時間 (recent_days)。';
+$lang['compress'] = '壓縮 CSS 與 JavaScript 的輸出';
+$lang['cssdatauri'] = 'CSS 中所引用的圖片假如小於該數字大小(bytes),將會被直接嵌入 CSS 中來減少 HTTP Request 的發送。此功能在 IE 7 及之下版本不支援。推薦使用 <code>400</code> 到 <code>600</code> 之間。設定為<code>0</code> 則停用。';
+$lang['hidepages'] = '隱藏匹配的界面 (正規式)';
+$lang['send404'] = '存取不存在的頁面時送出 "HTTP 404/Page Not Found"';
+$lang['sitemap'] = '產生 Google 站台地圖 (天)';
+$lang['broken_iua'] = 'ignore_user_abort 功能失效了?這有可能導致搜索索引不可用。IIS+PHP/CGI 已損壞。請參閱 <a href=\"http://bugs.splitbrain.org/?do=details&task_id=852\">Bug 852</a> 獲取更多信息。';
+$lang['xsendfile'] = '使用 X-Sendfile 頭讓服務器發送狀態文件?您的服務器需要支持該功能。';
+$lang['renderer_xhtml'] = '主要維基輸出 (xhtml) 的的渲染器';
+$lang['renderer__core'] = '%s (dokuwiki 核心)';
+$lang['renderer__plugin'] = '%s (插件)';
+$lang['rememberme'] = '允許自動登入 (記住我)';
+$lang['rss_type'] = 'XML feed 類型';
+$lang['rss_linkto'] = 'XML feed 連結到';
+$lang['rss_content'] = 'XML feed 項目中顯示什麼呢?';
+$lang['rss_update'] = 'XML feed 更新間隔時間 (秒)';
+$lang['recent_days'] = '儲存多少天內的變更';
+$lang['rss_show_summary'] = '於標題中顯示簡要的 XML feed';
+$lang['target____wiki'] = '內部連結的目標視窗';
+$lang['target____interwiki'] = '跨維基連結的目標視窗';
+$lang['target____extern'] = '外部連結的目標視窗';
+$lang['target____media'] = '媒體連結的目標視窗';
+$lang['target____windows'] = 'Windows 連結的目標視窗';
+$lang['proxy____host'] = 'Proxy 伺服器名稱';
+$lang['proxy____port'] = 'Proxy 連接埠';
+$lang['proxy____user'] = 'Proxy 使用者名稱';
+$lang['proxy____pass'] = 'Proxy 密碼';
+$lang['proxy____ssl'] = '使用 SSL 連接到 Proxy';
+$lang['proxy____except'] = '比對 proxy 代理時應跳過的地址的正規式。';
+$lang['safemodehack'] = '啟用 Safemode Hack';
+$lang['ftp____host'] = 'Safemode Hack 的 FTP 伺服器';
+$lang['ftp____port'] = 'Safemode Hack 的 FTP 端口';
+$lang['ftp____user'] = 'Safemode Hack 的 FTP 帳戶';
+$lang['ftp____pass'] = 'Safemode Hack 的 FTP 密碼';
+$lang['ftp____root'] = 'Safemode Hack 的 FTP 根路徑';
+$lang['license_o_'] = '未選擇';
+$lang['typography_o_0'] = '無';
+$lang['typography_o_1'] = '只限雙引號';
+$lang['typography_o_2'] = '包括單引號 (未必能運作)';
+$lang['userewrite_o_0'] = '無';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki 內部控制';
+$lang['deaccent_o_0'] = '關閉';
+$lang['deaccent_o_1'] = '移除重音符號';
+$lang['deaccent_o_2'] = '羅馬字母轉寫';
+$lang['gdlib_o_0'] = 'GD Lib 無法使用';
+$lang['gdlib_o_1'] = '版本 1.x';
+$lang['gdlib_o_2'] = '自動偵測';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = '摘要';
+$lang['rss_content_o_diff'] = '統一的差異';
+$lang['rss_content_o_htmldiff'] = 'HTML 格式的差異對照表';
+$lang['rss_content_o_html'] = '完整的 HTML 頁面內容';
+$lang['rss_linkto_o_diff'] = '差異檢視';
+$lang['rss_linkto_o_page'] = '已修訂的頁面';
+$lang['rss_linkto_o_rev'] = '版本清單';
+$lang['rss_linkto_o_current'] = '目前頁面';
+$lang['compression_o_0'] = '無';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = '不使用';
+$lang['xsendfile_o_1'] = '專有 lighttpd 標頭 (1.5 發布前)';
+$lang['xsendfile_o_2'] = '標準 X-Sendfile 標頭';
+$lang['xsendfile_o_3'] = '專有 Nginx X-Accel-Redirect 標頭';
+$lang['showuseras_o_loginname'] = '登入名稱';
+$lang['showuseras_o_username'] = '完整姓名';
+$lang['showuseras_o_email'] = '使用者的 email 位址 (根據郵件監控設定混淆化)';
+$lang['showuseras_o_email_link'] = '使用者的 email 位址標示成 mailto: link';
+$lang['useheading_o_0'] = '永不';
+$lang['useheading_o_navigation'] = '僅導覽';
+$lang['useheading_o_content'] = '僅維基內容';
+$lang['useheading_o_1'] = '總是';
+$lang['readdircache'] = 'readdir 緩存的最大存在時間 (秒)';
diff --git a/lib/plugins/config/lang/zh/intro.txt b/lib/plugins/config/lang/zh/intro.txt
new file mode 100644
index 000000000..a7db4eda0
--- /dev/null
+++ b/lib/plugins/config/lang/zh/intro.txt
@@ -0,0 +1,9 @@
+====== 配置管理器 ======
+
+使用本页中的内容来控制您的 Dokuwiki 设置。 每个单独设置的相关信息请参阅 [[doku>config]]。 配置管理器的更多信息请参阅 [[doku>plugin:config]]。
+
+淡红色背景的项目被保护,不能通过这个管理器更改。 蓝色背景的项目是系统的默认值,白色背景的项目是您作出更改的项目。蓝色和白色的设置项目都可以更改。
+
+离开本页之前不要忘记点击最后的 **保存** 按钮,否则您做的修改不会生效。
+
+
diff --git a/lib/plugins/config/lang/zh/lang.php b/lib/plugins/config/lang/zh/lang.php
new file mode 100644
index 000000000..2f6444ffa
--- /dev/null
+++ b/lib/plugins/config/lang/zh/lang.php
@@ -0,0 +1,200 @@
+<?php
+/**
+ * Chinese(Simplified) language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-tradsimp.html
+ * @author George Sheraton guxd@163.com
+ * @author Simon zhan <simonzhan@21cn.com>
+ * @author mr.jinyi@gmail.com
+ * @author ben <ben@livetom.com>
+ * @author lainme <lainme993@gmail.com>
+ * @author caii <zhoucaiqi@gmail.com>
+ * @author Hiphen Lee <jacob.b.leung@gmail.com>
+ * @author caii, patent agent in China <zhoucaiqi@gmail.com>
+ * @author lainme993@gmail.com
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '配置设置';
+$lang['error'] = '由于非法参数,设置没有更新。请检查您做的改动并重新提交。
+ <br />非法参数会用红框包围显示。';
+$lang['updated'] = '设置更新成功。';
+$lang['nochoice'] = '(没有其他可用选项)';
+$lang['locked'] = '设置文件无法更新。如果这是您没有意料到的,<br />
+ 请确保本地设置文件的名称和权限设置正确。';
+$lang['danger'] = '危险:更改这个选项可能会使用你的Wiki页面和配置菜单无法进入。';
+$lang['warning'] = '注意:更改这个选项可能会造成未知结果。';
+$lang['security'] = '安全提示:更改这个选项可能会有安全隐患。';
+$lang['_configuration_manager'] = '配置管理器';
+$lang['_header_dokuwiki'] = 'DokuWiki 设置';
+$lang['_header_plugin'] = '插件设置';
+$lang['_header_template'] = '模板设置';
+$lang['_header_undefined'] = '其他设置';
+$lang['_basic'] = '基本设置';
+$lang['_display'] = '显示设置';
+$lang['_authentication'] = '认证设置';
+$lang['_anti_spam'] = '反垃圾邮件/评论设置';
+$lang['_editing'] = '编辑设置';
+$lang['_links'] = '链接设置';
+$lang['_media'] = '媒体设置';
+$lang['_advanced'] = '高级设置';
+$lang['_network'] = '网络设置';
+$lang['_plugin_sufix'] = '插件设置';
+$lang['_template_sufix'] = '模板设置';
+$lang['_msg_setting_undefined'] = '设置的元数据不存在。';
+$lang['_msg_setting_no_class'] = '设置的分类不存在。';
+$lang['_msg_setting_no_default'] = '设置的默认值不存在。';
+$lang['fmode'] = '文件的创建模式';
+$lang['dmode'] = '文件夹的创建模式';
+$lang['lang'] = '语言';
+$lang['basedir'] = '根目录';
+$lang['baseurl'] = '根路径(URL)';
+$lang['savedir'] = '保存数据的目录';
+$lang['cookiedir'] = 'Cookie 路径。留空以使用 baseurl。';
+$lang['start'] = '开始页面的名称';
+$lang['title'] = '维基站点的标题';
+$lang['template'] = '模版';
+$lang['license'] = '您愿意让你贡献的内容在何种许可方式下发布?';
+$lang['fullpath'] = '在页面底部显示完整路径';
+$lang['recent'] = '最近更新';
+$lang['breadcrumbs'] = '显示“足迹”的数量';
+$lang['youarehere'] = '显示“您在这里”';
+$lang['typography'] = '进行字符替换';
+$lang['htmlok'] = '允许嵌入式 HTML';
+$lang['phpok'] = '允许嵌入式 PHP';
+$lang['dformat'] = '日期格式(参见 PHP 的 <a href="http://www.php.net/strftime">strftime</a> 功能)';
+$lang['signature'] = '签名样式';
+$lang['toptoclevel'] = '目录的最顶层';
+$lang['tocminheads'] = '头条数目的最小数目,这将用于决定是否创建目录列表(TOC)';
+$lang['maxtoclevel'] = '目录的最多层次';
+$lang['maxseclevel'] = '段落编辑的最多层次';
+$lang['camelcase'] = '对链接使用 CamelCase';
+$lang['deaccent'] = '清理页面名称';
+$lang['useheading'] = '使用“标题 H1”作为页面名称';
+$lang['refcheck'] = '检查媒体与页面的挂钩情况';
+$lang['refshow'] = '显示媒体与页面挂钩情况的数量';
+$lang['allowdebug'] = '允许调试 <b>如果您不需要调试,请勿勾选!</b>';
+$lang['usewordblock'] = '根据 wordlist 阻止垃圾评论';
+$lang['indexdelay'] = '构建索引前的时间延滞(秒)';
+$lang['relnofollow'] = '对外部链接使用 rel="nofollow" 标签';
+$lang['mailguard'] = '弄乱邮件地址(保护用户的邮件地址)';
+$lang['iexssprotect'] = '检验上传的文件以避免可能存在的恶意 JavaScript 或 HTML 代码';
+$lang['showuseras'] = '显示用户为';
+$lang['useacl'] = '使用访问控制列表(ACL)';
+$lang['autopasswd'] = '自动生成密码';
+$lang['authtype'] = '认证后台管理方式';
+$lang['passcrypt'] = '密码加密方法';
+$lang['defaultgroup'] = '默认组';
+$lang['superuser'] = '超级用户 - 不论 ACL 如何设置,都能访问所有页面与功能的用户组/用户';
+$lang['manager'] = '管理员 - 能访问相应管理功能的用户组/用户';
+$lang['profileconfirm'] = '更新个人信息时需要输入当前密码';
+$lang['disableactions'] = '停用 DokuWiki 功能';
+$lang['disableactions_check'] = '检查';
+$lang['disableactions_subscription'] = '订阅/退订';
+$lang['disableactions_wikicode'] = '查看源文件/导出源文件';
+$lang['disableactions_other'] = '其他功能(用英文逗号分隔)';
+$lang['sneaky_index'] = '默认情况下,DokuWiki 在索引页会显示所有 namespace。启用该选项能隐藏那些用户没有权限阅读的页面。但也可能将用户能够阅读的子页面一并隐藏。这有可能导致在特定 ACL 设置下,索引功能不可用。';
+$lang['auth_security_timeout'] = '认证安全超时(秒)';
+$lang['securecookie'] = '要让浏览器须以HTTPS方式传送在HTTPS会话中设置的cookies吗?请只在登录过程为SSL加密而浏览维基为明文的情况下打开此选项。';
+$lang['xmlrpc'] = '启用/禁用 XML-RPC 交互界面。';
+$lang['xmlrpcuser'] = '将 XML-RPC 连接限制在用逗号分隔的组或用户中。留空对所有人开启连接权限。';
+$lang['updatecheck'] = '自动检查更新并接收安全警告吗?开启该功能后 DokuWiki 将自动访问 splitbrain.org。';
+$lang['userewrite'] = '使用更整洁的 URL';
+$lang['useslash'] = '在 URL 中使用斜杠作为命名空间的分隔符';
+$lang['usedraft'] = '编辑时自动保存一份草稿';
+$lang['sepchar'] = '页面名称中的单词分隔符';
+$lang['canonical'] = '使用完全标准的 URL';
+$lang['fnencode'] = '非 ASCII 文件名的编码方法。';
+$lang['autoplural'] = '在链接中检查多种格式';
+$lang['compression'] = 'attic 文件的压缩方式';
+$lang['cachetime'] = '缓存的最长时间(秒)';
+$lang['locktime'] = '独有编辑权/文件锁定的最长时间(秒)';
+$lang['fetchsize'] = 'fetch.php 能从外部下载的最大文件大小(字节)';
+$lang['notify'] = '发送更改通知给这个邮件地址';
+$lang['registernotify'] = '发送新注册用户的信息给这个邮件地址';
+$lang['mailfrom'] = '自动发送邮件时使用的邮件地址';
+$lang['mailprefix'] = '自动发送邮件时使用的邮件地址前缀';
+$lang['gzip_output'] = '对 xhtml 使用 gzip 内容编码';
+$lang['gdlib'] = 'GD 库版本';
+$lang['im_convert'] = 'ImageMagick 转换工具的路径';
+$lang['jpg_quality'] = 'JPG 压缩质量(0-100)';
+$lang['subscribers'] = '启用页面订阅支持';
+$lang['subscribe_time'] = '订阅列表和摘要发送的时间间隔(秒);这应当小于指定的最近更改保留时间(recent_days)。
+';
+$lang['compress'] = '使 CSS 和 javascript 的输出更紧密';
+$lang['cssdatauri'] = '字节数。CSS 文件引用的图片若小于该字节,则被直接嵌入样式表中来减少 HTTP 请求头的开销。这个技术在 IE 中不起作用。<code>400</code> 到 <code>600</code> 字节是不错的值。设置为 <code>0</code> 则禁用。';
+$lang['hidepages'] = '隐藏匹配的界面(正则表达式)';
+$lang['send404'] = '发送 "HTTP 404/页面没有找到" 错误信息给不存在的页面';
+$lang['sitemap'] = '生成 Google sitemap(天)';
+$lang['broken_iua'] = 'ignore_user_abort 功能失效了?这有可能导致搜索索引不可用。IIS+PHP/CGI 已损坏。请参阅 <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> 获取更多信息。';
+$lang['xsendfile'] = '使用 X-Sendfile 头让服务器发送状态文件?您的服务器需要支持该功能。';
+$lang['renderer_xhtml'] = '主维基页面 (xhtml) 输出使用的渲染';
+$lang['renderer__core'] = '%s(DokuWiki 内核)';
+$lang['renderer__plugin'] = '%s(插件)';
+$lang['rememberme'] = '允许在本地机长期保留登录cookies信息(记住我)';
+$lang['rss_type'] = 'XML feed 类型';
+$lang['rss_linkto'] = 'XML feed 链接到';
+$lang['rss_content'] = 'XML feed 项目中显示什么呢?';
+$lang['rss_update'] = 'XML feed 升级间隔(秒)';
+$lang['recent_days'] = '保留多少天的最近更改(天)';
+$lang['rss_show_summary'] = 'XML feed 在标题中显示摘要';
+$lang['target____wiki'] = '内部链接的目标窗口';
+$lang['target____interwiki'] = 'Interwiki 链接的目标窗口';
+$lang['target____extern'] = '外部链接的目标窗口';
+$lang['target____media'] = '媒体文件链接的目标窗口';
+$lang['target____windows'] = 'Windows 链接的目标窗口';
+$lang['proxy____host'] = '代理服务器的名称';
+$lang['proxy____port'] = '代理服务器的端口';
+$lang['proxy____user'] = '代理服务器的用户名';
+$lang['proxy____pass'] = '代理服务器的密码';
+$lang['proxy____ssl'] = '使用 SSL 连接到代理服务器';
+$lang['proxy____except'] = '用来匹配代理应跳过的地址的正则表达式。';
+$lang['safemodehack'] = '启用 Safemode Hack';
+$lang['ftp____host'] = 'Safemode Hack 的 FTP 服务器';
+$lang['ftp____port'] = 'Safemode Hack 的 FTP 端口';
+$lang['ftp____user'] = 'Safemode Hack 的 FTP 用户名';
+$lang['ftp____pass'] = 'Safemode Hack 的 FTP 密码';
+$lang['ftp____root'] = 'Safemode Hack 的 FTP 根路径';
+$lang['license_o_'] = '什么都没有选';
+$lang['typography_o_0'] = '无';
+$lang['typography_o_1'] = '仅限双引号';
+$lang['typography_o_2'] = '所有引号(不一定能正常运行)';
+$lang['userewrite_o_0'] = '无';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki 内部控制';
+$lang['deaccent_o_0'] = '关闭';
+$lang['deaccent_o_1'] = '移除重音符号';
+$lang['deaccent_o_2'] = '用罗马字拼写';
+$lang['gdlib_o_0'] = 'GD 库不可用';
+$lang['gdlib_o_1'] = '1.x 版';
+$lang['gdlib_o_2'] = '自动检测';
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+$lang['rss_content_o_abstract'] = '摘要';
+$lang['rss_content_o_diff'] = '统一差异';
+$lang['rss_content_o_htmldiff'] = 'HTML 格式化的差异表';
+$lang['rss_content_o_html'] = '完整的 hTML 页面内容';
+$lang['rss_linkto_o_diff'] = '差别查看';
+$lang['rss_linkto_o_page'] = '已修订的页面';
+$lang['rss_linkto_o_rev'] = '修订列表';
+$lang['rss_linkto_o_current'] = '当前页面';
+$lang['compression_o_0'] = '无';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = '不要使用';
+$lang['xsendfile_o_1'] = '专有 lighttpd 头(1.5 发布前)';
+$lang['xsendfile_o_2'] = '标准 X-Sendfile 头';
+$lang['xsendfile_o_3'] = '专有 Nginx X-Accel-Redirect 头';
+$lang['showuseras_o_loginname'] = '登录名';
+$lang['showuseras_o_username'] = '用户全名';
+$lang['showuseras_o_email'] = '用户的电子邮箱(按邮箱保护设置加扰)';
+$lang['showuseras_o_email_link'] = '以mailto:形式显示用户的电子邮箱';
+$lang['useheading_o_0'] = '从不';
+$lang['useheading_o_navigation'] = '仅限导航';
+$lang['useheading_o_content'] = '仅限维基内容内';
+$lang['useheading_o_1'] = '一直';
+$lang['readdircache'] = 'readdir缓存的最长寿命(秒)';
diff --git a/lib/plugins/config/plugin.info.txt b/lib/plugins/config/plugin.info.txt
new file mode 100644
index 000000000..ace4889b6
--- /dev/null
+++ b/lib/plugins/config/plugin.info.txt
@@ -0,0 +1,6 @@
+author Christopher Smith
+email chris@jalakai.co.uk
+date 2007-08-05
+name Configuration Manager
+desc Manage Dokuwiki's Configuration Settings
+url http://dokuwiki.org/plugin:config
diff --git a/lib/plugins/config/rtl.css b/lib/plugins/config/rtl.css
new file mode 100644
index 000000000..b8b9660e2
--- /dev/null
+++ b/lib/plugins/config/rtl.css
@@ -0,0 +1,45 @@
+#config__manager fieldset {
+ clear: both;
+}
+
+#config__manager fieldset td {
+ text-align: right;
+}
+
+#config__manager label {
+ text-align: right;
+}
+
+#config__manager td.value input.checkbox {
+ float: right;
+ padding-left: 0;
+ padding-right: 0.7em;
+}
+
+#config__manager td.value label {
+ float: left;
+}
+
+#config__manager td.label {
+ padding: 0.8em 1em 0.6em 0;
+}
+
+#config__manager td.label span.outkey {
+ float: right;
+ margin-right: 1em;
+}
+
+#config__manager td.label label {
+ clear: right;
+}
+
+#config__manager td.label img {
+ float: left;
+}
+
+#config__manager .selection {
+ width: 14.8em;
+ float: right;
+ margin: 0 0 2px 0.3em;
+}
+
diff --git a/lib/plugins/config/settings/config.class.php b/lib/plugins/config/settings/config.class.php
new file mode 100644
index 000000000..1cdab607f
--- /dev/null
+++ b/lib/plugins/config/settings/config.class.php
@@ -0,0 +1,1057 @@
+<?php
+/**
+ * Configuration Class and generic setting classes
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+
+if (!class_exists('configuration')) {
+
+ class configuration {
+
+ var $_name = 'conf'; // name of the config variable found in the files (overridden by $config['varname'])
+ var $_format = 'php'; // format of the config file, supported formats - php (overridden by $config['format'])
+ var $_heading = ''; // heading string written at top of config file - don't include comment indicators
+ var $_loaded = false; // set to true after configuration files are loaded
+ var $_metadata = array(); // holds metadata describing the settings
+ var $setting = array(); // array of setting objects
+ var $locked = false; // configuration is considered locked if it can't be updated
+
+ // configuration filenames
+ var $_default_files = array();
+ var $_local_files = array(); // updated configuration is written to the first file
+ var $_protected_files = array();
+
+ var $_plugin_list = null;
+
+ /**
+ * constructor
+ */
+ function configuration($datafile) {
+ global $conf, $config_cascade;
+
+ if (!@file_exists($datafile)) {
+ msg('No configuration metadata found at - '.htmlspecialchars($datafile),-1);
+ return;
+ }
+ include($datafile);
+
+ if (isset($config['varname'])) $this->_name = $config['varname'];
+ if (isset($config['format'])) $this->_format = $config['format'];
+ if (isset($config['heading'])) $this->_heading = $config['heading'];
+
+ $this->_default_files = $config_cascade['main']['default'];
+ $this->_local_files = $config_cascade['main']['local'];
+ $this->_protected_files = $config_cascade['main']['protected'];
+
+# if (isset($file['default'])) $this->_default_file = $file['default'];
+# if (isset($file['local'])) $this->_local_file = $file['local'];
+# if (isset($file['protected'])) $this->_protected_file = $file['protected'];
+
+ $this->locked = $this->_is_locked();
+
+ $this->_metadata = array_merge($meta, $this->get_plugintpl_metadata($conf['template']));
+
+ $this->retrieve_settings();
+ }
+
+ function retrieve_settings() {
+ global $conf;
+ $no_default_check = array('setting_fieldset', 'setting_undefined', 'setting_no_class');
+
+ if (!$this->_loaded) {
+ $default = array_merge($this->get_plugintpl_default($conf['template']), $this->_read_config_group($this->_default_files));
+ $local = $this->_read_config_group($this->_local_files);
+ $protected = $this->_read_config_group($this->_protected_files);
+
+ $keys = array_merge(array_keys($this->_metadata),array_keys($default), array_keys($local), array_keys($protected));
+ $keys = array_unique($keys);
+
+ foreach ($keys as $key) {
+ if (isset($this->_metadata[$key])) {
+ $class = $this->_metadata[$key][0];
+ $class = ($class && class_exists('setting_'.$class)) ? 'setting_'.$class : 'setting';
+ if ($class=='setting') {
+ $this->setting[] = new setting_no_class($key,$param);
+ }
+
+ $param = $this->_metadata[$key];
+ array_shift($param);
+ } else {
+ $class = 'setting_undefined';
+ $param = NULL;
+ }
+
+ if (!in_array($class, $no_default_check) && !isset($default[$key])) {
+ $this->setting[] = new setting_no_default($key,$param);
+ }
+
+ $this->setting[$key] = new $class($key,$param);
+ $this->setting[$key]->initialize($default[$key],$local[$key],$protected[$key]);
+ }
+
+ $this->_loaded = true;
+ }
+ }
+
+ function save_settings($id, $header='', $backup=true) {
+ global $conf;
+
+ if ($this->locked) return false;
+
+ // write back to the last file in the local config cascade
+ $file = end($this->_local_files);
+
+ // backup current file (remove any existing backup)
+ if (@file_exists($file) && $backup) {
+ if (@file_exists($file.'.bak')) @unlink($file.'.bak');
+ if (!io_rename($file, $file.'.bak')) return false;
+ }
+
+ if (!$fh = @fopen($file, 'wb')) {
+ io_rename($file.'.bak', $file); // problem opening, restore the backup
+ return false;
+ }
+
+ if (empty($header)) $header = $this->_heading;
+
+ $out = $this->_out_header($id,$header);
+
+ foreach ($this->setting as $setting) {
+ $out .= $setting->out($this->_name, $this->_format);
+ }
+
+ $out .= $this->_out_footer();
+
+ @fwrite($fh, $out);
+ fclose($fh);
+ if($conf['fperm']) chmod($file, $conf['fperm']);
+ return true;
+ }
+
+ function _read_config_group($files) {
+ $config = array();
+ foreach ($files as $file) {
+ $config = array_merge($config, $this->_read_config($file));
+ }
+
+ return $config;
+ }
+
+ /**
+ * return an array of config settings
+ */
+ function _read_config($file) {
+
+ if (!$file) return array();
+
+ $config = array();
+# $file = eval('return '.$file.';');
+
+ if ($this->_format == 'php') {
+
+ if(@file_exists($file)){
+ $contents = @php_strip_whitespace($file);
+ }else{
+ $contents = '';
+ }
+ $pattern = '/\$'.$this->_name.'\[[\'"]([^=]+)[\'"]\] ?= ?(.*?);(?=[^;]*(?:\$'.$this->_name.'|@include|$))/s';
+ $matches=array();
+ preg_match_all($pattern,$contents,$matches,PREG_SET_ORDER);
+
+ for ($i=0; $i<count($matches); $i++) {
+
+ // correct issues with the incoming data
+ // FIXME ... for now merge multi-dimensional array indices using ____
+ $key = preg_replace('/.\]\[./',CM_KEYMARKER,$matches[$i][1]);
+
+ // remove quotes from quoted strings & unescape escaped data
+ $value = preg_replace('/^(\'|")(.*)(?<!\\\\)\1$/s','$2',$matches[$i][2]);
+ $value = strtr($value, array('\\\\'=>'\\','\\\''=>'\'','\\"'=>'"'));
+
+ $config[$key] = $value;
+ }
+ }
+
+ return $config;
+ }
+
+ function _out_header($id, $header) {
+ $out = '';
+ if ($this->_format == 'php') {
+ $out .= '<'.'?php'."\n".
+ "/*\n".
+ " * ".$header."\n".
+ " * Auto-generated by ".$id." plugin\n".
+ " * Run for user: ".$_SERVER['REMOTE_USER']."\n".
+ " * Date: ".date('r')."\n".
+ " */\n\n";
+ }
+
+ return $out;
+ }
+
+ function _out_footer() {
+ $out = '';
+ if ($this->_format == 'php') {
+ # if ($this->_protected_file) {
+ # $out .= "\n@include(".$this->_protected_file.");\n";
+ # }
+ $out .= "\n// end auto-generated content\n";
+ }
+
+ return $out;
+ }
+
+ // configuration is considered locked if there is no local settings filename
+ // or the directory its in is not writable or the file exists and is not writable
+ function _is_locked() {
+ if (!$this->_local_files) return true;
+
+# $local = eval('return '.$this->_local_file.';');
+ $local = $this->_local_files[0];
+
+ if (!is_writable(dirname($local))) return true;
+ if (@file_exists($local) && !is_writable($local)) return true;
+
+ return false;
+ }
+
+ /**
+ * not used ... conf's contents are an array!
+ * reduce any multidimensional settings to one dimension using CM_KEYMARKER
+ */
+ function _flatten($conf,$prefix='') {
+
+ $out = array();
+
+ foreach($conf as $key => $value) {
+ if (!is_array($value)) {
+ $out[$prefix.$key] = $value;
+ continue;
+ }
+
+ $tmp = $this->_flatten($value,$prefix.$key.CM_KEYMARKER);
+ $out = array_merge($out,$tmp);
+ }
+
+ return $out;
+ }
+
+ function get_plugin_list() {
+ if (is_null($this->_plugin_list)) {
+ $list = plugin_list('',true); // all plugins, including disabled ones
+
+ // remove this plugin from the list
+ $idx = array_search('config',$list);
+ unset($list[$idx]);
+
+ trigger_event('PLUGIN_CONFIG_PLUGINLIST',$list);
+ $this->_plugin_list = $list;
+ }
+
+ return $this->_plugin_list;
+ }
+
+ /**
+ * load metadata for plugin and template settings
+ */
+ function get_plugintpl_metadata($tpl){
+ $file = '/conf/metadata.php';
+ $class = '/conf/settings.class.php';
+ $metadata = array();
+
+ foreach ($this->get_plugin_list() as $plugin) {
+ $plugin_dir = plugin_directory($plugin);
+ if (@file_exists(DOKU_PLUGIN.$plugin_dir.$file)){
+ $meta = array();
+ @include(DOKU_PLUGIN.$plugin_dir.$file);
+ @include(DOKU_PLUGIN.$plugin_dir.$class);
+ if (!empty($meta)) {
+ $metadata['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.'plugin_settings_name'] = array('fieldset');
+ }
+ foreach ($meta as $key => $value){
+ if ($value[0]=='fieldset') { continue; } //plugins only get one fieldset
+ $metadata['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.$key] = $value;
+ }
+ }
+ }
+
+ // the same for the active template
+ if (@file_exists(tpl_incdir().$file)){
+ $meta = array();
+ @include(tpl_incdir().$file);
+ @include(tpl_incdir().$class);
+ if (!empty($meta)) {
+ $metadata['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.'template_settings_name'] = array('fieldset');
+ }
+ foreach ($meta as $key => $value){
+ if ($value[0]=='fieldset') { continue; } //template only gets one fieldset
+ $metadata['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.$key] = $value;
+ }
+ }
+
+ return $metadata;
+ }
+
+ /**
+ * load default settings for plugins and templates
+ */
+ function get_plugintpl_default($tpl){
+ $file = '/conf/default.php';
+ $default = array();
+
+ foreach ($this->get_plugin_list() as $plugin) {
+ $plugin_dir = plugin_directory($plugin);
+ if (@file_exists(DOKU_PLUGIN.$plugin_dir.$file)){
+ $conf = array();
+ @include(DOKU_PLUGIN.$plugin_dir.$file);
+ foreach ($conf as $key => $value){
+ $default['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.$key] = $value;
+ }
+ }
+ }
+
+ // the same for the active template
+ if (@file_exists(tpl_incdir().$file)){
+ $conf = array();
+ @include(tpl_incdir().$file);
+ foreach ($conf as $key => $value){
+ $default['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.$key] = $value;
+ }
+ }
+
+ return $default;
+ }
+
+ }
+}
+
+if (!class_exists('setting')) {
+ class setting {
+
+ var $_key = '';
+ var $_default = NULL;
+ var $_local = NULL;
+ var $_protected = NULL;
+
+ var $_pattern = '';
+ var $_error = false; // only used by those classes which error check
+ var $_input = NULL; // only used by those classes which error check
+
+ var $_cautionList = array(
+ 'basedir' => 'danger', 'baseurl' => 'danger', 'savedir' => 'danger', 'cookiedir' => 'danger', 'useacl' => 'danger', 'authtype' => 'danger', 'superuser' => 'danger', 'userewrite' => 'danger',
+ 'start' => 'warning', 'camelcase' => 'warning', 'deaccent' => 'warning', 'sepchar' => 'warning', 'compression' => 'warning', 'xsendfile' => 'warning', 'renderer_xhtml' => 'warning', 'fnencode' => 'warning',
+ 'allowdebug' => 'security', 'htmlok' => 'security', 'phpok' => 'security', 'iexssprotect' => 'security', 'xmlrpc' => 'security', 'fullpath' => 'security'
+ );
+
+ function setting($key, $params=NULL) {
+ $this->_key = $key;
+
+ if (is_array($params)) {
+ foreach($params as $property => $value) {
+ $this->$property = $value;
+ }
+ }
+ }
+
+ /**
+ * receives current values for the setting $key
+ */
+ function initialize($default, $local, $protected) {
+ if (isset($default)) $this->_default = $default;
+ if (isset($local)) $this->_local = $local;
+ if (isset($protected)) $this->_protected = $protected;
+ }
+
+ /**
+ * update setting with user provided value $input
+ * if value fails error check, save it
+ *
+ * @return true if changed, false otherwise (incl. on error)
+ */
+ function update($input) {
+ if (is_null($input)) return false;
+ if ($this->is_protected()) return false;
+
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ if ($value == $input) return false;
+
+ if ($this->_pattern && !preg_match($this->_pattern,$input)) {
+ $this->_error = true;
+ $this->_input = $input;
+ return false;
+ }
+
+ $this->_local = $input;
+ return true;
+ }
+
+ /**
+ * @return array(string $label_html, string $input_html)
+ */
+ function html(&$plugin, $echo=false) {
+ $value = '';
+ $disable = '';
+
+ if ($this->is_protected()) {
+ $value = $this->_protected;
+ $disable = 'disabled="disabled"';
+ } else {
+ if ($echo && $this->_error) {
+ $value = $this->_input;
+ } else {
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ }
+ }
+
+ $key = htmlspecialchars($this->_key);
+ $value = htmlspecialchars($value);
+
+ $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
+ $input = '<textarea rows="3" cols="40" id="config___'.$key.'" name="config['.$key.']" class="edit" '.$disable.'>'.$value.'</textarea>';
+ return array($label,$input);
+ }
+
+ /**
+ * generate string to save setting value to file according to $fmt
+ */
+ function out($var, $fmt='php') {
+
+ if ($this->is_protected()) return '';
+ if (is_null($this->_local) || ($this->_default == $this->_local)) return '';
+
+ $out = '';
+
+ if ($fmt=='php') {
+ // translation string needs to be improved FIXME
+ $tr = array("\n"=>'\n', "\r"=>'\r', "\t"=>'\t', "\\" => '\\\\', "'" => '\\\'');
+ $tr = array("\\" => '\\\\', "'" => '\\\'');
+
+ $out = '$'.$var."['".$this->_out_key()."'] = '".strtr($this->_local, $tr)."';\n";
+ }
+
+ return $out;
+ }
+
+ function prompt(&$plugin) {
+ $prompt = $plugin->getLang($this->_key);
+ if (!$prompt) $prompt = htmlspecialchars(str_replace(array('____','_'),' ',$this->_key));
+ return $prompt;
+ }
+
+ function is_protected() { return !is_null($this->_protected); }
+ function is_default() { return !$this->is_protected() && is_null($this->_local); }
+ function error() { return $this->_error; }
+
+ function caution() {
+ if (!array_key_exists($this->_key, $this->_cautionList)) return false;
+ return $this->_cautionList[$this->_key];
+ }
+
+ function _out_key($pretty=false,$url=false) {
+ if($pretty){
+ $out = str_replace(CM_KEYMARKER,"&raquo;",$this->_key);
+ if ($url && !strstr($out,'&raquo;')) {//provide no urls for plugins, etc.
+ if ($out == 'start') //one exception
+ return '<a href="http://www.dokuwiki.org/config:startpage">'.$out.'</a>';
+ else
+ return '<a href="http://www.dokuwiki.org/config:'.$out.'">'.$out.'</a>';
+ }
+ return $out;
+ }else{
+ return str_replace(CM_KEYMARKER,"']['",$this->_key);
+ }
+ }
+ }
+}
+
+if (!class_exists('setting_string')) {
+ class setting_string extends setting {
+ function html(&$plugin, $echo=false) {
+ $value = '';
+ $disable = '';
+
+ if ($this->is_protected()) {
+ $value = $this->_protected;
+ $disable = 'disabled="disabled"';
+ } else {
+ if ($echo && $this->_error) {
+ $value = $this->_input;
+ } else {
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ }
+ }
+
+ $key = htmlspecialchars($this->_key);
+ $value = htmlspecialchars($value);
+
+ $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
+ $input = '<input id="config___'.$key.'" name="config['.$key.']" type="text" class="edit" value="'.$value.'" '.$disable.'/>';
+ return array($label,$input);
+ }
+ }
+}
+
+if (!class_exists('setting_password')) {
+ class setting_password extends setting_string {
+
+ var $_code = 'plain'; // mechanism to be used to obscure passwords
+
+ function update($input) {
+ if ($this->is_protected()) return false;
+ if (!$input) return false;
+
+ if ($this->_pattern && !preg_match($this->_pattern,$input)) {
+ $this->_error = true;
+ $this->_input = $input;
+ return false;
+ }
+
+ $this->_local = conf_encodeString($input,$this->_code);
+ return true;
+ }
+
+ function html(&$plugin, $echo=false) {
+
+ $value = '';
+ $disable = $this->is_protected() ? 'disabled="disabled"' : '';
+
+ $key = htmlspecialchars($this->_key);
+
+ $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
+ $input = '<input id="config___'.$key.'" name="config['.$key.']" autocomplete="off" type="password" class="edit" value="" '.$disable.' />';
+ return array($label,$input);
+ }
+ }
+}
+
+if (!class_exists('setting_email')) {
+ if (!defined('SETTING_EMAIL_PATTERN')) define('SETTING_EMAIL_PATTERN','<^'.PREG_PATTERN_VALID_EMAIL.'$>');
+
+ class setting_email extends setting_string {
+ var $_pattern = SETTING_EMAIL_PATTERN; // no longer required, retained for backward compatibility - FIXME, may not be necessary
+ var $_multiple = false;
+
+ /**
+ * update setting with user provided value $input
+ * if value fails error check, save it
+ *
+ * @return true if changed, false otherwise (incl. on error)
+ */
+ function update($input) {
+ if (is_null($input)) return false;
+ if ($this->is_protected()) return false;
+
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ if ($value == $input) return false;
+
+ if ($this->_multiple) {
+ $mails = array_filter(array_map('trim', split(',', $input)));
+ } else {
+ $mails = array($input);
+ }
+
+ foreach ($mails as $mail) {
+ if (!mail_isvalid($mail)) {
+ $this->_error = true;
+ $this->_input = $input;
+ return false;
+ }
+ }
+
+ $this->_local = $input;
+ return true;
+ }
+ }
+}
+
+if (!class_exists('setting_richemail')) {
+ class setting_richemail extends setting_email {
+
+ /**
+ * update setting with user provided value $input
+ * if value fails error check, save it
+ *
+ * @return true if changed, false otherwise (incl. on error)
+ */
+ function update($input) {
+ if (is_null($input)) return false;
+ if ($this->is_protected()) return false;
+
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ if ($value == $input) return false;
+
+ // replace variables with pseudo values
+ $test = $input;
+ $test = str_replace('@USER@','joe',$test);
+ $test = str_replace('@NAME@','Joe Schmoe',$test);
+ $test = str_replace('@MAIL@','joe@example.com',$test);
+
+ // now only check the address part
+ if(preg_match('#(.*?)<(.*?)>#',$test,$matches)){
+ $text = trim($matches[1]);
+ $addr = $matches[2];
+ }else{
+ $addr = $test;
+ }
+
+ if ($test !== '' && !mail_isvalid($addr)) {
+ $this->_error = true;
+ $this->_input = $input;
+ return false;
+ }
+
+ $this->_local = $input;
+ return true;
+ }
+
+ }
+}
+
+
+if (!class_exists('setting_numeric')) {
+ class setting_numeric extends setting_string {
+ // This allows for many PHP syntax errors...
+ // var $_pattern = '/^[-+\/*0-9 ]*$/';
+ // much more restrictive, but should eliminate syntax errors.
+ var $_pattern = '/^[-+]? *[0-9]+ *(?:[-+*] *[0-9]+ *)*$/';
+ var $_min = null;
+ var $_max = null;
+
+ function update($input) {
+ $local = $this->_local;
+ $valid = parent::update($input);
+ if ($valid && !(is_null($this->_min) && is_null($this->_max))) {
+ $numeric_local = (int) eval('return '.$this->_local.';');
+ if ((!is_null($this->_min) && $numeric_local < $this->_min) ||
+ (!is_null($this->_max) && $numeric_local > $this->_max)) {
+ $this->_error = true;
+ $this->_input = $input;
+ $this->_local = $local;
+ $valid = false;
+ }
+ }
+ return $valid;
+ }
+
+ function out($var, $fmt='php') {
+
+ if ($this->is_protected()) return '';
+ if (is_null($this->_local) || ($this->_default == $this->_local)) return '';
+
+ $out = '';
+
+ if ($fmt=='php') {
+ $local = $this->_local === '' ? "''" : $this->_local;
+ $out .= '$'.$var."['".$this->_out_key()."'] = ".$local.";\n";
+ }
+
+ return $out;
+ }
+ }
+}
+
+if (!class_exists('setting_numericopt')) {
+ class setting_numericopt extends setting_numeric {
+ // just allow an empty config
+ var $_pattern = '/^(|[-]?[0-9]+(?:[-+*][0-9]+)*)$/';
+ }
+}
+
+if (!class_exists('setting_onoff')) {
+ class setting_onoff extends setting_numeric {
+
+ function html(&$plugin) {
+ $value = '';
+ $disable = '';
+
+ if ($this->is_protected()) {
+ $value = $this->_protected;
+ $disable = ' disabled="disabled"';
+ } else {
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ }
+
+ $key = htmlspecialchars($this->_key);
+ $checked = ($value) ? ' checked="checked"' : '';
+
+ $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
+ $input = '<div class="input"><input id="config___'.$key.'" name="config['.$key.']" type="checkbox" class="checkbox" value="1"'.$checked.$disable.'/></div>';
+ return array($label,$input);
+ }
+
+ function update($input) {
+ if ($this->is_protected()) return false;
+
+ $input = ($input) ? 1 : 0;
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ if ($value == $input) return false;
+
+ $this->_local = $input;
+ return true;
+ }
+ }
+}
+
+if (!class_exists('setting_multichoice')) {
+ class setting_multichoice extends setting_string {
+ var $_choices = array();
+
+ function html(&$plugin) {
+ $value = '';
+ $disable = '';
+ $nochoice = '';
+
+ if ($this->is_protected()) {
+ $value = $this->_protected;
+ $disable = ' disabled="disabled"';
+ } else {
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ }
+
+ // ensure current value is included
+ if (!in_array($value, $this->_choices)) {
+ $this->_choices[] = $value;
+ }
+ // disable if no other choices
+ if (!$this->is_protected() && count($this->_choices) <= 1) {
+ $disable = ' disabled="disabled"';
+ $nochoice = $plugin->getLang('nochoice');
+ }
+
+ $key = htmlspecialchars($this->_key);
+
+ $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
+
+ $input = "<div class=\"input\">\n";
+ $input .= '<select class="edit" id="config___'.$key.'" name="config['.$key.']"'.$disable.'>'."\n";
+ foreach ($this->_choices as $choice) {
+ $selected = ($value == $choice) ? ' selected="selected"' : '';
+ $option = $plugin->getLang($this->_key.'_o_'.$choice);
+ if (!$option && isset($this->lang[$this->_key.'_o_'.$choice])) $option = $this->lang[$this->_key.'_o_'.$choice];
+ if (!$option) $option = $choice;
+
+ $choice = htmlspecialchars($choice);
+ $option = htmlspecialchars($option);
+ $input .= ' <option value="'.$choice.'"'.$selected.' >'.$option.'</option>'."\n";
+ }
+ $input .= "</select> $nochoice \n";
+ $input .= "</div>\n";
+
+ return array($label,$input);
+ }
+
+ function update($input) {
+ if (is_null($input)) return false;
+ if ($this->is_protected()) return false;
+
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ if ($value == $input) return false;
+
+ if (!in_array($input, $this->_choices)) return false;
+
+ $this->_local = $input;
+ return true;
+ }
+ }
+}
+
+
+if (!class_exists('setting_dirchoice')) {
+ class setting_dirchoice extends setting_multichoice {
+
+ var $_dir = '';
+
+ function initialize($default,$local,$protected) {
+
+ // populate $this->_choices with a list of directories
+ $list = array();
+
+ if ($dh = @opendir($this->_dir)) {
+ while (false !== ($entry = readdir($dh))) {
+ if ($entry == '.' || $entry == '..') continue;
+ if ($this->_pattern && !preg_match($this->_pattern,$entry)) continue;
+
+ $file = (is_link($this->_dir.$entry)) ? readlink($this->_dir.$entry) : $this->_dir.$entry;
+ if (is_dir($file)) $list[] = $entry;
+ }
+ closedir($dh);
+ }
+ sort($list);
+ $this->_choices = $list;
+
+ parent::initialize($default,$local,$protected);
+ }
+ }
+}
+
+
+if (!class_exists('setting_hidden')) {
+ class setting_hidden extends setting {
+ // Used to explicitly ignore a setting in the configuration manager.
+ }
+}
+
+if (!class_exists('setting_fieldset')) {
+ class setting_fieldset extends setting {
+ // A do-nothing class used to detect the 'fieldset' type.
+ // Used to start a new settings "display-group".
+ }
+}
+
+if (!class_exists('setting_undefined')) {
+ class setting_undefined extends setting_hidden {
+ // A do-nothing class used to detect settings with no metadata entry.
+ // Used internaly to hide undefined settings, and generate the undefined settings list.
+ }
+}
+
+if (!class_exists('setting_no_class')) {
+ class setting_no_class extends setting_undefined {
+ // A do-nothing class used to detect settings with a missing setting class.
+ // Used internaly to hide undefined settings, and generate the undefined settings list.
+ }
+}
+
+if (!class_exists('setting_no_default')) {
+ class setting_no_default extends setting_undefined {
+ // A do-nothing class used to detect settings with no default value.
+ // Used internaly to hide undefined settings, and generate the undefined settings list.
+ }
+}
+
+if (!class_exists('setting_multicheckbox')) {
+ class setting_multicheckbox extends setting_string {
+
+ var $_choices = array();
+ var $_combine = array();
+
+ function update($input) {
+ if ($this->is_protected()) return false;
+
+ // split any combined values + convert from array to comma separated string
+ $input = ($input) ? $input : array();
+ $input = $this->_array2str($input);
+
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ if ($value == $input) return false;
+
+ if ($this->_pattern && !preg_match($this->_pattern,$input)) {
+ $this->_error = true;
+ $this->_input = $input;
+ return false;
+ }
+
+ $this->_local = $input;
+ return true;
+ }
+
+ function html(&$plugin, $echo=false) {
+
+ $value = '';
+ $disable = '';
+
+ if ($this->is_protected()) {
+ $value = $this->_protected;
+ $disable = 'disabled="disabled"';
+ } else {
+ if ($echo && $this->_error) {
+ $value = $this->_input;
+ } else {
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ }
+ }
+
+ $key = htmlspecialchars($this->_key);
+
+ // convert from comma separated list into array + combine complimentary actions
+ $value = $this->_str2array($value);
+ $default = $this->_str2array($this->_default);
+
+ $input = '';
+ foreach ($this->_choices as $choice) {
+ $idx = array_search($choice, $value);
+ $idx_default = array_search($choice,$default);
+
+ $checked = ($idx !== false) ? 'checked="checked"' : '';
+
+ // ideally this would be handled using a second class of "default", however IE6 does not
+ // correctly support CSS selectors referencing multiple class names on the same element
+ // (e.g. .default.selection).
+ $class = (($idx !== false) == (false !== $idx_default)) ? " selectiondefault" : "";
+
+ $prompt = ($plugin->getLang($this->_key.'_'.$choice) ?
+ $plugin->getLang($this->_key.'_'.$choice) : htmlspecialchars($choice));
+
+ $input .= '<div class="selection'.$class.'">'."\n";
+ $input .= '<label for="config___'.$key.'_'.$choice.'">'.$prompt."</label>\n";
+ $input .= '<input id="config___'.$key.'_'.$choice.'" name="config['.$key.'][]" type="checkbox" class="checkbox" value="'.$choice.'" '.$disable.' '.$checked."/>\n";
+ $input .= "</div>\n";
+
+ // remove this action from the disabledactions array
+ if ($idx !== false) unset($value[$idx]);
+ if ($idx_default !== false) unset($default[$idx_default]);
+ }
+
+ // handle any remaining values
+ $other = join(',',$value);
+
+ $class = (count($default == count($value)) && (count($value) == count(array_intersect($value,$default)))) ?
+ " selectiondefault" : "";
+
+ $input .= '<div class="other'.$class.'">'."\n";
+ $input .= '<label for="config___'.$key.'_other">'.$plugin->getLang($key.'_other')."</label>\n";
+ $input .= '<input id="config___'.$key.'_other" name="config['.$key.'][other]" type="text" class="edit" value="'.htmlspecialchars($other).'" '.$disable." />\n";
+ $input .= "</div>\n";
+
+ $label = '<label>'.$this->prompt($plugin).'</label>';
+ return array($label,$input);
+ }
+
+ /**
+ * convert comma separated list to an array and combine any complimentary values
+ */
+ function _str2array($str) {
+ $array = explode(',',$str);
+
+ if (!empty($this->_combine)) {
+ foreach ($this->_combine as $key => $combinators) {
+ $idx = array();
+ foreach ($combinators as $val) {
+ if (($idx[] = array_search($val, $array)) === false) break;
+ }
+
+ if (count($idx) && $idx[count($idx)-1] !== false) {
+ foreach ($idx as $i) unset($array[$i]);
+ $array[] = $key;
+ }
+ }
+ }
+
+ return $array;
+ }
+
+ /**
+ * convert array of values + other back to a comma separated list, incl. splitting any combined values
+ */
+ function _array2str($input) {
+
+ // handle other
+ $other = trim($input['other']);
+ $other = !empty($other) ? explode(',',str_replace(' ','',$input['other'])) : array();
+ unset($input['other']);
+
+ $array = array_unique(array_merge($input, $other));
+
+ // deconstruct any combinations
+ if (!empty($this->_combine)) {
+ foreach ($this->_combine as $key => $combinators) {
+
+ $idx = array_search($key,$array);
+ if ($idx !== false) {
+ unset($array[$idx]);
+ $array = array_merge($array, $combinators);
+ }
+ }
+ }
+
+ return join(',',array_unique($array));
+ }
+ }
+}
+
+/**
+ * Provide php_strip_whitespace (php5 function) functionality
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+if (!function_exists('php_strip_whitespace')) {
+
+ if (function_exists('token_get_all')) {
+
+ if (!defined('T_ML_COMMENT')) {
+ define('T_ML_COMMENT', T_COMMENT);
+ } else {
+ define('T_DOC_COMMENT', T_ML_COMMENT);
+ }
+
+ /**
+ * modified from original
+ * source Google Groups, php.general, by David Otton
+ */
+ function php_strip_whitespace($file) {
+ if (!@is_readable($file)) return '';
+
+ $in = join('',@file($file));
+ $out = '';
+
+ $tokens = token_get_all($in);
+
+ foreach ($tokens as $token) {
+ if (is_string ($token)) {
+ $out .= $token;
+ } else {
+ list ($id, $text) = $token;
+ switch ($id) {
+ case T_COMMENT : // fall thru
+ case T_ML_COMMENT : // fall thru
+ case T_DOC_COMMENT : // fall thru
+ case T_WHITESPACE :
+ break;
+ default : $out .= $text; break;
+ }
+ }
+ }
+ return ($out);
+ }
+
+ } else {
+
+ function is_whitespace($c) { return (strpos("\t\n\r ",$c) !== false); }
+ function is_quote($c) { return (strpos("\"'",$c) !== false); }
+ function is_escaped($s,$i) {
+ $idx = $i-1;
+ while(($idx>=0) && ($s{$idx} == '\\')) $idx--;
+ return (($i - $idx + 1) % 2);
+ }
+
+ function is_commentopen($str, $i) {
+ if ($str{$i} == '#') return "\n";
+ if ($str{$i} == '/') {
+ if ($str{$i+1} == '/') return "\n";
+ if ($str{$i+1} == '*') return "*/";
+ }
+
+ return false;
+ }
+
+ function php_strip_whitespace($file) {
+
+ if (!@is_readable($file)) return '';
+
+ $contents = join('',@file($file));
+ $out = '';
+
+ $state = 0;
+ for ($i=0; $i<strlen($contents); $i++) {
+ if (!$state && is_whitespace($contents{$i})) continue;
+
+ if (!$state && ($c_close = is_commentopen($contents, $i))) {
+ $c_open_len = ($contents{$i} == '/') ? 2 : 1;
+ $i = strpos($contents, $c_close, $i+$c_open_len)+strlen($c_close)-1;
+ continue;
+ }
+
+ $out .= $contents{$i};
+ if (is_quote($contents{$i})) {
+ if (($state == $contents{$i}) && !is_escaped($contents, $i)) { $state = 0; continue; }
+ if (!$state) {$state = $contents{$i}; continue; }
+ }
+ }
+
+ return $out;
+ }
+ }
+}
diff --git a/lib/plugins/config/settings/config.metadata.php b/lib/plugins/config/settings/config.metadata.php
new file mode 100644
index 000000000..af815e8dc
--- /dev/null
+++ b/lib/plugins/config/settings/config.metadata.php
@@ -0,0 +1,216 @@
+<?php
+/**
+ * Metadata for configuration manager plugin
+ *
+ * Note: This file should be included within a function to ensure it
+ * doesn't clash with the settings it is describing.
+ *
+ * Format:
+ * $meta[<setting name>] = array(<handler class id>,<param name> => <param value>);
+ *
+ * <handler class id> is the handler class name without the "setting_" prefix
+ *
+ * Defined classes:
+ * Generic (source: settings/config.class.php)
+ * -------------------------------------------
+ * '' - default class ('setting'), textarea, minimal input validation, setting output in quotes
+ * 'string' - single line text input, minimal input validation, setting output in quotes
+ * 'numeric' - text input, accepts numbers and arithmetic operators, setting output without quotes
+ * if given the '_min' and '_max' parameters are used for validation
+ * 'numericopt' - like above, but accepts empty values
+ * 'onoff' - checkbox input, setting output 0|1
+ * 'multichoice' - select input (single choice), setting output with quotes, required _choices parameter
+ * 'email' - text input, input must conform to email address format, setting output in quotes
+ * 'richemail' - text input, input must conform to email address format but accepts variables and
+ * emails with a real name prepended (when email address is given in <>)
+ * 'password' - password input, minimal input validation, setting output text in quotes, maybe encoded
+ * according to the _code parameter
+ * 'dirchoice' - as multichoice, selection choices based on folders found at location specified in _dir
+ * parameter (required). A pattern can be used to restrict the folders to only those which
+ * match the pattern.
+ * 'multicheckbox'- a checkbox for each choice plus an "other" string input, config file setting is a comma
+ * separated list of checked choices
+ * 'fieldset' - used to group configuration settings, but is not itself a setting. To make this clear in
+ * the language files the keys for this type should start with '_'.
+ *
+ * Single Setting (source: settings/extra.class.php)
+ * -------------------------------------------------
+ * 'savedir' - as 'setting', input tested against initpath() (inc/init.php)
+ * 'sepchar' - as multichoice, selection constructed from string of valid values
+ * 'authtype' - as 'setting', input validated against a valid php file at expected location for auth files
+ * 'im_convert' - as 'setting', input must exist and be an im_convert module
+ * 'disableactions' - as 'setting'
+ * 'compression' - no additional parameters. checks php installation supports possible compression alternatives
+ *
+ * Any setting commented or missing will use 'setting' class - text input, minimal validation, quoted output
+ *
+ * Defined parameters:
+ * '_pattern' - string, a preg pattern. input is tested against this pattern before being accepted
+ * optional all classes, except onoff & multichoice which ignore it
+ * '_choices' - array of choices. used to populate a selection box. choice will be replaced by a localised
+ * language string, indexed by <setting name>_o_<choice>, if one exists
+ * required by 'multichoice' & 'multicheckbox' classes, ignored by others
+ * '_dir' - location of directory to be used to populate choice list
+ * required by 'dirchoice' class, ignored by other classes
+ * '_combine' - complimentary output setting values which can be combined into a single display checkbox
+ * optional for 'multicheckbox', ignored by other classes
+ * '_code' - encoding method to use, accepted values: 'base64','uuencode','plain'. defaults to plain.
+ * '_min' - minimum numeric value, optional for 'numeric' and 'numericopt', ignored by others
+ * '_max' - maximum numeric value, optional for 'numeric' and 'numericopt', ignored by others
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+// ---------------[ settings for settings ]------------------------------
+$config['format'] = 'php'; // format of setting files, supported formats: php
+$config['varname'] = 'conf'; // name of the config variable, sans $
+
+// this string is written at the top of the rewritten settings file,
+// !! do not include any comment indicators !!
+// this value can be overriden when calling save_settings() method
+$config['heading'] = 'Dokuwiki\'s Main Configuration File - Local Settings';
+
+/* DEPRECATED
+// ---------------[ setting files ]--------------------------------------
+// these values can be string expressions, they will be eval'd before use
+$file['local'] = "DOKU_CONF.'local.php'"; // mandatory (file doesn't have to exist)
+$file['default'] = "DOKU_CONF.'dokuwiki.php'"; // optional
+$file['protected'] = "DOKU_CONF.'local.protected.php'"; // optional
+ */
+
+// test value (FIXME, remove before publishing)
+//$meta['test'] = array('multichoice','_choices' => array(''));
+
+// --------------[ setting metadata ]------------------------------------
+// - for description of format and fields see top of file
+// - order the settings in the order you wish them to appear
+// - any settings not mentioned will come after the last setting listed and
+// will use the default class with no parameters
+
+$meta['_basic'] = array('fieldset');
+$meta['title'] = array('string');
+$meta['start'] = array('string','_pattern' => '!^[^:;/]+$!'); // don't accept namespaces
+$meta['lang'] = array('dirchoice','_dir' => DOKU_INC.'inc/lang/');
+$meta['template'] = array('dirchoice','_dir' => DOKU_INC.'lib/tpl/','_pattern' => '/^[\w-]+$/');
+$meta['tagline'] = array('string');
+$meta['sidebar'] = array('string');
+$meta['license'] = array('license');
+$meta['savedir'] = array('savedir');
+$meta['basedir'] = array('string');
+$meta['baseurl'] = array('string');
+$meta['cookiedir'] = array('string');
+$meta['dmode'] = array('numeric','_pattern' => '/0[0-7]{3,4}/'); // only accept octal representation
+$meta['fmode'] = array('numeric','_pattern' => '/0[0-7]{3,4}/'); // only accept octal representation
+$meta['allowdebug'] = array('onoff');
+
+$meta['_display'] = array('fieldset');
+$meta['recent'] = array('numeric');
+$meta['breadcrumbs'] = array('numeric','_min' => 0);
+$meta['youarehere'] = array('onoff');
+$meta['fullpath'] = array('onoff');
+$meta['typography'] = array('multichoice','_choices' => array(0,1,2));
+$meta['dformat'] = array('string');
+$meta['signature'] = array('string');
+$meta['showuseras'] = array('multichoice','_choices' => array('loginname','username','email','email_link'));
+$meta['toptoclevel'] = array('multichoice','_choices' => array(1,2,3,4,5)); // 5 toc levels
+$meta['tocminheads'] = array('multichoice','_choices' => array(0,1,2,3,4,5,10,15,20));
+$meta['maxtoclevel'] = array('multichoice','_choices' => array(0,1,2,3,4,5));
+$meta['maxseclevel'] = array('multichoice','_choices' => array(0,1,2,3,4,5)); // 0 for no sec edit buttons
+$meta['camelcase'] = array('onoff');
+$meta['deaccent'] = array('multichoice','_choices' => array(0,1,2));
+$meta['useheading'] = array('multichoice','_choices' => array(0,'navigation','content',1));
+$meta['refcheck'] = array('onoff');
+$meta['refshow'] = array('numeric');
+
+$meta['_authentication'] = array('fieldset');
+$meta['useacl'] = array('onoff');
+$meta['autopasswd'] = array('onoff');
+$meta['authtype'] = array('authtype');
+$meta['passcrypt'] = array('multichoice','_choices' => array('smd5','md5','apr1','sha1','ssha','lsmd5','crypt','mysql','my411','kmd5','pmd5','hmd5','bcrypt'));
+$meta['defaultgroup']= array('string');
+$meta['superuser'] = array('string');
+$meta['manager'] = array('string');
+$meta['profileconfirm'] = array('onoff');
+$meta['rememberme'] = array('onoff');
+$meta['registernotify'] = array('email');
+$meta['disableactions'] = array('disableactions',
+ '_choices' => array('backlink','index','recent','revisions','search','subscription','register','resendpwd','profile','edit','wikicode','check'),
+ '_combine' => array('subscription' => array('subscribe','unsubscribe'), 'wikicode' => array('source','export_raw')));
+$meta['sneaky_index'] = array('onoff');
+$meta['auth_security_timeout'] = array('numeric');
+$meta['securecookie'] = array('onoff');
+$meta['xmlrpc'] = array('onoff');
+$meta['xmlrpcuser'] = array('string');
+
+$meta['_anti_spam'] = array('fieldset');
+$meta['usewordblock']= array('onoff');
+$meta['relnofollow'] = array('onoff');
+$meta['indexdelay'] = array('numeric');
+$meta['mailguard'] = array('multichoice','_choices' => array('visible','hex','none'));
+$meta['iexssprotect']= array('onoff');
+
+$meta['_editing'] = array('fieldset');
+$meta['usedraft'] = array('onoff');
+$meta['htmlok'] = array('onoff');
+$meta['phpok'] = array('onoff');
+$meta['notify'] = array('email', '_multiple' => true);
+$meta['subscribers'] = array('onoff');
+$meta['subscribe_time'] = array('numeric');
+$meta['locktime'] = array('numeric');
+$meta['cachetime'] = array('numeric');
+
+$meta['_links'] = array('fieldset');
+$meta['target____wiki'] = array('string');
+$meta['target____interwiki'] = array('string');
+$meta['target____extern'] = array('string');
+$meta['target____media'] = array('string');
+$meta['target____windows'] = array('string');
+
+$meta['_media'] = array('fieldset');
+$meta['mediarevisions'] = array('onoff');
+$meta['gdlib'] = array('multichoice','_choices' => array(0,1,2));
+$meta['im_convert'] = array('im_convert');
+$meta['jpg_quality'] = array('numeric','_pattern' => '/^100$|^[1-9]?[0-9]$/'); //(0-100)
+$meta['fetchsize'] = array('numeric');
+
+$meta['_advanced'] = array('fieldset');
+$meta['updatecheck'] = array('onoff');
+$meta['userewrite'] = array('multichoice','_choices' => array(0,1,2));
+$meta['useslash'] = array('onoff');
+$meta['sepchar'] = array('sepchar');
+$meta['canonical'] = array('onoff');
+$meta['fnencode'] = array('multichoice','_choices' => array('url','safe','utf-8'));
+$meta['autoplural'] = array('onoff');
+$meta['mailfrom'] = array('richemail');
+$meta['mailprefix'] = array('string');
+$meta['compress'] = array('onoff');
+$meta['cssdatauri'] = array('numeric','_pattern' => '/^\d+$/');
+$meta['gzip_output'] = array('onoff');
+$meta['hidepages'] = array('string');
+$meta['send404'] = array('onoff');
+$meta['compression'] = array('compression');
+$meta['sitemap'] = array('numeric');
+$meta['rss_type'] = array('multichoice','_choices' => array('rss','rss1','rss2','atom','atom1'));
+$meta['rss_linkto'] = array('multichoice','_choices' => array('diff','page','rev','current'));
+$meta['rss_content'] = array('multichoice','_choices' => array('abstract','diff','htmldiff','html'));
+$meta['rss_update'] = array('numeric');
+$meta['recent_days'] = array('numeric');
+$meta['rss_show_summary'] = array('onoff');
+$meta['broken_iua'] = array('onoff');
+$meta['xsendfile'] = array('multichoice','_choices' => array(0,1,2,3));
+$meta['renderer_xhtml'] = array('renderer','_format' => 'xhtml','_choices' => array('xhtml'));
+$meta['readdircache'] = array('numeric');
+
+$meta['_network'] = array('fieldset');
+$meta['proxy____host'] = array('string','_pattern' => '#^(|[a-z0-9\-\.+]+)$#i');
+$meta['proxy____port'] = array('numericopt');
+$meta['proxy____user'] = array('string');
+$meta['proxy____pass'] = array('password','_code' => 'base64');
+$meta['proxy____ssl'] = array('onoff');
+$meta['proxy____except'] = array('string');
+$meta['safemodehack'] = array('onoff');
+$meta['ftp____host'] = array('string','_pattern' => '#^(|[a-z0-9\-\.+]+)$#i');
+$meta['ftp____port'] = array('numericopt');
+$meta['ftp____user'] = array('string');
+$meta['ftp____pass'] = array('password','_code' => 'base64');
+$meta['ftp____root'] = array('string');
+
diff --git a/lib/plugins/config/settings/extra.class.php b/lib/plugins/config/settings/extra.class.php
new file mode 100644
index 000000000..b4e35b1cc
--- /dev/null
+++ b/lib/plugins/config/settings/extra.class.php
@@ -0,0 +1,175 @@
+<?php
+/**
+ * additional setting classes specific to these settings
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+
+if (!class_exists('setting_sepchar')) {
+ class setting_sepchar extends setting_multichoice {
+
+ function setting_sepchar($key,$param=NULL) {
+ $str = '_-.';
+ for ($i=0;$i<strlen($str);$i++) $this->_choices[] = $str{$i};
+
+ // call foundation class constructor
+ $this->setting($key,$param);
+ }
+ }
+}
+
+if (!class_exists('setting_savedir')) {
+ class setting_savedir extends setting_string {
+
+ function update($input) {
+ if ($this->is_protected()) return false;
+
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ if ($value == $input) return false;
+
+ if (!init_path($input)) {
+ $this->_error = true;
+ $this->_input = $input;
+ return false;
+ }
+
+ $this->_local = $input;
+ return true;
+ }
+ }
+}
+
+if (!class_exists('setting_authtype')) {
+ class setting_authtype extends setting_multichoice {
+
+ function initialize($default,$local,$protected) {
+
+ // populate $this->_choices with a list of available auth mechanisms
+ $authtypes = glob(DOKU_INC.'inc/auth/*.class.php');
+ $authtypes = preg_replace('#^.*/([^/]*)\.class\.php$#i','$1', $authtypes);
+ $authtypes = array_diff($authtypes, array('basic'));
+ sort($authtypes);
+
+ $this->_choices = $authtypes;
+
+ parent::initialize($default,$local,$protected);
+ }
+ }
+}
+
+if (!class_exists('setting_im_convert')) {
+ class setting_im_convert extends setting_string {
+
+ function update($input) {
+ if ($this->is_protected()) return false;
+
+ $input = trim($input);
+
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ if ($value == $input) return false;
+
+ if ($input && !@file_exists($input)) {
+ $this->_error = true;
+ $this->_input = $input;
+ return false;
+ }
+
+ $this->_local = $input;
+ return true;
+ }
+ }
+}
+
+if (!class_exists('setting_disableactions')) {
+ class setting_disableactions extends setting_multicheckbox {
+
+ function html(&$plugin, $echo=false) {
+ global $lang;
+
+ // make some language adjustments (there must be a better way)
+ // transfer some DokuWiki language strings to the plugin
+ if (!$plugin->localised) $this->setupLocale();
+ $plugin->lang[$this->_key.'_revisions'] = $lang['btn_revs'];
+
+ foreach ($this->_choices as $choice)
+ if (isset($lang['btn_'.$choice])) $plugin->lang[$this->_key.'_'.$choice] = $lang['btn_'.$choice];
+
+ return parent::html($plugin, $echo);
+ }
+ }
+}
+
+if (!class_exists('setting_compression')) {
+ class setting_compression extends setting_multichoice {
+
+ var $_choices = array('0'); // 0 = no compression, always supported
+
+ function initialize($default,$local,$protected) {
+
+ // populate _choices with the compression methods supported by this php installation
+ if (function_exists('gzopen')) $this->_choices[] = 'gz';
+ if (function_exists('bzopen')) $this->_choices[] = 'bz2';
+
+ parent::initialize($default,$local,$protected);
+ }
+ }
+}
+
+if (!class_exists('setting_license')) {
+ class setting_license extends setting_multichoice {
+
+ var $_choices = array(''); // none choosen
+
+ function initialize($default,$local,$protected) {
+ global $license;
+
+ foreach($license as $key => $data){
+ $this->_choices[] = $key;
+ $this->lang[$this->_key.'_o_'.$key] = $data['name'];
+ }
+
+ parent::initialize($default,$local,$protected);
+ }
+ }
+}
+
+
+if (!class_exists('setting_renderer')) {
+ class setting_renderer extends setting_multichoice {
+ var $_prompts = array();
+
+ function initialize($default,$local,$protected) {
+ $format = $this->_format;
+
+ foreach (plugin_list('renderer') as $plugin) {
+ $renderer =& plugin_load('renderer',$plugin);
+ if (method_exists($renderer,'canRender') && $renderer->canRender($format)) {
+ $this->_choices[] = $plugin;
+
+ $info = $renderer->getInfo();
+ $this->_prompts[$plugin] = $info['name'];
+ }
+ }
+
+ parent::initialize($default,$local,$protected);
+ }
+
+ function html(&$plugin, $echo=false) {
+
+ // make some language adjustments (there must be a better way)
+ // transfer some plugin names to the config plugin
+ if (!$plugin->localised) $this->setupLocale();
+
+ foreach ($this->_choices as $choice) {
+ if (!isset($plugin->lang[$this->_key.'_o_'.$choice])) {
+ if (!isset($this->_prompts[$choice])) {
+ $plugin->lang[$this->_key.'_o_'.$choice] = sprintf($plugin->lang['renderer__core'],$choice);
+ } else {
+ $plugin->lang[$this->_key.'_o_'.$choice] = sprintf($plugin->lang['renderer__plugin'],$this->_prompts[$choice]);
+ }
+ }
+ }
+ return parent::html($plugin, $echo);
+ }
+ }
+}
diff --git a/lib/plugins/config/style.css b/lib/plugins/config/style.css
new file mode 100644
index 000000000..65c44a758
--- /dev/null
+++ b/lib/plugins/config/style.css
@@ -0,0 +1,136 @@
+/* plugin:configmanager */
+#config__manager div.success,
+#config__manager div.error,
+#config__manager div.info {
+ background-position: 0.5em;
+ padding: 0.5em;
+ text-align: center;
+}
+
+#config__manager fieldset {
+ margin: 1em;
+ width: auto;
+ margin-bottom: 2em;
+ background-color: __background_alt__;
+ color: __text__;
+ padding: 0 1em;
+}
+#config__manager legend {
+ font-size: 1.25em;
+}
+
+#config__manager form { }
+#config__manager table {
+ margin: 1em 0;
+ width: 100%;
+}
+
+#config__manager fieldset td {
+ text-align: left;
+}
+#config__manager fieldset td.value {
+ /* fixed data column width */
+ width: 31em;
+}
+
+#config__manager td.label {
+ padding: 0.8em 0 0.6em 1em;
+ vertical-align: top;
+}
+
+#config__manager td.label label {
+ clear: left;
+ display: block;
+}
+#config__manager td.label img {
+ padding: 0 10px;
+ vertical-align: middle;
+ float: right;
+}
+
+#config__manager td.label span.outkey {
+ font-size: 70%;
+ margin-top: -1.7em;
+ margin-left: -1em;
+ display: block;
+ background-color: __background__;
+ color: __text_neu__;
+ float: left;
+ padding: 0 0.1em;
+ position: relative;
+ z-index: 1;
+}
+
+#config__manager td input.edit {
+ width: 30em;
+}
+#config__manager td .input {
+ width: 30.8em;
+}
+#config__manager td select.edit { }
+#config__manager td textarea.edit {
+ width: 27.5em;
+ height: 4em;
+}
+
+#config__manager tr .input,
+#config__manager tr input,
+#config__manager tr textarea,
+#config__manager tr select {
+ background-color: #fff;
+ color: #000;
+}
+
+#config__manager tr.default .input,
+#config__manager tr.default input,
+#config__manager tr.default textarea,
+#config__manager tr.default select,
+#config__manager .selectiondefault {
+ background-color: #ccddff;
+ color: #000;
+}
+
+#config__manager tr.protected .input,
+#config__manager tr.protected input,
+#config__manager tr.protected textarea,
+#config__manager tr.protected select,
+#config__manager tr.protected .selection {
+ background-color: #ffcccc!important;
+ color: #000 !important;
+}
+
+#config__manager td.error { background-color: red; color: #000; }
+
+#config__manager .selection {
+ width: 14.8em;
+ float: left;
+ margin: 0 0.3em 2px 0;
+}
+
+#config__manager .selection label {
+ float: right;
+ width: 14em;
+ font-size: 90%;
+}
+
+
+/* IE6 correction */
+* html #config__manager .selection label {
+ padding-top: 2px;
+}
+
+#config__manager .selection input.checkbox {
+ padding-left: 0.7em;
+}
+
+#config__manager .other {
+ clear: both;
+ padding-top: 0.5em;
+}
+
+#config__manager .other label {
+ padding-left: 2px;
+ font-size: 90%;
+}
+
+/* end plugin:configmanager */
diff --git a/lib/plugins/index.html b/lib/plugins/index.html
new file mode 100644
index 000000000..d614603ac
--- /dev/null
+++ b/lib/plugins/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="refresh" content="0; URL=../../" />
+<meta name="robots" content="noindex" />
+<title>nothing here...</title>
+</head>
+<body>
+<!-- this is just here to prevent directory browsing -->
+</body>
+</html>
diff --git a/lib/plugins/info/lang/sl/lang.php b/lib/plugins/info/lang/sl/lang.php
new file mode 100644
index 000000000..62936947c
--- /dev/null
+++ b/lib/plugins/info/lang/sl/lang.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * English language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ */
+
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['onHidden'] = 'Click to display ⇲';
+$lang['onVisible'] = 'Click to hide ⇱';
diff --git a/lib/plugins/info/plugin.info.txt b/lib/plugins/info/plugin.info.txt
new file mode 100644
index 000000000..2432225f1
--- /dev/null
+++ b/lib/plugins/info/plugin.info.txt
@@ -0,0 +1,6 @@
+author Andreas Gohr
+email andi@splitbrain.org
+date 2008-09-12
+name Info Plugin
+desc Displays information about various DokuWiki internals
+url http://dokuwiki.org/plugin:info
diff --git a/lib/plugins/info/syntax.php b/lib/plugins/info/syntax.php
new file mode 100644
index 000000000..9aedbf0aa
--- /dev/null
+++ b/lib/plugins/info/syntax.php
@@ -0,0 +1,256 @@
+<?php
+/**
+ * Info Plugin: Displays information about various DokuWiki internals
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Esther Brunner <wikidesign@gmail.com>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * All DokuWiki plugins to extend the parser/rendering mechanism
+ * need to inherit from this class
+ */
+class syntax_plugin_info extends DokuWiki_Syntax_Plugin {
+
+ /**
+ * return some info
+ */
+ function getInfo(){
+ return array(
+ 'author' => 'Andreas Gohr',
+ 'email' => 'andi@splitbrain.org',
+ 'date' => '2008-09-12',
+ 'name' => 'Info Plugin',
+ 'desc' => 'Displays information about various DokuWiki internals',
+ 'url' => 'http://dokuwiki.org/plugin:info',
+ );
+ }
+
+ /**
+ * What kind of syntax are we?
+ */
+ function getType(){
+ return 'substition';
+ }
+
+ /**
+ * What about paragraphs?
+ */
+ function getPType(){
+ return 'block';
+ }
+
+ /**
+ * Where to sort in?
+ */
+ function getSort(){
+ return 155;
+ }
+
+
+ /**
+ * Connect pattern to lexer
+ */
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('~~INFO:\w+~~',$mode,'plugin_info');
+ }
+
+
+ /**
+ * Handle the match
+ */
+ function handle($match, $state, $pos, &$handler){
+ $match = substr($match,7,-2); //strip ~~INFO: from start and ~~ from end
+ return array(strtolower($match));
+ }
+
+ /**
+ * Create output
+ */
+ function render($format, &$renderer, $data) {
+ if($format == 'xhtml'){
+ //handle various info stuff
+ switch ($data[0]){
+ case 'version':
+ $renderer->doc .= getVersion();
+ break;
+ case 'syntaxmodes':
+ $renderer->doc .= $this->_syntaxmodes_xhtml();
+ break;
+ case 'syntaxtypes':
+ $renderer->doc .= $this->_syntaxtypes_xhtml();
+ break;
+ case 'syntaxplugins':
+ $this->_plugins_xhtml('syntax', $renderer);
+ break;
+ case 'adminplugins':
+ $this->_plugins_xhtml('admin', $renderer);
+ break;
+ case 'actionplugins':
+ $this->_plugins_xhtml('action', $renderer);
+ break;
+ case 'rendererplugins':
+ $this->_plugins_xhtml('renderer', $renderer);
+ break;
+ case 'helperplugins':
+ $this->_plugins_xhtml('helper', $renderer);
+ break;
+ case 'helpermethods':
+ $this->_helpermethods_xhtml($renderer);
+ break;
+ default:
+ $renderer->doc .= "no info about ".htmlspecialchars($data[0]);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * list all installed plugins
+ *
+ * uses some of the original renderer methods
+ */
+ function _plugins_xhtml($type, &$renderer){
+ global $lang;
+ $renderer->doc .= '<ul>';
+
+ $plugins = plugin_list($type);
+ $plginfo = array();
+
+ // remove subparts
+ foreach($plugins as $p){
+ if (!$po =& plugin_load($type,$p)) continue;
+ list($name,$part) = explode('_',$p,2);
+ $plginfo[$name] = $po->getInfo();
+ }
+
+ // list them
+ foreach($plginfo as $info){
+ $renderer->doc .= '<li><div class="li">';
+ $renderer->externallink($info['url'],$info['name']);
+ $renderer->doc .= ' ';
+ $renderer->doc .= '<em>'.$info['date'].'</em>';
+ $renderer->doc .= ' ';
+ $renderer->doc .= $lang['by'];
+ $renderer->doc .= ' ';
+ $renderer->emaillink($info['email'],$info['author']);
+ $renderer->doc .= '<br />';
+ $renderer->doc .= strtr(hsc($info['desc']),array("\n"=>"<br />"));
+ $renderer->doc .= '</div></li>';
+ unset($po);
+ }
+
+ $renderer->doc .= '</ul>';
+ }
+
+ /**
+ * list all installed plugins
+ *
+ * uses some of the original renderer methods
+ */
+ function _helpermethods_xhtml(&$renderer){
+ global $lang;
+
+ $plugins = plugin_list('helper');
+ foreach($plugins as $p){
+ if (!$po =& plugin_load('helper',$p)) continue;
+
+ if (!method_exists($po, 'getMethods')) continue;
+ $methods = $po->getMethods();
+ $info = $po->getInfo();
+
+ $hid = $this->_addToTOC($info['name'], 2, $renderer);
+ $doc = '<h2><a name="'.$hid.'" id="'.$hid.'">'.hsc($info['name']).'</a></h2>';
+ $doc .= '<div class="level2">';
+ $doc .= '<p>'.strtr(hsc($info['desc']), array("\n"=>"<br />")).'</p>';
+ $doc .= '<pre class="code">$'.$p." =& plugin_load('helper', '".$p."');</pre>";
+ $doc .= '</div>';
+ foreach ($methods as $method){
+ $title = '$'.$p.'->'.$method['name'].'()';
+ $hid = $this->_addToTOC($title, 3, $renderer);
+ $doc .= '<h3><a name="'.$hid.'" id="'.$hid.'">'.hsc($title).'</a></h3>';
+ $doc .= '<div class="level3">';
+ $doc .= '<div class="table"><table class="inline"><tbody>';
+ $doc .= '<tr><th>Description</th><td colspan="2">'.$method['desc'].
+ '</td></tr>';
+ if ($method['params']){
+ $c = count($method['params']);
+ $doc .= '<tr><th rowspan="'.$c.'">Parameters</th><td>';
+ $params = array();
+ foreach ($method['params'] as $desc => $type){
+ $params[] = hsc($desc).'</td><td>'.hsc($type);
+ }
+ $doc .= join($params, '</td></tr><tr><td>').'</td></tr>';
+ }
+ if ($method['return']){
+ $doc .= '<tr><th>Return value</th><td>'.hsc(key($method['return'])).
+ '</td><td>'.hsc(current($method['return'])).'</td></tr>';
+ }
+ $doc .= '</tbody></table></div>';
+ $doc .= '</div>';
+ }
+ unset($po);
+
+ $renderer->doc .= $doc;
+ }
+ }
+
+ /**
+ * lists all known syntax types and their registered modes
+ */
+ function _syntaxtypes_xhtml(){
+ global $PARSER_MODES;
+ $doc = '';
+
+ $doc .= '<div class="table"><table class="inline"><tbody>';
+ foreach($PARSER_MODES as $mode => $modes){
+ $doc .= '<tr>';
+ $doc .= '<td class="leftalign">';
+ $doc .= $mode;
+ $doc .= '</td>';
+ $doc .= '<td class="leftalign">';
+ $doc .= join(', ',$modes);
+ $doc .= '</td>';
+ $doc .= '</tr>';
+ }
+ $doc .= '</tbody></table></div>';
+ return $doc;
+ }
+
+ /**
+ * lists all known syntax modes and their sorting value
+ */
+ function _syntaxmodes_xhtml(){
+ $modes = p_get_parsermodes();
+ $doc = '';
+
+ foreach ($modes as $mode){
+ $doc .= $mode['mode'].' ('.$mode['sort'].'), ';
+ }
+ return $doc;
+ }
+
+ /**
+ * Adds a TOC item
+ */
+ function _addToTOC($text, $level, &$renderer){
+ global $conf;
+
+ if (($level >= $conf['toptoclevel']) && ($level <= $conf['maxtoclevel'])){
+ $hid = $renderer->_headerToLink($text, 'true');
+ $renderer->toc[] = array(
+ 'hid' => $hid,
+ 'title' => $text,
+ 'type' => 'ul',
+ 'level' => $level - $conf['toptoclevel'] + 1
+ );
+ }
+ return $hid;
+ }
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/plugins/plugin/admin.php b/lib/plugins/plugin/admin.php
new file mode 100644
index 000000000..b2108f185
--- /dev/null
+++ b/lib/plugins/plugin/admin.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ * Plugin management functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+// todo
+// - maintain a history of file modified
+// - allow a plugin to contain extras to be copied to the current template (extra/tpl/)
+// - to images (lib/images/) [ not needed, should go in lib/plugin/images/ ]
+
+require_once(DOKU_PLUGIN."/plugin/classes/ap_manage.class.php");
+
+//--------------------------[ GLOBALS ]------------------------------------------------
+// note: probably should be dokuwiki wide globals, where they can be accessed by pluginutils.php
+// global $plugin_types;
+// $plugin_types = array('syntax', 'admin');
+
+// plugins that are an integral part of dokuwiki, they shouldn't be disabled or deleted
+global $plugin_protected;
+$plugin_protected = array('acl','plugin','config','info','usermanager','revert');
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_plugin extends DokuWiki_Admin_Plugin {
+
+ var $disabled = 0;
+ var $plugin = '';
+ var $cmd = '';
+ var $handler = NULL;
+
+ var $functions = array('delete','update',/*'settings',*/'info'); // require a plugin name
+ var $commands = array('manage','download','enable'); // don't require a plugin name
+ var $plugin_list = array();
+
+ var $msg = '';
+ var $error = '';
+
+ function admin_plugin_plugin() {
+ global $conf;
+ $this->disabled = plugin_isdisabled('plugin');
+ }
+
+ /**
+ * return some info
+ */
+ function getInfo(){
+ $disabled = ($this->disabled) ? '(disabled)' : '';
+
+ return array(
+ 'author' => 'Christopher Smith',
+ 'email' => 'chris@jalakai.co.uk',
+ 'date' => '2009-11-11',
+ 'name' => 'Plugin Manager',
+ 'desc' => "Manage Plugins, including automated plugin installer $disabled",
+ 'url' => 'http://www.dokuwiki.org/plugin:plugin',
+ );
+ }
+
+
+ /**
+ * return sort order for position in admin menu
+ */
+ function getMenuSort() {
+ return 20;
+ }
+
+ /**
+ * handle user request
+ */
+ function handle() {
+ // enable direct access to language strings
+ $this->setupLocale();
+
+
+ $fn = $_REQUEST['fn'];
+ if (is_array($fn)) {
+ $this->cmd = key($fn);
+ $this->plugin = is_array($fn[$this->cmd]) ? key($fn[$this->cmd]) : null;
+ } else {
+ $this->cmd = $fn;
+ $this->plugin = null;
+ }
+ $this->_get_plugin_list();
+
+ // verify $_REQUEST vars
+ if (in_array($this->cmd, $this->commands)) {
+ $this->plugin = '';
+ } else if (!in_array($this->cmd, $this->functions) || !in_array($this->plugin, $this->plugin_list)) {
+ $this->cmd = 'manage';
+ $this->plugin = '';
+ }
+
+ if(($this->cmd != 'manage' || $this->plugin != '') && !checkSecurityToken()){
+ $this->cmd = 'manage';
+ $this->plugin = '';
+ }
+
+ // create object to handle the command
+ $class = "ap_".$this->cmd;
+ @require_once(DOKU_PLUGIN."/plugin/classes/$class.class.php");
+ if (!class_exists($class)){
+ $class = 'ap_manage';
+ }
+
+ $this->handler = new $class($this, $this->plugin);
+ $this->msg = $this->handler->process();
+
+ }
+
+ /**
+ * output appropriate html
+ */
+ function html() {
+ // enable direct access to language strings
+ $this->setupLocale();
+ $this->_get_plugin_list();
+
+ if ($this->handler === NULL) $this->handler = new ap_manage($this, $this->plugin);
+
+ ptln('<div id="plugin__manager">');
+ $this->handler->html();
+ ptln('</div><!-- #plugin_manager -->');
+ }
+
+ /**
+ * Returns a list of all plugins, including the disabled ones
+ */
+ function _get_plugin_list() {
+ if (empty($this->plugin_list)) {
+ $list = plugin_list('',true); // all plugins, including disabled ones
+ sort($list);
+ trigger_event('PLUGIN_PLUGINMANAGER_PLUGINLIST',$list);
+ $this->plugin_list = $list;
+ }
+ return $this->plugin_list;
+ }
+
+}
+
+
+
+
+
+
diff --git a/lib/plugins/plugin/classes/ap_delete.class.php b/lib/plugins/plugin/classes/ap_delete.class.php
new file mode 100644
index 000000000..581a6295f
--- /dev/null
+++ b/lib/plugins/plugin/classes/ap_delete.class.php
@@ -0,0 +1,28 @@
+<?php
+class ap_delete extends ap_manage {
+
+ function process() {
+
+ if (!$this->dir_delete(DOKU_PLUGIN.plugin_directory($this->manager->plugin))) {
+ $this->manager->error = sprintf($this->lang['error_delete'],$this->manager->plugin);
+ } else {
+ msg(sprintf($this->lang['deleted'],$this->plugin));
+ $this->refresh();
+ }
+ }
+
+ function html() {
+ parent::html();
+
+ ptln('<div class="pm_info">');
+ ptln('<h2>'.$this->lang['deleting'].'</h2>');
+
+ if ($this->manager->error) {
+ ptln('<div class="error">'.str_replace("\n","<br />",$this->manager->error).'</div>');
+ } else {
+ ptln('<p>'.sprintf($this->lang['deleted'],$this->plugin).'</p>');
+ }
+ ptln('</div>');
+ }
+}
+
diff --git a/lib/plugins/plugin/classes/ap_download.class.php b/lib/plugins/plugin/classes/ap_download.class.php
new file mode 100644
index 000000000..b2571f632
--- /dev/null
+++ b/lib/plugins/plugin/classes/ap_download.class.php
@@ -0,0 +1,294 @@
+<?php
+class ap_download extends ap_manage {
+
+ var $overwrite = true;
+
+ /**
+ * Initiate the plugin download
+ */
+ function process() {
+ global $lang;
+
+ $plugin_url = $_REQUEST['url'];
+ $this->download($plugin_url, $this->overwrite);
+ return '';
+ }
+
+ /**
+ * Print results of the download
+ */
+ function html() {
+ parent::html();
+
+ ptln('<div class="pm_info">');
+ ptln('<h2>'.$this->lang['downloading'].'</h2>');
+
+ if ($this->manager->error) {
+ ptln('<div class="error">'.str_replace("\n","<br />",$this->manager->error).'</div>');
+ } else if (count($this->downloaded) == 1) {
+ ptln('<p>'.sprintf($this->lang['downloaded'],$this->downloaded[0]).'</p>');
+ } else if (count($this->downloaded)) { // more than one plugin in the download
+ ptln('<p>'.$this->lang['downloads'].'</p>');
+ ptln('<ul>');
+ foreach ($this->downloaded as $plugin) {
+ ptln('<li><div class="li">'.$plugin.'</div></li>',2);
+ }
+ ptln('</ul>');
+ } else { // none found in download
+ ptln('<p>'.$this->lang['download_none'].'</p>');
+ }
+ ptln('</div>');
+ }
+
+ /**
+ * Process the downloaded file
+ */
+ function download($url, $overwrite=false) {
+ global $lang;
+ // check the url
+ $matches = array();
+ if (!preg_match("/[^\/]*$/", $url, $matches) || !$matches[0]) {
+ $this->manager->error = $this->lang['error_badurl']."\n";
+ return false;
+ }
+
+ $file = $matches[0];
+
+ if (!($tmp = io_mktmpdir())) {
+ $this->manager->error = $this->lang['error_dircreate']."\n";
+ return false;
+ }
+
+ if (!$file = io_download($url, "$tmp/", true, $file, 0)) {
+ $this->manager->error = sprintf($this->lang['error_download'],$url)."\n";
+ }
+
+ if (!$this->manager->error && !$this->decompress("$tmp/$file", $tmp)) {
+ $this->manager->error = sprintf($this->lang['error_decompress'],$file)."\n";
+ }
+
+ // search $tmp for the folder(s) that has been created
+ // move the folder(s) to lib/plugins/
+ if (!$this->manager->error) {
+ $result = array('old'=>array(), 'new'=>array());
+ if($this->find_folders($result,$tmp)){
+ // choose correct result array
+ if(count($result['new'])){
+ $install = $result['new'];
+ }else{
+ $install = $result['old'];
+ }
+
+ // now install all found items
+ foreach($install as $item){
+ // where to install?
+ if($item['type'] == 'template'){
+ $target = DOKU_INC.'lib/tpl/'.$item['base'];
+ }else{
+ $target = DOKU_INC.'lib/plugins/'.$item['base'];
+ }
+
+ // check to make sure we aren't overwriting anything
+ if (!$overwrite && @file_exists($target)) {
+ // remember our settings, ask the user to confirm overwrite, FIXME
+ continue;
+ }
+
+ $instruction = @file_exists($target) ? 'update' : 'install';
+
+ // copy action
+ if ($this->dircopy($item['tmp'], $target)) {
+ $this->downloaded[] = $item['base'];
+ $this->plugin_writelog($target, $instruction, array($url));
+ } else {
+ $this->manager->error .= sprintf($this->lang['error_copy']."\n", $item['base']);
+ }
+ }
+
+ } else {
+ $this->manager->error = $this->lang['error']."\n";
+ }
+ }
+
+ // cleanup
+ if ($tmp) $this->dir_delete($tmp);
+
+ if (!$this->manager->error) {
+ msg(sprintf($this->lang['packageinstalled'], count($this->downloaded), join(',',$this->downloaded)),1);
+ $this->refresh();
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Find out what was in the extracted directory
+ *
+ * Correct folders are searched recursively using the "*.info.txt" configs
+ * as indicator for a root folder. When such a file is found, it's base
+ * setting is used (when set). All folders found by this method are stored
+ * in the 'new' key of the $result array.
+ *
+ * For backwards compatibility all found top level folders are stored as
+ * in the 'old' key of the $result array.
+ *
+ * When no items are found in 'new' the copy mechanism should fall back
+ * the 'old' list.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param arrayref $result - results are stored here
+ * @param string $base - the temp directory where the package was unpacked to
+ * @param string $dir - a subdirectory. do not set. used by recursion
+ * @return bool - false on error
+ */
+ function find_folders(&$result,$base,$dir=''){
+ $dh = @opendir("$base/$dir");
+ if(!$dh) return false;
+ while (false !== ($f = readdir($dh))) {
+ if ($f == '.' || $f == '..' || $f == 'tmp') continue;
+
+ if(!is_dir("$base/$dir/$f")){
+ // it's a file -> check for config
+ if($f == 'plugin.info.txt'){
+ $info = array();
+ $info['type'] = 'plugin';
+ $info['tmp'] = "$base/$dir";
+ $conf = confToHash("$base/$dir/$f");
+ $info['base'] = basename($conf['base']);
+ if(!$info['base']) $info['base'] = basename("$base/$dir");
+ $result['new'][] = $info;
+ }elseif($f == 'template.info.txt'){
+ $info = array();
+ $info['type'] = 'template';
+ $info['tmp'] = "$base/$dir";
+ $conf = confToHash("$base/$dir/$f");
+ $info['base'] = basename($conf['base']);
+ if(!$info['base']) $info['base'] = basename("$base/$dir");
+ $result['new'][] = $info;
+ }
+ }else{
+ // it's a directory -> add to dir list for old method, then recurse
+ if(!$dir){
+ $info = array();
+ $info['type'] = 'plugin';
+ $info['tmp'] = "$base/$dir/$f";
+ $info['base'] = $f;
+ $result['old'][] = $info;
+ }
+ $this->find_folders($result,$base,"$dir/$f");
+ }
+ }
+ closedir($dh);
+ return true;
+ }
+
+
+ /**
+ * Decompress a given file to the given target directory
+ *
+ * Determines the compression type from the file extension
+ */
+ function decompress($file, $target) {
+ global $conf;
+
+ // decompression library doesn't like target folders ending in "/"
+ if (substr($target, -1) == "/") $target = substr($target, 0, -1);
+
+ $ext = $this->guess_archive($file);
+ if (in_array($ext, array('tar','bz','gz'))) {
+ switch($ext){
+ case 'bz':
+ $compress_type = TarLib::COMPRESS_BZIP;
+ break;
+ case 'gz':
+ $compress_type = TarLib::COMPRESS_GZIP;
+ break;
+ default:
+ $compress_type = TarLib::COMPRESS_NONE;
+ }
+
+ $tar = new TarLib($file, $compress_type);
+ if($tar->_initerror < 0){
+ if($conf['allowdebug']){
+ msg('TarLib Error: '.$tar->TarErrorStr($tar->_initerror),-1);
+ }
+ return false;
+ }
+ $ok = $tar->Extract(TarLib::FULL_ARCHIVE, $target, '', 0777);
+
+ if($ok<1){
+ if($conf['allowdebug']){
+ msg('TarLib Error: '.$tar->TarErrorStr($ok),-1);
+ }
+ return false;
+ }
+ return true;
+ } else if ($ext == 'zip') {
+
+ $zip = new ZipLib();
+ $ok = $zip->Extract($file, $target);
+
+ // FIXME sort something out for handling zip error messages meaningfully
+ return ($ok==-1?false:true);
+
+ }
+
+ // unsupported file type
+ return false;
+ }
+
+ /**
+ * Determine the archive type of the given file
+ *
+ * Reads the first magic bytes of the given file for content type guessing,
+ * if neither bz, gz or zip are recognized, tar is assumed.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @returns false if the file can't be read, otherwise an "extension"
+ */
+ function guess_archive($file){
+ $fh = fopen($file,'rb');
+ if(!$fh) return false;
+ $magic = fread($fh,5);
+ fclose($fh);
+
+ if(strpos($magic,"\x42\x5a") === 0) return 'bz';
+ if(strpos($magic,"\x1f\x8b") === 0) return 'gz';
+ if(strpos($magic,"\x50\x4b\x03\x04") === 0) return 'zip';
+ return 'tar';
+ }
+
+ /**
+ * Copy with recursive sub-directory support
+ */
+ function dircopy($src, $dst) {
+ global $conf;
+
+ if (is_dir($src)) {
+ if (!$dh = @opendir($src)) return false;
+
+ if ($ok = io_mkdir_p($dst)) {
+ while ($ok && (false !== ($f = readdir($dh)))) {
+ if ($f == '..' || $f == '.') continue;
+ $ok = $this->dircopy("$src/$f", "$dst/$f");
+ }
+ }
+
+ closedir($dh);
+ return $ok;
+
+ } else {
+ $exists = @file_exists($dst);
+
+ if (!@copy($src,$dst)) return false;
+ if (!$exists && !empty($conf['fperm'])) chmod($dst, $conf['fperm']);
+ @touch($dst,filemtime($src));
+ }
+
+ return true;
+ }
+
+
+}
+
diff --git a/lib/plugins/plugin/classes/ap_enable.class.php b/lib/plugins/plugin/classes/ap_enable.class.php
new file mode 100644
index 000000000..35450a907
--- /dev/null
+++ b/lib/plugins/plugin/classes/ap_enable.class.php
@@ -0,0 +1,49 @@
+<?php
+
+class ap_enable extends ap_manage {
+
+ var $enabled = array();
+
+ function process() {
+ global $plugin_protected;
+ $count_enabled = $count_disabled = 0;
+
+ $this->enabled = isset($_REQUEST['enabled']) ? $_REQUEST['enabled'] : array();
+
+ foreach ($this->manager->plugin_list as $plugin) {
+ if (in_array($plugin, $plugin_protected)) continue;
+
+ $new = in_array($plugin, $this->enabled);
+ $old = !plugin_isdisabled($plugin);
+
+ if ($new != $old) {
+ switch ($new) {
+ // enable plugin
+ case true :
+ if(plugin_enable($plugin)){
+ msg(sprintf($this->lang['enabled'],$plugin),1);
+ $count_enabled++;
+ }else{
+ msg(sprintf($this->lang['notenabled'],$plugin),-1);
+ }
+ break;
+ case false:
+ if(plugin_disable($plugin)){
+ msg(sprintf($this->lang['disabled'],$plugin),1);
+ $count_disabled++;
+ }else{
+ msg(sprintf($this->lang['notdisabled'],$plugin),-1);
+ }
+ break;
+ }
+ }
+ }
+
+ // refresh plugins, including expiring any dokuwiki cache(s)
+ if ($count_enabled || $count_disabled) {
+ $this->refresh();
+ }
+ }
+
+}
+
diff --git a/lib/plugins/plugin/classes/ap_info.class.php b/lib/plugins/plugin/classes/ap_info.class.php
new file mode 100644
index 000000000..44926c035
--- /dev/null
+++ b/lib/plugins/plugin/classes/ap_info.class.php
@@ -0,0 +1,144 @@
+<?php
+
+class ap_info extends ap_manage {
+
+ var $plugin_info = array(); // the plugin itself
+ var $details = array(); // any component plugins
+
+ function process() {
+
+ // sanity check
+ if (!$this->manager->plugin) { return; }
+
+ $component_list = $this->get_plugin_components($this->manager->plugin);
+ usort($component_list, array($this,'component_sort'));
+
+
+ foreach ($component_list as $component) {
+ if (($obj = &plugin_load($component['type'],$component['name'],false,true)) === NULL) continue;
+
+ $compname = explode('_',$component['name']);
+ if($compname[1]){
+ $compname = '['.$compname[1].']';
+ }else{
+ $compname = '';
+ }
+
+ $this->details[] = array_merge(
+ $obj->getInfo(),
+ array(
+ 'type' => $component['type'],
+ 'compname' => $compname
+ ));
+ unset($obj);
+ }
+
+ // review details to simplify things
+ foreach($this->details as $info) {
+ foreach($info as $item => $value) {
+ if (!isset($this->plugin_info[$item])) { $this->plugin_info[$item] = $value; continue; }
+ if ($this->plugin_info[$item] != $value) $this->plugin_info[$item] = '';
+ }
+ }
+ }
+
+ function html() {
+
+ // output the standard menu stuff
+ parent::html();
+
+ // sanity check
+ if (!$this->manager->plugin) { return; }
+
+ ptln('<div class="pm_info">');
+ ptln("<h2>".$this->manager->getLang('plugin')." {$this->manager->plugin}</h2>");
+
+ // collect pertinent information from the log
+ $installed = $this->plugin_readlog($this->manager->plugin, 'installed');
+ $source = $this->plugin_readlog($this->manager->plugin, 'url');
+ $updated = $this->plugin_readlog($this->manager->plugin, 'updated');
+ if (strrpos($updated, "\n") !== false) $updated = substr($updated, strrpos($updated, "\n")+1);
+
+ ptln("<dl>",2);
+ ptln("<dt>".$this->manager->getLang('source').'</dt><dd>'.($source ? $source : $this->manager->getLang('unknown'))."</dd>",4);
+ ptln("<dt>".$this->manager->getLang('installed').'</dt><dd>'.($installed ? $installed : $this->manager->getLang('unknown'))."</dd>",4);
+ if ($updated) ptln("<dt>".$this->manager->getLang('lastupdate').'</dt><dd>'.$updated."</dd>",4);
+ ptln("</dl>",2);
+
+ if (count($this->details) == 0) {
+ ptln("<p>".$this->manager->getLang('noinfo')."</p>",2);
+ } else {
+
+ ptln("<dl>",2);
+ if ($this->plugin_info['name']) ptln("<dt>".$this->manager->getLang('name')."</dt><dd>".$this->out($this->plugin_info['name'])."</dd>",4);
+ if ($this->plugin_info['date']) ptln("<dt>".$this->manager->getLang('date')."</dt><dd>".$this->out($this->plugin_info['date'])."</dd>",4);
+ if ($this->plugin_info['type']) ptln("<dt>".$this->manager->getLang('type')."</dt><dd>".$this->out($this->plugin_info['type'])."</dd>",4);
+ if ($this->plugin_info['desc']) ptln("<dt>".$this->manager->getLang('desc')."</dt><dd>".$this->out($this->plugin_info['desc'])."</dd>",4);
+ if ($this->plugin_info['author']) ptln("<dt>".$this->manager->getLang('author')."</dt><dd>".$this->manager->email($this->plugin_info['email'], $this->plugin_info['author'])."</dd>",4);
+ if ($this->plugin_info['url']) ptln("<dt>".$this->manager->getLang('www')."</dt><dd>".$this->manager->external_link($this->plugin_info['url'], '', 'urlextern')."</dd>",4);
+ ptln("</dl>",2);
+
+ if (count($this->details) > 1) {
+ ptln("<h3>".$this->manager->getLang('components')."</h3>",2);
+ ptln("<div>",2);
+
+ foreach ($this->details as $info) {
+
+ ptln("<dl>",4);
+ ptln("<dt>".$this->manager->getLang('name')."</dt><dd>".$this->out($info['name'].' '.$info['compname'])."</dd>",6);
+ if (!$this->plugin_info['date']) ptln("<dt>".$this->manager->getLang('date')."</dt><dd>".$this->out($info['date'])."</dd>",6);
+ if (!$this->plugin_info['type']) ptln("<dt>".$this->manager->getLang('type')."</dt><dd>".$this->out($info['type'])."</dd>",6);
+ if (!$this->plugin_info['desc']) ptln("<dt>".$this->manager->getLang('desc')."</dt><dd>".$this->out($info['desc'])."</dd>",6);
+ if (!$this->plugin_info['author']) ptln("<dt>".$this->manager->getLang('author')."</dt><dd>".$this->manager->email($info['email'], $info['author'])."</dd>",6);
+ if (!$this->plugin_info['url']) ptln("<dt>".$this->manager->getLang('www')."</dt><dd>".$this->manager->external_link($info['url'], '', 'urlextern')."</dd>",6);
+ ptln("</dl>",4);
+
+ }
+ ptln("</div>",2);
+ }
+ }
+ ptln("</div>");
+ }
+
+ // simple output filter, make html entities safe and convert new lines to <br />
+ function out($text) {
+ return str_replace("\n",'<br />',htmlspecialchars($text));
+ }
+
+
+ /**
+ * return a list (name & type) of all the component plugins that make up this plugin
+ *
+ * @todo can this move to pluginutils?
+ */
+ function get_plugin_components($plugin) {
+
+ global $plugin_types;
+
+ $components = array();
+ $path = DOKU_PLUGIN.plugin_directory($plugin).'/';
+
+ foreach ($plugin_types as $type) {
+ if (@file_exists($path.$type.'.php')) { $components[] = array('name'=>$plugin, 'type'=>$type); continue; }
+
+ if ($dh = @opendir($path.$type.'/')) {
+ while (false !== ($cp = readdir($dh))) {
+ if ($cp == '.' || $cp == '..' || strtolower(substr($cp,-4)) != '.php') continue;
+
+ $components[] = array('name'=>$plugin.'_'.substr($cp, 0, -4), 'type'=>$type);
+ }
+ closedir($dh);
+ }
+ }
+
+ return $components;
+ }
+
+ /**
+ * usort callback to sort plugin components
+ */
+ function component_sort($a, $b) {
+ if ($a['name'] == $b['name']) return 0;
+ return ($a['name'] < $b['name']) ? -1 : 1;
+ }
+}
diff --git a/lib/plugins/plugin/classes/ap_manage.class.php b/lib/plugins/plugin/classes/ap_manage.class.php
new file mode 100644
index 000000000..12480e922
--- /dev/null
+++ b/lib/plugins/plugin/classes/ap_manage.class.php
@@ -0,0 +1,197 @@
+<?php
+
+class ap_manage {
+
+ var $manager = NULL;
+ var $lang = array();
+ var $plugin = '';
+ var $downloaded = array();
+
+ function ap_manage(&$manager, $plugin) {
+ $this->manager = & $manager;
+ $this->plugin = $plugin;
+ $this->lang = & $manager->lang;
+ }
+
+ function process() {
+ return '';
+ }
+
+ function html() {
+ print $this->manager->locale_xhtml('admin_plugin');
+ $this->html_menu();
+ }
+
+ // build our standard menu
+ function html_menu($listPlugins = true) {
+ global $ID;
+
+ ptln('<div class="pm_menu">');
+
+ ptln('<div class="common">');
+ ptln(' <h2>'.$this->lang['download'].'</h2>');
+ ptln(' <form action="'.wl($ID).'" method="post">');
+ ptln(' <fieldset class="hidden">',4);
+ ptln(' <input type="hidden" name="do" value="admin" />');
+ ptln(' <input type="hidden" name="page" value="plugin" />');
+ formSecurityToken();
+ ptln(' </fieldset>');
+ ptln(' <fieldset>');
+ ptln(' <legend>'.$this->lang['download'].'</legend>');
+ ptln(' <label for="dw__url">'.$this->lang['url'].'<input name="url" id="dw__url" class="edit" type="text" maxlength="200" /></label>');
+ ptln(' <input type="submit" class="button" name="fn[download]" value="'.$this->lang['btn_download'].'" />');
+ ptln(' </fieldset>');
+ ptln(' </form>');
+ ptln('</div>');
+
+ if ($listPlugins) {
+ ptln('<h2>'.$this->lang['manage'].'</h2>');
+
+ ptln('<form action="'.wl($ID).'" method="post" class="plugins">');
+
+ ptln(' <fieldset class="hidden">');
+ ptln(' <input type="hidden" name="do" value="admin" />');
+ ptln(' <input type="hidden" name="page" value="plugin" />');
+ formSecurityToken();
+ ptln(' </fieldset>');
+
+ $this->html_pluginlist();
+
+ ptln(' <fieldset class="buttons">');
+ ptln(' <input type="submit" class="button" name="fn[enable]" value="'.$this->lang['btn_enable'].'" />');
+ ptln(' </fieldset>');
+
+ // ptln(' </div>');
+ ptln('</form>');
+ }
+
+ ptln('</div>');
+ }
+
+ function html_pluginlist() {
+ global $ID;
+ global $plugin_protected;
+
+ foreach ($this->manager->plugin_list as $plugin) {
+
+ $disabled = plugin_isdisabled($plugin);
+ $protected = in_array($plugin,$plugin_protected);
+
+ $checked = ($disabled) ? '' : ' checked="checked"';
+ $check_disabled = ($protected) ? ' disabled="disabled"' : '';
+
+ // determine display class(es)
+ $class = array();
+ if (in_array($plugin, $this->downloaded)) $class[] = 'new';
+ if ($disabled) $class[] = 'disabled';
+ if ($protected) $class[] = 'protected';
+
+ $class = count($class) ? ' class="'.join(' ', $class).'"' : '';
+
+ ptln(' <fieldset'.$class.'>');
+ ptln(' <legend>'.$plugin.'</legend>');
+ ptln(' <input type="checkbox" class="enable" name="enabled[]" id="dw__p_'.$plugin.'" value="'.$plugin.'"'.$checked.$check_disabled.' />');
+ ptln(' <h3 class="legend"><label for="dw__p_'.$plugin.'">'.$plugin.'</label></h3>');
+
+ $this->html_button($plugin, 'info', false, 6);
+ if (in_array('settings', $this->manager->functions)) {
+ $this->html_button($plugin, 'settings', !@file_exists(DOKU_PLUGIN.$plugin.'/settings.php'), 6);
+ }
+ $this->html_button($plugin, 'update', !$this->plugin_readlog($plugin, 'url'), 6);
+ $this->html_button($plugin, 'delete', $protected, 6);
+
+ ptln(' </fieldset>');
+ }
+ }
+
+ function html_button($plugin, $btn, $disabled=false, $indent=0) {
+ $disabled = ($disabled) ? 'disabled="disabled"' : '';
+ ptln('<input type="submit" class="button" '.$disabled.' name="fn['.$btn.']['.$plugin.']" value="'.$this->lang['btn_'.$btn].'" />',$indent);
+ }
+
+ /**
+ * Refresh plugin list
+ */
+ function refresh() {
+ global $config_cascade;
+
+ // expire dokuwiki caches
+ // touching local.php expires wiki page, JS and CSS caches
+ @touch(reset($config_cascade['main']['local']));
+
+ // update latest plugin date - FIXME
+ global $ID;
+ send_redirect(wl($ID,array('do'=>'admin','page'=>'plugin'),true, '&'));
+ }
+
+ /**
+ * Write a log entry to the given target directory
+ */
+ function plugin_writelog($target, $cmd, $data) {
+
+ $file = $target.'/manager.dat';
+
+ switch ($cmd) {
+ case 'install' :
+ $url = $data[0];
+ $date = date('r');
+ if (!$fp = @fopen($file, 'w')) return;
+ fwrite($fp, "installed=$date\nurl=$url\n");
+ fclose($fp);
+ break;
+
+ case 'update' :
+ $date = date('r');
+ if (!$fp = @fopen($file, 'a')) return;
+ fwrite($fp, "updated=$date\n");
+ fclose($fp);
+ break;
+ }
+ }
+
+ function plugin_readlog($plugin, $field) {
+ static $log = array();
+ $file = DOKU_PLUGIN.plugin_directory($plugin).'/manager.dat';
+
+ if (!isset($log[$plugin])) {
+ $tmp = @file_get_contents($file);
+ if (!$tmp) return '';
+ $log[$plugin] = & $tmp;
+ }
+
+ if ($field == 'ALL') {
+ return $log[$plugin];
+ }
+
+ $match = array();
+ if (preg_match_all('/'.$field.'=(.*)$/m',$log[$plugin], $match))
+ return implode("\n", $match[1]);
+
+ return '';
+ }
+
+ /**
+ * delete, with recursive sub-directory support
+ */
+ function dir_delete($path) {
+ if (!is_string($path) || $path == "") return false;
+
+ if (is_dir($path) && !is_link($path)) {
+ if (!$dh = @opendir($path)) return false;
+
+ while ($f = readdir($dh)) {
+ if ($f == '..' || $f == '.') continue;
+ $this->dir_delete("$path/$f");
+ }
+
+ closedir($dh);
+ return @rmdir($path);
+ } else {
+ return @unlink($path);
+ }
+
+ return false;
+ }
+
+
+}
diff --git a/lib/plugins/plugin/classes/ap_update.class.php b/lib/plugins/plugin/classes/ap_update.class.php
new file mode 100644
index 000000000..c43429a1b
--- /dev/null
+++ b/lib/plugins/plugin/classes/ap_update.class.php
@@ -0,0 +1,38 @@
+<?php
+require_once(DOKU_PLUGIN."/plugin/classes/ap_download.class.php");
+class ap_update extends ap_download {
+
+ var $overwrite = true;
+
+ function process() {
+ global $lang;
+
+ $plugin_url = $this->plugin_readlog($this->plugin, 'url');
+ $this->download($plugin_url, $this->overwrite);
+ return '';
+ }
+
+ function html() {
+ parent::html();
+
+ ptln('<div class="pm_info">');
+ ptln('<h2>'.$this->lang['updating'].'</h2>');
+
+ if ($this->manager->error) {
+ ptln('<div class="error">'.str_replace("\n","<br />", $this->manager->error).'</div>');
+ } else if (count($this->downloaded) == 1) {
+ ptln('<p>'.sprintf($this->lang['updated'],$this->downloaded[0]).'</p>');
+ } else if (count($this->downloaded)) { // more than one plugin in the download
+ ptln('<p>'.$this->lang['updates'].'</p>');
+ ptln('<ul>');
+ foreach ($this->downloaded as $plugin) {
+ ptln('<li><div class="li">'.$plugin.'</div></li>',2);
+ }
+ ptln('</ul>');
+ } else { // none found in download
+ ptln('<p>'.$this->lang['update_none'].'</p>');
+ }
+ ptln('</div>');
+ }
+}
+
diff --git a/lib/plugins/plugin/lang/af/lang.php b/lib/plugins/plugin/lang/af/lang.php
new file mode 100644
index 000000000..669fdd5ce
--- /dev/null
+++ b/lib/plugins/plugin/lang/af/lang.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Afrikaans language file
+ *
+ */
+$lang['btn_download'] = 'Af laai';
+$lang['btn_enable'] = 'Store';
+$lang['url'] = 'URL';
+$lang['unknown'] = 'unbekende';
+$lang['name'] = 'Naam:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Tipe:';
+$lang['www'] = 'Web-werf:';
diff --git a/lib/plugins/plugin/lang/ar/admin_plugin.txt b/lib/plugins/plugin/lang/ar/admin_plugin.txt
new file mode 100644
index 000000000..2ef9fd595
--- /dev/null
+++ b/lib/plugins/plugin/lang/ar/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== إدارة الإضافات ======
+
+على هذه الصفحة يمكنك إدارة كل ما يتعلق ب[[doku>plugins|إضافات]] دوكو ويكي. لتتمكن من تنزيل و تثبيت الإضافات يجب أن يكون دليل الاضافات قابلا للكتابة من خادوم الوب.
+
diff --git a/lib/plugins/plugin/lang/ar/lang.php b/lib/plugins/plugin/lang/ar/lang.php
new file mode 100644
index 000000000..fbc6d3c36
--- /dev/null
+++ b/lib/plugins/plugin/lang/ar/lang.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Arabic language file
+ *
+ * @author Yaman Hokan <always.smile.yh@hotmail.com>
+ * @author Usama Akkad <uahello@gmail.com>
+ * @author uahello@gmail.com
+ */
+$lang['menu'] = 'إدارة الملحقات';
+$lang['download'] = 'نزّل و ثبت اضافة جديدة';
+$lang['manage'] = 'الإضافات المثبتة';
+$lang['btn_info'] = 'معلومات';
+$lang['btn_update'] = 'حدّث';
+$lang['btn_delete'] = 'احذف';
+$lang['btn_settings'] = 'إعدادات';
+$lang['btn_download'] = 'نزل';
+$lang['btn_enable'] = 'احفظ';
+$lang['url'] = 'رابط';
+$lang['installed'] = 'ثُبتت:';
+$lang['lastupdate'] = 'آخر تحديث:';
+$lang['source'] = 'المصدر:';
+$lang['unknown'] = 'مجهول';
+$lang['updating'] = 'تُحدث ...';
+$lang['updated'] = 'الاضافة %s حُدثت بنجاح';
+$lang['updates'] = 'الاضافة التالية حُدثت بنجاح';
+$lang['update_none'] = 'لا يوجد تحديثات.';
+$lang['deleting'] = 'تُحذف ... ';
+$lang['deleted'] = 'حُذفت الإضافة %s.';
+$lang['downloading'] = 'يُنزل ...';
+$lang['downloaded'] = 'الاضافة %s ثبتت بنجاح';
+$lang['downloads'] = 'الاضافة التالية ثبتت بنجاح:';
+$lang['download_none'] = 'لم يجد إضافة، أو ان هناك مشكلة غير معروفة أثناء التنزيل و التثبيت.';
+$lang['plugin'] = 'الإضافة:';
+$lang['components'] = 'المكون:';
+$lang['noinfo'] = 'لم تعطي الإضافة أية معلومة، قد تكون معطوبة.';
+$lang['name'] = 'الاسم :';
+$lang['date'] = 'التاريخ :';
+$lang['type'] = 'النوع :';
+$lang['desc'] = 'الوصف :';
+$lang['author'] = 'الكاتب :';
+$lang['www'] = 'الشابكة :';
+$lang['error'] = 'حث خطأ مجهول.';
+$lang['error_download'] = 'تعذر تنزيل ملف الاضافة: %s';
+$lang['error_badurl'] = 'اشتبه بعنوان خاطئ - تعذر الحصول على الاسم من العنوان';
+$lang['error_dircreate'] = 'تعذر إنشاء مجلد مؤقت للتنزيل';
+$lang['error_decompress'] = 'تعذر على مدير الاضافات فك ضغط الملف المُنزّل. قد يكون ذلك نتيجة لتنزيل خاطئ، في هذه الحالة أعد المحاولة; أو ان هيئة الضغط غير معروفة، في هذه الحالة عليك تنزيل و تثبيت الاضافة يدويا.';
+$lang['error_copy'] = 'كان هناك خطأ في نسخ ملف عند محاولة تثبيت ملفات للإضافة <em>%s</em>: قد يكون القرص ممتلئا أو أن صلاحيات الوصول للملف خاطئة. لربما نتج عن ذلك اضافة مثبته جزئيا تجعل نظام الويكي غير ثابت.';
+$lang['error_delete'] = 'كان هناك خطأ عند محاولة حذف الاضافة <em>%s</em>. السبب الاكثر احتمالا هو صلاحيات غير كافية على الملف أو المجلد';
+$lang['enabled'] = 'الاضافة %s فُعلت. ';
+$lang['notenabled'] = 'تعذر تفعيل الاضافة %s، تحقق من اذونات الملف.';
+$lang['disabled'] = 'عُطلت الإضافة %s.';
+$lang['notdisabled'] = 'تعذر تعطيل الإضافة %s، تحقق من اذونات الملف.';
diff --git a/lib/plugins/plugin/lang/bg/admin_plugin.txt b/lib/plugins/plugin/lang/bg/admin_plugin.txt
new file mode 100644
index 000000000..bad73e136
--- /dev/null
+++ b/lib/plugins/plugin/lang/bg/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Управление на приставките ======
+
+От тази страница можете на управлявате [[doku>plugins|приставките]] на Dokuwiki. За да свалите и инсталирате приставка, е необходимо писането в директорията .../lib/plugins/ да е позволено на сървъра.
diff --git a/lib/plugins/plugin/lang/bg/lang.php b/lib/plugins/plugin/lang/bg/lang.php
new file mode 100644
index 000000000..09ac35229
--- /dev/null
+++ b/lib/plugins/plugin/lang/bg/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * bulgarian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Nikolay Vladimirov <nikolay@vladimiroff.com>
+ * @author Viktor Usunov <usun0v@mail.bg>
+ * @author Kiril <neohidra@gmail.com>
+ */
+$lang['menu'] = 'Управление на приставките';
+$lang['download'] = 'Сваляне и инсталиране на нова приставка';
+$lang['manage'] = 'Инсталирани приставки';
+$lang['btn_info'] = 'информация';
+$lang['btn_update'] = 'обновяване';
+$lang['btn_delete'] = 'изтриване';
+$lang['btn_settings'] = 'настройки';
+$lang['btn_download'] = 'Сваляне';
+$lang['btn_enable'] = 'Запис';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Инсталирана:';
+$lang['lastupdate'] = 'Актуализирана:';
+$lang['source'] = 'Източник:';
+$lang['unknown'] = 'непознат';
+$lang['updating'] = 'Актуализиране ...';
+$lang['updated'] = 'Приставката %s е качена успешно';
+$lang['updates'] = 'Следните приставки са актуализирани успешно';
+$lang['update_none'] = 'Не са намерени нови версии.';
+$lang['deleting'] = 'Изтриване ...';
+$lang['deleted'] = 'Приставката %s е изтрита успешно.';
+$lang['downloading'] = 'Сваляне ...';
+$lang['downloaded'] = 'Приставката %s е инсталирана успешно ';
+$lang['downloads'] = 'Следните приставки са инсталирани успешно:';
+$lang['download_none'] = 'Не са намерени приставки или е възникнала непозната грешка при свалянето и инсталирането.';
+$lang['plugin'] = 'Приставка:';
+$lang['components'] = 'Компоненти';
+$lang['noinfo'] = 'Приставка не върна информация, може да е повредена.';
+$lang['name'] = 'Име:';
+$lang['date'] = 'Дата:';
+$lang['type'] = 'Тип:';
+$lang['desc'] = 'Описание:';
+$lang['author'] = 'Автор:';
+$lang['www'] = 'Уебстраница:';
+$lang['error'] = 'Възникна непозната грешка.';
+$lang['error_download'] = 'Свалянето на приставката %s е невъзможно.';
+$lang['error_badurl'] = 'Предполагаем грешен адрес - не може да се определи име на файла от URL адреса';
+$lang['error_dircreate'] = 'Създаването на временна директория за сваляне не е възможно.';
+$lang['error_decompress'] = 'Разархивирането на сваленият файл е невъзможно. Вероятно е резултат от грешка при свалянето, в този случай трябва да опитате отново; или формата на компресия е непознат - тогава трябва да свалите и инсталирате приставката ръчно.';
+$lang['error_copy'] = 'Възникна грешка при копиране на файл по време на инсталиране на приставката <em>%s</em>: вероятно дискът е пълен или правата за достъп до файловете са грешни. Може да доведе до частично инсталирана приставка и да причини нестабилно функциониране на wiki-то ви.';
+$lang['error_delete'] = 'Възникна грешка при изтриването на приставката <em>%s</em>. Най-вероятната причина е в правата за достъп до файл или директория';
+$lang['enabled'] = 'Приставката %s е включена.';
+$lang['notenabled'] = 'Приставката %s не може да бъде включена, моля проверете правата за файловете.';
+$lang['disabled'] = 'Приставката %s е изключена.';
+$lang['notdisabled'] = 'Приставката %s не е изключена, моля проверете правата за файловете.';
+$lang['packageinstalled'] = 'Пакетът е инсталиран успешно (%d приставка: %s).';
diff --git a/lib/plugins/plugin/lang/ca-valencia/admin_plugin.txt b/lib/plugins/plugin/lang/ca-valencia/admin_plugin.txt
new file mode 100644
index 000000000..6b5a95838
--- /dev/null
+++ b/lib/plugins/plugin/lang/ca-valencia/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== Gestor de plúgins ======
+
+Des d'esta pàgina pot gestionar tot lo relacionat en els [[doku>plugins|plúgins]] de DokuWiki. Per a poder descarregar i instalar un plúgin, el servidor web deu poder escriure en la carpeta de plúgins.
+
diff --git a/lib/plugins/plugin/lang/ca-valencia/lang.php b/lib/plugins/plugin/lang/ca-valencia/lang.php
new file mode 100644
index 000000000..3fbdb134d
--- /dev/null
+++ b/lib/plugins/plugin/lang/ca-valencia/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * valencian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Bernat Arlandis i Mañó <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@llenguaitecnologia.com>
+ */
+$lang['menu'] = 'Gestor de plúgins';
+$lang['download'] = 'Descarregar i instalar un nou plúgin';
+$lang['manage'] = 'Plúgins instalats';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'actualisar';
+$lang['btn_delete'] = 'borrar';
+$lang['btn_settings'] = 'ajusts';
+$lang['btn_download'] = 'Descarregar';
+$lang['btn_enable'] = 'Guardar';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalat:';
+$lang['lastupdate'] = 'Última actualisació:';
+$lang['source'] = 'Font:';
+$lang['unknown'] = 'desconegut';
+$lang['updating'] = 'Actualisant ...';
+$lang['updated'] = 'Plúgin %s actualisat correctament';
+$lang['updates'] = 'Els següents plúgins s\'han actualisat correctament:';
+$lang['update_none'] = 'No s\'han trobat actualisacions.';
+$lang['deleting'] = 'Borrant ...';
+$lang['deleted'] = 'Plúgin %s borrat.';
+$lang['downloading'] = 'Descarregant ...';
+$lang['downloaded'] = 'Plúgin %s instalat correctament';
+$lang['downloads'] = 'Els següents plúgins s\'han instalat correctament:';
+$lang['download_none'] = 'No s\'han trobat plúgins o ha hagut algun problema descarregant i instalant.';
+$lang['plugin'] = 'Plúgin:';
+$lang['components'] = 'Components';
+$lang['noinfo'] = 'Este plúgin no ha tornat informació, pot ser invàlit.';
+$lang['name'] = 'Nom:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Classe:';
+$lang['desc'] = 'Descripció:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Ha ocorregut un erro desconegut.';
+$lang['error_download'] = 'No es pot descarregar l\'archiu del plúgin: %s';
+$lang['error_badurl'] = 'Possible URL roïn - no es pot determinar el nom de l\'archiu a partir de la URL';
+$lang['error_dircreate'] = 'No es pot crear la carpeta temporal per a rebre descàrregues';
+$lang['error_decompress'] = 'El gestor de plúgins no ha pogut descomprimir l\'archiu descarregat. Açò pot ser degut a una descàrrega fallida, en eixe cas deuria intentar-ho de nou; o el format de compressió pot ser desconegut, en eixe cas necessitarà descarregar i instalar el plúgin manualment.';
+$lang['error_copy'] = 'Ha ocorregut un erro copiant archius a l\'instalar archius del plúgin <em>%s</em>: el disc podria estar ple o els permissos d\'accés a l\'archiu estar mal. El plúgin podria haver quedat parcialment instalat i deixar el wiki inestable.';
+$lang['error_delete'] = 'Ha ocorregut un erro intentant borrar el plúgin <em>%s</em>. La causa més provable és que els permissos d\'accés a l\'archiu o el directori no siguen suficients';
+$lang['enabled'] = 'Plúgin %s activat.';
+$lang['notenabled'] = 'No s\'ha pogut activar el plúgin %s, comprove els permissos dels archius.';
+$lang['disabled'] = 'Plúgin %s desactivat.';
+$lang['notdisabled'] = 'No s\'ha pogut desactivar el plúgin %s, comprove els permissos dels archius.';
diff --git a/lib/plugins/plugin/lang/ca/admin_plugin.txt b/lib/plugins/plugin/lang/ca/admin_plugin.txt
new file mode 100644
index 000000000..c21e3f502
--- /dev/null
+++ b/lib/plugins/plugin/lang/ca/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Gestió de connectors ======
+
+En aquesta pàgina podeu gestionar tot allò referent als [[doku>plugins|connectors]] de Dokuwiki. Per a baixar i instal·lar connectors, cal que el servidor web tingui permís d'escriptura en la carpeta de connectors. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/ca/lang.php b/lib/plugins/plugin/lang/ca/lang.php
new file mode 100644
index 000000000..0e3ef05df
--- /dev/null
+++ b/lib/plugins/plugin/lang/ca/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Catalan language file
+ *
+ * @author Carles Bellver <carles.bellver@gmail.com>
+ * @author carles.bellver@gmail.com
+ * @author carles.bellver@cent.uji.es
+ * @author Carles Bellver <carles.bellver@cent.uji.es>
+ */
+$lang['menu'] = 'Gestió de connectors';
+$lang['download'] = 'Baixa i instal·la un nou connector';
+$lang['manage'] = 'Connectors instal·lats';
+$lang['btn_info'] = 'informació';
+$lang['btn_update'] = 'actualitza';
+$lang['btn_delete'] = 'suprimeix';
+$lang['btn_settings'] = 'paràmetres';
+$lang['btn_download'] = 'Baixa';
+$lang['btn_enable'] = 'Desa';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instal·lació:';
+$lang['lastupdate'] = 'Darrera actualitació:';
+$lang['source'] = 'Font:';
+$lang['unknown'] = 'desconegut';
+$lang['updating'] = 'S\'està actualitzant...';
+$lang['updated'] = 'El connector %s s\'ha actualitzat amb èxit.';
+$lang['updates'] = 'Els connectors següents s\'han actualitzat amb èxit';
+$lang['update_none'] = 'No s\'han trobat actualitzacions.';
+$lang['deleting'] = 'S\'està suprimint...';
+$lang['deleted'] = 'S\'ha suprimit el connector %s.';
+$lang['downloading'] = 'S\'està baixant...';
+$lang['downloaded'] = 'El connector %s s\'ha instal·lat amb èxit';
+$lang['downloads'] = 'Els connectors següents s\'han instal·lat amb èxit:';
+$lang['download_none'] = 'No s\'han trobat connectors, o hi ha hagut un problema desconegut durant el procés de baixada i instal·lació.';
+$lang['plugin'] = 'Connector:';
+$lang['components'] = 'Components';
+$lang['noinfo'] = 'Aquest connector no ha retornat informació. Potser no és vàlid.';
+$lang['name'] = 'Nom:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipus:';
+$lang['desc'] = 'Descripció:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'S\'ha produït un error desconegut.';
+$lang['error_download'] = 'No s\'ha pogut baixar el fitxer del connector: %s';
+$lang['error_badurl'] = 'L\'URL no sembla vàlid: no permet determinar el nom del fitxer';
+$lang['error_dircreate'] = 'No s\'ha pogut crear una carpeta temporal per rebre la baixada';
+$lang['error_decompress'] = 'El gestor de connectors no ha pogut descomprimir el fitxer baixat. Potser no s\'ha baixat correctament, en el qual cas podríeu tornar a intentar-ho. O el format de compressió podria ser desconegut, en el qual cas hauríeu de baixar i instal·lar el connector manualment.';
+$lang['error_copy'] = 'S\'ha produït un error de còpia de fitxers quan s\'estaven instal·lant els fitxers del connector <em>%s</em>: potser el disc està ple o els permisos d\'accés són incorrectes. Això pot haver causat una instal·lació incompleta del connector i per tant el vostre wiki pot haver quedat en un estat inestable.';
+$lang['error_delete'] = 'S\'ha produït un error quan s\'intentava suprimir el connector <em>%s</em>. La causa més probable d\'això són uns permisos d\'accés insuficients al fitxer o al directori. ';
+$lang['enabled'] = 'S\'ha habilitat el connector %s.';
+$lang['notenabled'] = 'No s\'ha pogut habilitar el connector %s. Comproveu els permisos dels fitxers.';
+$lang['disabled'] = 'S\'ha inhabilitat el connector %s.';
+$lang['notdisabled'] = 'No s\'ha pogut inhabilitar el connector %s. Comproveu els permisos dels fitxers.';
diff --git a/lib/plugins/plugin/lang/cs/admin_plugin.txt b/lib/plugins/plugin/lang/cs/admin_plugin.txt
new file mode 100644
index 000000000..6ebf1e78f
--- /dev/null
+++ b/lib/plugins/plugin/lang/cs/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Správa pluginů ======
+
+Na této stránce lze spravovat pluginy DokuWiki [[doku>plugins|plugins]]. Aby bylo možné stahovat a instalovat pluginy, musí mít webový server přístup pro zápis do adresáře //plugin//.
diff --git a/lib/plugins/plugin/lang/cs/lang.php b/lib/plugins/plugin/lang/cs/lang.php
new file mode 100644
index 000000000..0ccabf344
--- /dev/null
+++ b/lib/plugins/plugin/lang/cs/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Czech language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Tomas Valenta <t.valenta@sh.cvut.cz>
+ * @author Zbynek Krivka <zbynek.krivka@seznam.cz>
+ * @author Bohumir Zamecnik <bohumir@zamecnik.org>
+ * @author tomas@valenta.cz
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @author Lefty <lefty@multihost.cz>
+ * @author Vojta Beran <xmamut@email.cz>
+ * @author zbynek.krivka@seznam.cz
+ */
+$lang['menu'] = 'Správa pluginů';
+$lang['download'] = 'Stáhnout a instalovat plugin';
+$lang['manage'] = 'Seznam instalovaných pluginů';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'aktualizovat';
+$lang['btn_delete'] = 'smazat';
+$lang['btn_settings'] = 'nastavení';
+$lang['btn_download'] = 'Stáhnout';
+$lang['btn_enable'] = 'Uložit';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalován:';
+$lang['lastupdate'] = 'Poslední aktualizace:';
+$lang['source'] = 'Zdroj:';
+$lang['unknown'] = 'neznámý';
+$lang['updating'] = 'Aktualizuji ...';
+$lang['updated'] = 'Modul %s úspěšně aktualizován';
+$lang['updates'] = 'Následující pluginy byly úspěšně aktualizovány';
+$lang['update_none'] = 'Žádné aktualizace nenalezeny.';
+$lang['deleting'] = 'Probíhá mazání ...';
+$lang['deleted'] = 'Plugin %s smazán.';
+$lang['downloading'] = 'Stahuji ...';
+$lang['downloaded'] = 'Plugin %s nainstalován';
+$lang['downloads'] = 'Následující pluginy byly úspěšně instalovány:';
+$lang['download_none'] = 'Žádné pluginy nebyly nenalezeny, nebo se vyskytla nějaká chyba při
+stahování a instalaci.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Součásti';
+$lang['noinfo'] = 'Plugin nevrátil žádné informace. Může být poškozen nebo špatný.';
+$lang['name'] = 'Jméno:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Typ:';
+$lang['desc'] = 'Popis:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Nastala neznámá chyba.';
+$lang['error_download'] = 'Nelze stáhnout soubor s pluginem: %s';
+$lang['error_badurl'] = 'URL je zřejmě chybná - nelze z ní určit název souboru';
+$lang['error_dircreate'] = 'Nelze vytvořit dočasný adresář ke stažení dat';
+$lang['error_decompress'] = 'Správce pluginů nemůže rozbalit stažený soubor. Toto může být způsobeno chybou při stahování. Můžete se pokusit stahování opakovat. Chyba může být také v kompresním formátu souboru. V tom případě bude nutné stáhnout a nainstalovat plugin ručně.';
+$lang['error_copy'] = 'Došlo k chybě při instalaci pluginu <em>%s</em>. Je možné, že na disku není volné místo, nebo mohou být špatně nastavena přístupová práva. Pozor, mohlo dojít k částečné a tudíž chybné instalaci pluginu a tím může být ohrožena stabilita wiki.';
+$lang['error_delete'] = 'Došlo k chybě při pokusu o smazání pluginu <em>%s</em>. Nejspíše je chyba v nastavení přístupových práv k některým souborům či adresářům.';
+$lang['enabled'] = 'Plugin %s aktivován.';
+$lang['notenabled'] = 'Plugin %s nelze aktivovat, zkontrolujte práva k souborům.';
+$lang['disabled'] = 'Plugin %s deaktivován.';
+$lang['notdisabled'] = 'Plugin %s nelze deaktivovat, zkontrolujte práva k souborům.';
+$lang['packageinstalled'] = 'Balíček pluginů (%d plugin(ů): %s) úspěšně nainstalován.';
diff --git a/lib/plugins/plugin/lang/da/admin_plugin.txt b/lib/plugins/plugin/lang/da/admin_plugin.txt
new file mode 100644
index 000000000..300b6618b
--- /dev/null
+++ b/lib/plugins/plugin/lang/da/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Udvidelsesstyring ======
+
+På denne side kan du kontrollere alle Dokuwikis [[doku>plugins|udvidelser]]. For at hente og opsætte en udvidelse, må din udvidelsesmappe kunne skrives til af serveren.
+
+
diff --git a/lib/plugins/plugin/lang/da/lang.php b/lib/plugins/plugin/lang/da/lang.php
new file mode 100644
index 000000000..841d246df
--- /dev/null
+++ b/lib/plugins/plugin/lang/da/lang.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Danish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Lars Næsbye Christensen <larsnaesbye@stud.ku.dk>
+ * @author Kalle Sommer Nielsen <kalle@php.net>
+ * @author Esben Laursen <hyber@hyber.dk>
+ * @author Harith <haj@berlingske.dk>
+ * @author Daniel Ejsing-Duun <dokuwiki@zilvador.dk>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author rasmus@kinnerup.com
+ * @author Michael Pedersen subben@gmail.com
+ */
+$lang['menu'] = 'Håndter udvidelser';
+$lang['download'] = 'Hent og tilføj ny udvidelse';
+$lang['manage'] = 'Tilføjede udvidelser';
+$lang['btn_info'] = 'oplysninger';
+$lang['btn_update'] = 'opdater';
+$lang['btn_delete'] = 'slet';
+$lang['btn_settings'] = 'indstillinger';
+$lang['btn_download'] = 'Hent';
+$lang['btn_enable'] = 'Gem';
+$lang['url'] = 'URL-adresse';
+$lang['installed'] = 'Tliføjet:';
+$lang['lastupdate'] = 'Sidst opdateret:';
+$lang['source'] = 'Kilde:';
+$lang['unknown'] = 'ukendt';
+$lang['updating'] = 'Opdaterer ...';
+$lang['updated'] = 'Udvidelse %s blev korrekt opdateret';
+$lang['updates'] = 'De følgende udvidelser blev opdateret korrekt:';
+$lang['update_none'] = 'Ingen opdateringer fundet.';
+$lang['deleting'] = 'Sletter ...';
+$lang['deleted'] = 'Udvidelsen %s slettet.';
+$lang['downloading'] = 'Henter ...';
+$lang['downloaded'] = 'Udvidelse %s blev korrekt installeret';
+$lang['downloads'] = 'De følgende udvidelser blev installeret korrekt:';
+$lang['download_none'] = 'Ingen udvidelser blev fundet, eller en ukendt fejl opstod under hentning og opsætning';
+$lang['plugin'] = 'Udvidelse:';
+$lang['components'] = 'Komponenter';
+$lang['noinfo'] = 'Denne udvidelse videregav ingen oplysninger. Den kan være fejlagtig.';
+$lang['name'] = 'Navn:';
+$lang['date'] = 'Dato:';
+$lang['type'] = 'Type:';
+$lang['desc'] = 'Beskrivelse:';
+$lang['author'] = 'Programmør:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'En ukendt fejl opstod.';
+$lang['error_download'] = 'Kunne ikke hente udvidelsesfilen: %s';
+$lang['error_badurl'] = 'Muligvis dårlig netadresse; kunne ikke hente filnavn fra adressen.';
+$lang['error_dircreate'] = 'Kunne ikke oprette midlertidig mappe til hentning';
+$lang['error_decompress'] = 'Udvidelseshåndtering kunne ikke udpakke den hentede fil. Det kan skyldes et fejlagtigt download, i hvilket fald du må prøve igen. Komprimeringsformatet kan også være ukendt, hvorved du du vil være nødt til at hente og opsætte udvidelsen manuelt.';
+$lang['error_copy'] = 'Der opstod en filkopieringsfejl under forsøget på at installere filerne til udvidelsen <em>%s</em>: Disken kan være fuld eller filadgangsrettighederne kan være forkert sat. Dette kan have ført til en delvist installeret udvidelse og efterladt din wiki-opsætning ustabil.';
+$lang['error_delete'] = 'Der opstod en fejl ved forsøget på at slette udvidelsen <em>%s</em>. Dette skyldes sandsynligvis utilstrækkelig adgang til filer eller mapper.';
+$lang['enabled'] = 'Udvidelsen %s blev aktiveret.';
+$lang['notenabled'] = 'Udvidelsen %s kunne ikke aktiveres. Kontroller filtilladelser.';
+$lang['disabled'] = 'Udvidelsen %s blev ikke aktiveret.';
+$lang['notdisabled'] = 'Udvidelsen %s kunne ikke aktiveres. Kontroller filtilladelser.';
diff --git a/lib/plugins/plugin/lang/de-informal/admin_plugin.txt b/lib/plugins/plugin/lang/de-informal/admin_plugin.txt
new file mode 100644
index 000000000..576797d57
--- /dev/null
+++ b/lib/plugins/plugin/lang/de-informal/admin_plugin.txt
@@ -0,0 +1,3 @@
+===== Erweiterungsmanagement =====
+
+Auf dieser Seite kannst du alles anpassen was mit den DokuWiki [[doku>plugins|Erweiterungen]] zu tun hat. Der Ordner der Erweiterungen muss für den Webserver beschreibbar sein, um Erweiterungen herunterladen und installieren zu können. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/de-informal/lang.php b/lib/plugins/plugin/lang/de-informal/lang.php
new file mode 100644
index 000000000..abcdf2c83
--- /dev/null
+++ b/lib/plugins/plugin/lang/de-informal/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * German (informal) language file
+ *
+ * @author Alexander Fischer <tbanus@os-forge.net>
+ * @author Juergen Schwarzer <jschwarzer@freenet.de>
+ * @author Marcel Metz <marcel_metz@gmx.de>
+ * @author Matthias Schulte <post@lupo49.de>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Plugins verwalten';
+$lang['download'] = 'Herunterladen und installieren einer neuen Erweiterung';
+$lang['manage'] = 'Installierte Erweiterungen';
+$lang['btn_info'] = 'Information';
+$lang['btn_update'] = 'aktualisieren';
+$lang['btn_delete'] = 'löschen';
+$lang['btn_settings'] = 'Einstellungen';
+$lang['btn_download'] = 'Herunterladen';
+$lang['btn_enable'] = 'Speichern';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Installiert:';
+$lang['lastupdate'] = 'Letzte Aktualisierung:';
+$lang['source'] = 'Quellen:';
+$lang['unknown'] = 'unbekannt';
+$lang['updating'] = 'Aktualisiere...';
+$lang['updated'] = 'Erweiterung %s wurde erfolgreich aktualisiert.';
+$lang['updates'] = 'Die folgenden Erweiterungen wurden erfolgreich aktualisiert.';
+$lang['update_none'] = 'Keine Aktualisierungen gefunden.';
+$lang['deleting'] = 'Lösche...';
+$lang['deleted'] = 'Erweiterung %s wurde gelöscht.';
+$lang['downloading'] = 'Herunterladen...';
+$lang['downloaded'] = 'Erweiterung %s wurde erfolgreich installiert';
+$lang['downloads'] = 'Die folgenden Erweiterungen wurden erfolgreich installiert:';
+$lang['download_none'] = 'Keine Erweiterungen gefunden oder es trat ein unbekanntest Problem beim Herunterladen und Installieren auf.';
+$lang['plugin'] = 'Erweiterung:';
+$lang['components'] = 'Komponenten';
+$lang['noinfo'] = 'Diese Erweiterung gab keine Information zurück - sie könnte ungültig sein.';
+$lang['name'] = 'Name:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Typ:';
+$lang['desc'] = 'Beschreibung:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Internet:';
+$lang['error'] = 'Es ist ein unbekannter Fehler aufgetreten.';
+$lang['error_download'] = 'Nicht möglich die Erweiterung herunterzuladen: %s';
+$lang['error_badurl'] = 'Vermute schlechte URL - nicht möglich den Dateinamen aus der URL zu ermitteln';
+$lang['error_dircreate'] = 'Nicht möglich einen temporären Ordner zu erstellen um den Download zu empfangen.';
+$lang['error_decompress'] = 'Dem Erweiterungsmanager war es nicht möglich die heruntergeladene Datei zu dekomprimieren. Dies kann an einem defekten Download liegen, in diesem Fall sollten Sie es erneut versuchen; oder das Format mit dem die Datei komprimiert ist, ist unbekannt, da müssen Sie die Erweiterung manuell herunterladen und installieren. ';
+$lang['error_copy'] = 'Es trat ein Dateifehler beim Kopieren der Installationsdateien für die Erweiterung <em>%s</em> auf: Die Festplatte könnte voll oder die Zugriffsrechte verweigert worden sein. Dies führt zu einer teilweise installierten Erweiterung und belässt dein Wiki in einem instabilen Zustand.';
+$lang['error_delete'] = 'Es trat ein Fehler beim Löschen der Erweiterung <em>%s</em> auf. Die wahrscheinlichste Ursache ist eine unzureichende Datei- oder Ordnerzugriffserlaubnis.';
+$lang['enabled'] = 'Erweiterung %s aktiviert.';
+$lang['notenabled'] = 'Erweiterung %s konnte nicht aktiviert werden. Überprüfen sie die Zugriffsberechtigung der Datei.';
+$lang['disabled'] = 'Erweiterung %s deaktiviert.';
+$lang['notdisabled'] = 'Erweiterung %s konnte nicht deaktiviert werden - überprüfe Dateiberechtigungen';
+$lang['packageinstalled'] = 'Plugin-Paket (%d Plugin(s): %s) erfolgreich installiert.';
diff --git a/lib/plugins/plugin/lang/de/admin_plugin.txt b/lib/plugins/plugin/lang/de/admin_plugin.txt
new file mode 100644
index 000000000..f3b2caa0c
--- /dev/null
+++ b/lib/plugins/plugin/lang/de/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Verwaltung der Plugins ======
+
+Auf dieser Seite kannst du alles machen, was mit DokuWiki [[doku>plugins|Plugins]] zu tun hat. Um Plugins automatisch herunterladen und installieren zu können, muss der Webserver im Plugin-Ordner schreiben dürfen.
+
+
diff --git a/lib/plugins/plugin/lang/de/lang.php b/lib/plugins/plugin/lang/de/lang.php
new file mode 100644
index 000000000..8708d7836
--- /dev/null
+++ b/lib/plugins/plugin/lang/de/lang.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * german language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Esther Brunner <esther@kaffeehaus.ch>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Dirk Einecke <dirk@dirkeinecke.de>
+ * @author Blitzi94@gmx.de
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Niels Lange <niels@boldencursief.nl>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Paul Lachewsky <kaeptn.haddock@gmail.com>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Plugins verwalten';
+$lang['download'] = 'Neues Plugin herunterladen und installieren';
+$lang['manage'] = 'Installierte Plugins';
+$lang['btn_info'] = 'Info';
+$lang['btn_update'] = 'Update';
+$lang['btn_delete'] = 'Löschen';
+$lang['btn_settings'] = 'Einstellungen';
+$lang['btn_download'] = 'Herunterladen';
+$lang['btn_enable'] = 'Speichern';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Installiert:';
+$lang['lastupdate'] = 'Letzte Version:';
+$lang['source'] = 'Quelle:';
+$lang['unknown'] = 'unbekannt';
+$lang['updating'] = 'Lade Update ...';
+$lang['updated'] = 'Update von Plugin %s erfolgreich installiert';
+$lang['updates'] = 'Die folgenden Plugins wurden erfolgreich aktualisiert';
+$lang['update_none'] = 'Keine Updates gefunden.';
+$lang['deleting'] = 'Löschen ...';
+$lang['deleted'] = 'Plugin %s gelöscht.';
+$lang['downloading'] = 'Lade herunter ...';
+$lang['downloaded'] = 'Plugin %s erfolgreich installiert';
+$lang['downloads'] = 'Die folgenden Plugins wurden erfolgreich installiert:';
+$lang['download_none'] = 'Keine Plugins gefunden oder es trat ein Fehler beim Herunterladen auf.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Komponenten';
+$lang['noinfo'] = 'Dieses Plugin liefert keine Informationen, möglicherweise ist es fehlerhaft.';
+$lang['name'] = 'Name:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Typ:';
+$lang['desc'] = 'Beschreibung:';
+$lang['author'] = 'Entwickler:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Ein unbekannter Fehler ist aufgetreten.';
+$lang['error_download'] = 'Konnte das Plugin %s nicht installieren';
+$lang['error_badurl'] = 'Wahrscheinlich ungültige URL, konnte keinen Dateinamen ausfindig machen';
+$lang['error_dircreate'] = 'Konnte keinen temporären Ordner für die Downloads erstellen';
+$lang['error_decompress'] = 'Der Plugin Manager konnte das Plugin-Archiv nicht entpacken. Entweder ist der Download fehlerhaft oder das Komprimierungsverfahren wird nicht unterstützt. Bitte versuchen Sie es erneut oder downloaden und installieren Sie das Plugin manuell.';
+$lang['error_copy'] = 'Beim Kopieren der Dateien des Plugins trat ein Fehler auf <em>%s</em>: möglicherweise ist die Festplatte voll oder die Dateiberechtigungen falsch. Möglicherweise wurde das Plugin nur teilweise installiert. Sie sollten das Plugin manuell entfernen um Instabilitäten zu vermeiden.';
+$lang['error_delete'] = 'Es gab einem Fehler beim Versuch das Plugin zu löschen <em>%s</em>. Dies liegt wahrscheinlich an fehlenden Dateiberechtigungen.';
+$lang['enabled'] = 'Plugin %s wurde aktiviert.';
+$lang['notenabled'] = 'Plugin %s konnte nicht aktiviert werden, überprüfen Sie die Dateirechte.';
+$lang['disabled'] = 'Plugin %s wurde deaktiviert.';
+$lang['notdisabled'] = 'Plugin %s konnte nicht deaktiviert werden, überprüfen Sie die Dateirechte.';
+$lang['packageinstalled'] = 'Plugin-Paket (%d Plugin(s): %s) erfolgreich installiert.';
diff --git a/lib/plugins/plugin/lang/el/admin_plugin.txt b/lib/plugins/plugin/lang/el/admin_plugin.txt
new file mode 100644
index 000000000..8b292935d
--- /dev/null
+++ b/lib/plugins/plugin/lang/el/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Διαχείριση Επεκτάσεων ======
+
+Σε αυτή την σελίδα μπορείτε να διαχειριστείτε τις [[doku>plugins|επεκτάσεις]] του Dokuwiki σας. Για να μπορέσετε να εγκαταστήσετε νέες επεκτάσεις, ο αντίστοιχος φάκελος συστήματος θα πρέπει να είναι εγγράψιμος από τον χρήστη κάτω από τον οποίο εκτελείται η εφαρμογή του εξυπηρετητή σας.
+
+
diff --git a/lib/plugins/plugin/lang/el/lang.php b/lib/plugins/plugin/lang/el/lang.php
new file mode 100644
index 000000000..bd6dc2013
--- /dev/null
+++ b/lib/plugins/plugin/lang/el/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Greek language file
+ *
+ * Based on DokuWiki Version rc2007-05-24 english language file
+ * Original english language file contents included for reference
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Thanos Massias <tm@thriasio.gr>
+ * @author Αθανάσιος Νταής <homunculus@wana.gr>
+ * @author Konstantinos Koryllos <koryllos@gmail.com>
+ * @author George Petsagourakis <petsagouris@gmail.com>
+ * @author Petros Vidalis <pvidalis@gmail.com>
+ */
+$lang['menu'] = 'Διαχείριση Επεκτάσεων';
+$lang['download'] = 'Κατεβάστε και εγκαταστήστε μια νέα επέκταση (plugin)';
+$lang['manage'] = 'Εγκατεστημένες επεκτάσεις';
+$lang['btn_info'] = 'πληροφορίες';
+$lang['btn_update'] = 'ενημέρωση';
+$lang['btn_delete'] = 'διαγραφή';
+$lang['btn_settings'] = 'ρυθμίσεις';
+$lang['btn_download'] = 'Μεταφόρτωση';
+$lang['btn_enable'] = 'Αποθήκευση';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Εγκατεστημένη:';
+$lang['lastupdate'] = 'Τελευταία ενημέρωση:';
+$lang['source'] = 'Προέλευση:';
+$lang['unknown'] = 'άγνωστο';
+$lang['updating'] = 'Σε διαδικασία ενημέρωσης ...';
+$lang['updated'] = 'Η επέκταση %s ενημερώθηκε με επιτυχία';
+$lang['updates'] = 'Οι παρακάτω επεκτάσεις ενημερώθηκαν με επιτυχία:';
+$lang['update_none'] = 'Δεν βρέθηκαν ενημερώσεις.';
+$lang['deleting'] = 'Σε διαδικασία διαγραφής ...';
+$lang['deleted'] = 'Η επέκταση %s διαγράφηκε.';
+$lang['downloading'] = 'Σε διαδικασία μεταφόρτωσης ...';
+$lang['downloaded'] = 'Η επέκταση %s εγκαταστάθηκε με επιτυχία';
+$lang['downloads'] = 'Οι παρακάτω επεκτάσεις εγκαταστάθηκαν με επιτυχία:';
+$lang['download_none'] = 'Δεν βρέθηκαν επεκτάσεις ή εμφανίστηκε κάποιο πρόβλημα κατά την σχετική διαδικασία.';
+$lang['plugin'] = 'Επέκταση:';
+$lang['components'] = 'Συστατικά';
+$lang['noinfo'] = 'Αυτή η επέκταση δεν επέστρεψε κάποια πληροφορία - η επέκταση μπορεί να μην λειτουργεί κανονικά.';
+$lang['name'] = 'Όνομα:';
+$lang['date'] = 'Ημερομηνία:';
+$lang['type'] = 'Τύπος:';
+$lang['desc'] = 'Περιγραφή:';
+$lang['author'] = 'Συγγραφέας:';
+$lang['www'] = 'Διεύθυνση στο διαδίκτυο:';
+$lang['error'] = 'Εμφανίστηκε άγνωστο σφάλμα.';
+$lang['error_download'] = 'Δεν είναι δυνατή η μεταφόρτωση του αρχείου: %s';
+$lang['error_badurl'] = 'Το URL είναι μάλλον λανθασμένο - είναι αδύνατον να εξαχθεί το όνομα αρχείου από αυτό το URL';
+$lang['error_dircreate'] = 'Δεν είναι δυνατή η δημιουργία ενός προσωρινού φακέλου αποθήκευσης των μεταφορτώσεων';
+$lang['error_decompress'] = 'Δεν είναι δυνατή η αποσυμπίεση των μεταφορτώσεων. Αυτό μπορεί να οφείλεται σε μερική λήψη των μεταφορτώσεων, οπότε θα πρέπει να επαναλάβετε την διαδικασία ή το σύστημά σας δεν μπορεί να διαχειριστεί το συγκεκριμένο είδος συμπίεσης, οπότε θα πρέπει να εγκαταστήσετε την επέκταση χειροκίνητα.';
+$lang['error_copy'] = 'Εμφανίστηκε ένα σφάλμα αντιγραφής αρχείων κατά την διάρκεια εγκατάστασης της επέκτασης <em>%s</em>: ο δίσκος μπορεί να είναι γεμάτος ή να μην είναι σωστά ρυθμισμένα τα δικαιώματα πρόσβασης. Αυτό το γεγονός μπορεί να οδήγησε σε μερική εγκατάσταση της επέκτασης και άρα η DokuWiki εγκατάστασή σας να εμφανίσει προβλήματα σταθερότητας.';
+$lang['error_delete'] = 'Εμφανίστηκε ένα σφάλμα κατά την διαδικασία διαγραφής της επέκτασης <em>%s</em>. Η πιθανότερη αιτία είναι να μην είναι σωστά ρυθμισμένα τα δικαιώματα πρόσβασης.';
+$lang['enabled'] = 'Η επέκταση %s ενεργοποιήθηκε.';
+$lang['notenabled'] = 'Η επέκταση %s δεν μπορεί να ενεργοποιηθεί. Ελέγξτε τα δικαιώματα πρόσβασης.';
+$lang['disabled'] = 'Η επέκταση %s απενεργοποιήθηκε.';
+$lang['notdisabled'] = 'Η επέκταση %s δεν μπορεί να απενεργοποιηθεί. Ελέγξτε τα δικαιώματα πρόσβασης.';
+$lang['packageinstalled'] = 'Το πακέτο της επέκτασης (%d επέκταση(εις): %s) εγκαστήθηκε επιτυχημένα.';
diff --git a/lib/plugins/plugin/lang/en/admin_plugin.txt b/lib/plugins/plugin/lang/en/admin_plugin.txt
new file mode 100644
index 000000000..cb23b1e02
--- /dev/null
+++ b/lib/plugins/plugin/lang/en/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Plugin Management ======
+
+On this page you can manage everything to do with Dokuwiki [[doku>plugins|plugins]]. To be able to download and install a plugin your plugin folder must be writeable by the webserver.
+
+
diff --git a/lib/plugins/plugin/lang/en/lang.php b/lib/plugins/plugin/lang/en/lang.php
new file mode 100644
index 000000000..87570a708
--- /dev/null
+++ b/lib/plugins/plugin/lang/en/lang.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * english language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+
+$lang['menu'] = 'Manage Plugins';
+
+// custom language strings for the plugin
+$lang['download'] = "Download and install a new plugin";
+$lang['manage'] = "Installed Plugins";
+
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'update';
+$lang['btn_delete'] = 'delete';
+$lang['btn_settings'] = 'settings';
+$lang['btn_download'] = 'Download';
+$lang['btn_enable'] = 'Save';
+
+$lang['url'] = 'URL';
+
+$lang['installed'] = 'Installed:';
+$lang['lastupdate'] = 'Last updated:';
+$lang['source'] = 'Source:';
+$lang['unknown'] = 'unknown';
+
+// ..ing = header message
+// ..ed = success message
+
+$lang['updating'] = 'Updating ...';
+$lang['updated'] = 'Plugin %s updated successfully';
+$lang['updates'] = 'The following plugins have been updated successfully';
+$lang['update_none'] = 'No updates found.';
+
+$lang['deleting'] = 'Deleting ...';
+$lang['deleted'] = 'Plugin %s deleted.';
+
+$lang['downloading'] = 'Downloading ...';
+$lang['downloaded'] = 'Plugin %s installed successfully';
+$lang['downloads'] = 'The following plugins have been installed successfully:';
+$lang['download_none'] = 'No plugins found, or there has been an unknown problem during downloading and installing.';
+
+// info titles
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Components';
+$lang['noinfo'] = 'This plugin returned no information, it may be invalid.';
+$lang['name'] = 'Name:';
+$lang['date'] = 'Date:';
+$lang['type'] = 'Type:';
+$lang['desc'] = 'Description:';
+$lang['author'] = 'Author:';
+$lang['www'] = 'Web:';
+
+// error messages
+$lang['error'] = 'An unknown error occurred.';
+$lang['error_download'] = 'Unable to download the plugin file: %s';
+$lang['error_badurl'] = 'Suspect bad url - unable to determine file name from the url';
+$lang['error_dircreate'] = 'Unable to create temporary folder to receive download';
+$lang['error_decompress'] = 'The plugin manager was unable to decompress the downloaded file. '.
+ 'This maybe as a result of a bad download, in which case you should try again; '.
+ 'or the compression format may be unknown, in which case you will need to '.
+ 'download and install the plugin manually.';
+$lang['error_copy'] = 'There was a file copy error while attempting to install files for plugin '.
+ '<em>%s</em>: the disk could be full or file access permissions may be incorrect. '.
+ 'This may have resulted in a partially installed plugin and leave your wiki '.
+ 'installation unstable.';
+$lang['error_delete'] = 'There was an error while attempting to delete plugin <em>%s</em>. '.
+ 'The most probably cause is insufficient file or directory access permissions';
+
+$lang['enabled'] = 'Plugin %s enabled.';
+$lang['notenabled'] = 'Plugin %s could not be enabled, check file permissions.';
+$lang['disabled'] = 'Plugin %s disabled.';
+$lang['notdisabled'] = 'Plugin %s could not be disabled, check file permissions.';
+$lang['packageinstalled'] = 'Plugin package (%d plugin(s): %s) successfully installed.';
+
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/plugins/plugin/lang/eo/admin_plugin.txt b/lib/plugins/plugin/lang/eo/admin_plugin.txt
new file mode 100644
index 000000000..8cc59843b
--- /dev/null
+++ b/lib/plugins/plugin/lang/eo/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Administrado de Kromaĵoj ======
+
+En tiu ĉi paĝo vi povas administri ĉion pri DokuWiki-aj [[doku&gt;plugins|kromaĵoj]]. Por sukcesi elŝuti kaj instali kromaĵon, via dosierujo de kromaĵoj devas esti konservebla por la retservilo.
diff --git a/lib/plugins/plugin/lang/eo/lang.php b/lib/plugins/plugin/lang/eo/lang.php
new file mode 100644
index 000000000..ab9af73e1
--- /dev/null
+++ b/lib/plugins/plugin/lang/eo/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Esperantolanguage file
+ *
+ * @author Felipe Castro <fefcas@uol.com.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Felipe Castro <fefcas (cxe) gmail (punkto) com>
+ * @author Felipo Kastro <fefcas@gmail.com>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Erik Pedersen <erik pedersen@shaw.ca>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert BOGENSCHNEIDER <robog@gmx.de>
+ * @author Robert BOGENSCHNEIDER <bogi@UEA.org>
+ */
+$lang['menu'] = 'Administri Kromaĵojn';
+$lang['download'] = 'Elŝuti kaj instali novan kromaĵon';
+$lang['manage'] = 'Instalitaj kromaĵoj';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'ĝisdatigo';
+$lang['btn_delete'] = 'forigi';
+$lang['btn_settings'] = 'agordoj';
+$lang['btn_download'] = 'Elŝuti';
+$lang['btn_enable'] = 'Konservi';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalite:';
+$lang['lastupdate'] = 'Laste ĝisdatigite:';
+$lang['source'] = 'Fonto:';
+$lang['unknown'] = 'nekonate';
+$lang['updating'] = 'Ĝisdatiganta ...';
+$lang['updated'] = 'Kromaĵo %s estas sukcese ĝisdatigita';
+$lang['updates'] = 'La jenaj kromaĵoj estas sukcese ĝisdatigitaj';
+$lang['update_none'] = 'Neniu ĝisdatigo troviĝas.';
+$lang['deleting'] = 'Foriganta ...';
+$lang['deleted'] = 'Kromaĵo %s estas forigita.';
+$lang['downloading'] = 'Elŝutanta ...';
+$lang['downloaded'] = 'La kromaĵo %s estas sukcese instalita';
+$lang['downloads'] = 'La jenaj kromaĵoj estas sukcese instalitaj:';
+$lang['download_none'] = 'Neniu kromaĵo troveblas, aŭ eble okazis nekonata problemo dum elŝuto kaj instalo.';
+$lang['plugin'] = 'Kromaĵo:';
+$lang['components'] = 'Komponeroj';
+$lang['noinfo'] = 'Tiu ĉi kromaĵo liveris neniun informon: eble ĝi ne validas.';
+$lang['name'] = 'Nomo:';
+$lang['date'] = 'Dato:';
+$lang['type'] = 'Tipo:';
+$lang['desc'] = 'Priskribo:';
+$lang['author'] = 'Aŭtoro:';
+$lang['www'] = 'Retpaĝo:';
+$lang['error'] = 'Nekonata eraro okazis.';
+$lang['error_download'] = 'Maleblas elŝuti la kromaĵan dosieron: %s';
+$lang['error_badurl'] = 'Suspektinda malbona URL - maleblas difini la dosieran nomon el la URL';
+$lang['error_dircreate'] = 'Maleblas krei provizoran dosierujon por ricevi elŝutaĵon';
+$lang['error_decompress'] = 'La administrilo de kromaĵoj ne kapablis malkompakti la elŝutitan dosieron. Tio povas esti pro malkompleta elŝuto, tiaokaze vi devus provi refoje; aŭ eble la kompakta formato ne estas konata, tiaokaze vi bezonos elŝuti kaj instali la kromaĵon permane.';
+$lang['error_copy'] = 'Okazis eraro de dosierkopio dum provo instali dosierojn por la kromaĵo &lt;em&gt;%s&lt;/em&gt;: la disko povus esti plenplena aŭ aliro-rajtoj povus esti misdifinitaj. Tio povus rezulti en malkomplete instalita kromaĵo kaj igi vian vikion malstabila.';
+$lang['error_delete'] = 'Okazis eraro dum provo forigi la kromaĵon &lt;em&gt;%s&lt;/em&gt;. Plejprobable tio sekvas de nesufiĉa rajto por aliri la dosieron aŭ ties ujon.';
+$lang['enabled'] = 'La kromaĵo %s estas ebligita.';
+$lang['notenabled'] = 'La kromaĵo %s ne povis esti ebligita, kontrolu dosier-permesojn.';
+$lang['disabled'] = 'La kromaĵo %s estas malebligita.';
+$lang['notdisabled'] = 'La kromaĵo %s ne povis esti malebligita, kontrolu dosier-permesojn.';
+$lang['packageinstalled'] = 'Kromaĵa pakaĵo (%d kromaĵo(j): %s) sukcese instalitaj.';
diff --git a/lib/plugins/plugin/lang/es/admin_plugin.txt b/lib/plugins/plugin/lang/es/admin_plugin.txt
new file mode 100644
index 000000000..973789f03
--- /dev/null
+++ b/lib/plugins/plugin/lang/es/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Administración de Plugin (agregados) ======
+
+En esta página tu puedes administrar todo lo que tenga que ver con los [[doku>plugins|plugins]] de Dokuwiki. Para poder descargar e instalar un plugin el usuario correspondiente al servidor de web debe poder escribir en el directorio de plugins.
diff --git a/lib/plugins/plugin/lang/es/lang.php b/lib/plugins/plugin/lang/es/lang.php
new file mode 100644
index 000000000..ac548245b
--- /dev/null
+++ b/lib/plugins/plugin/lang/es/lang.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * spanish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Miguel Pagano <miguel.pagano@gmail.com>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ * @author Gabriel Castillo <gch@pumas.ii.unam.mx>
+ * @author oliver@samera.com.py
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Manuel Meco <manuel.meco@gmail.com>
+ * @author VictorCastelan <victorcastelan@gmail.com>
+ * @author Jordan Mero hack.jord@gmail.com
+ * @author Felipe Martinez <metalmartinez@gmail.com>
+ * @author Javier Aranda <internet@javierav.com>
+ * @author Zerial <fernando@zerial.org>
+ * @author Marvin Ortega <maty1206@maryanlinux.com>
+ * @author Daniel Castro Alvarado <dancas2@gmail.com>
+ * @author Fernando J. Gómez <fjgomez@gmail.com>
+ * @author Victor Castelan <victorcastelan@gmail.com>
+ * @author Mauro Javier Giamberardino <mgiamberardino@gmail.com>
+ * @author emezeta <emezeta@infoprimo.com>
+ * @author Oscar Ciudad <oscar@jacho.net>
+ * @author Ruben Figols <ruben.figols@gmail.com>
+ */
+$lang['menu'] = 'Administración de Plugins';
+$lang['download'] = 'Descargar e instalar un nuevo plugin';
+$lang['manage'] = 'Plugins instalados';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'actualizar';
+$lang['btn_delete'] = 'borrar';
+$lang['btn_settings'] = 'configuraciones';
+$lang['btn_download'] = 'Descargar';
+$lang['btn_enable'] = 'Guardar';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalado:';
+$lang['lastupdate'] = 'Última actualización:';
+$lang['source'] = 'Origen:';
+$lang['unknown'] = 'desconocido';
+$lang['updating'] = 'Actualizando ...';
+$lang['updated'] = 'El plugin %s ha sido actualizado con éxito';
+$lang['updates'] = 'Los siguientes plugins han sido actualizados con éxito';
+$lang['update_none'] = 'No se encontraron actualizaciones.';
+$lang['deleting'] = 'Eliminando ...';
+$lang['deleted'] = 'El plugin %s ha sido eliminado.';
+$lang['downloading'] = 'Descargando ...';
+$lang['downloaded'] = 'El plugin %s ha sido instalado con éxito';
+$lang['downloads'] = 'Los siguientes plugins han sido instalados con éxito:';
+$lang['download_none'] = 'No se han encontrado plugins, o hubo algún problema durante la descarga o la instalación.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Componentes';
+$lang['noinfo'] = 'Este plugin no devolvió información, puede ser inválido.';
+$lang['name'] = 'Nombre:';
+$lang['date'] = 'Fecha:';
+$lang['type'] = 'Tipo:';
+$lang['desc'] = 'Descripción:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Ha ocurrido un error desconocido.';
+$lang['error_download'] = 'Incapaz de descargar el archivo del plugin: %s';
+$lang['error_badurl'] = 'Se sospecha que la URL es incorrecta - incapaz de determinar el nombre del archivo a partir de la URL.';
+$lang['error_dircreate'] = 'Incapaz de crear el directorio temporal para la descarga';
+$lang['error_decompress'] = 'El administrador de plugins fue incapaz de descomprimir el fichero descargado. Esto puede ser por una descarga errónea, en cuyo caso debieras intentar nuevamente; o el formato de compresión es desconocido, en este caso deberás descargar e instalar el plugin manualmente.';
+$lang['error_copy'] = 'Hubo un error al copiar el fichero mientras se intentaban instalar ficheros para el plugin <em>%s</em>: el disco puede estar lleno o los permisos del fichero pueden ser incorrectos. Esto puede haber terminado con una instalación parcial del plugin y haber dejado la instalación del wiki en una situación inestable';
+$lang['error_delete'] = 'Hubo un error al intentar eliminar el plugin <em>%s</em>. La causa más probable es que no se cuente con los permisos necesarios en el fichero o en el directorio';
+$lang['enabled'] = 'Plugin %s habilitado.';
+$lang['notenabled'] = 'Plugin %s no puede ser habilitado, verifica los permisos del archivo.';
+$lang['disabled'] = 'Plugin %s desabilitado.';
+$lang['notdisabled'] = 'Plugin %s no puede ser desabilitado, verifica los permisos de archivo.';
+$lang['packageinstalled'] = 'Plugin (%d plugin(s): %s) instalado exitosamente.';
diff --git a/lib/plugins/plugin/lang/et/lang.php b/lib/plugins/plugin/lang/et/lang.php
new file mode 100644
index 000000000..088acf39b
--- /dev/null
+++ b/lib/plugins/plugin/lang/et/lang.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Estonian language file
+ *
+ * @author kristian.kankainen@kuu.la
+ * @author Rivo Zängov <eraser@eraser.ee>
+ */
+$lang['manage'] = 'Paigaldatud pluginad';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'uuenda';
+$lang['btn_delete'] = 'kustuta';
+$lang['btn_settings'] = 'seaded';
+$lang['btn_download'] = 'Lae alla';
+$lang['btn_enable'] = 'Salvesta';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Paigaldatud:';
+$lang['lastupdate'] = 'Viimati uuendatud:';
+$lang['source'] = 'Allikas:';
+$lang['unknown'] = 'tundmatu';
+$lang['updating'] = 'Uuendamine ...';
+$lang['update_none'] = 'Uuendusi ei leitud.';
+$lang['deleting'] = 'Kustutamine ...';
+$lang['deleted'] = 'Plugin %s on kustutatud.';
+$lang['downloading'] = 'Allalaadimine ...';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Komponendid';
+$lang['name'] = 'Nimi:';
+$lang['date'] = 'Kuupäev';
+$lang['type'] = 'Tüüp:';
+$lang['desc'] = 'Kirjeldus:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Veeb:';
diff --git a/lib/plugins/plugin/lang/eu/admin_plugin.txt b/lib/plugins/plugin/lang/eu/admin_plugin.txt
new file mode 100644
index 000000000..367cf37ee
--- /dev/null
+++ b/lib/plugins/plugin/lang/eu/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Plugin Kudeaketa ======
+
+Orri honetan Dokuwiki [[doku>plugins|plugin-ekin]] erlazionatutako edozer kudeatu dezakezu. Plugin-en bat deskargatu eta instalatu ahal izateko, plugin-en direktorioak web zerbitzariarengatik idazgarria izan behar du.
diff --git a/lib/plugins/plugin/lang/eu/lang.php b/lib/plugins/plugin/lang/eu/lang.php
new file mode 100644
index 000000000..56c03325f
--- /dev/null
+++ b/lib/plugins/plugin/lang/eu/lang.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Basque language file
+ *
+ * @author Inko Illarramendi <inko.i.a@gmail.com>
+ */
+$lang['menu'] = 'Plugin-ak Kudeatu';
+$lang['download'] = 'Plugin berri bat deskargatu eta instalatu';
+$lang['manage'] = 'Instalatutako Plugin-ak';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'eguneratu';
+$lang['btn_delete'] = 'ezabatu';
+$lang['btn_settings'] = 'ezarpenak';
+$lang['btn_download'] = 'Deskargatu';
+$lang['btn_enable'] = 'Gorde';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalatua:';
+$lang['lastupdate'] = 'Azken aldiz eguneratua:';
+$lang['source'] = 'Iturria:';
+$lang['unknown'] = 'ezezaguna';
+$lang['updating'] = 'Eguneratzen ...';
+$lang['updated'] = 'Arrakastaz eguneratu da %s plugin-a';
+$lang['updates'] = 'Ondorengo plugin-ak ondo eguneratu dira';
+$lang['update_none'] = 'Ez da eguneraketarik aurkitu.';
+$lang['deleting'] = 'Ezabatzen ...';
+$lang['deleted'] = '%s plugin-a ezabatua.';
+$lang['downloading'] = 'Deskargatzen ...';
+$lang['downloaded'] = '%s Plugin-a arrakastaz instalatua';
+$lang['downloads'] = 'Ondorengo plugin-ak arrakastaz instalatu dira:';
+$lang['download_none'] = 'Ez da plugin-ik aurkitu, edo arazo ezezagunen bat egon da deskargatu eta instalatzerako garaian.';
+$lang['plugin'] = 'Plugin-a:';
+$lang['components'] = 'Osagaiak';
+$lang['noinfo'] = 'Plugin honek ez du informaziorik itzuli, agian ez da erabilgarria.';
+$lang['name'] = 'izena:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Mota:';
+$lang['desc'] = 'Deskribapena:';
+$lang['author'] = 'Egilea:';
+$lang['www'] = 'Web-gunea:';
+$lang['error'] = 'Akats ezezagun bat gertatu da.';
+$lang['error_download'] = 'Ezin izan da plugin-aren honako fitxategia deskargatu: %s';
+$lang['error_badurl'] = 'Ustezko url okerra - ezin izan da fitxategi izena url-tik zehaztu';
+$lang['error_dircreate'] = 'Ezin izan da aldiroko karpeta sortu deskarga jasotzeko';
+$lang['error_decompress'] = 'Plugin kudeatzaileak ezin izan du deskargatutako fitxategia erauzi. Deskarga oker baten ondorioa izan daiteke, eta hala bada berriz saiatu beharko zenuke; edo agian trinkotze formatua ezezaguna da, hala izanik plugin-a eskuz deskargatu eta instalatu beharko zenuelarik.';
+$lang['error_copy'] = 'Fitxategi kopia akats bat egon da <em>%s</em> plugin-arentzat fitxategiak instalatzen saiatzean: diska betea egon liteke edo fitxategi atzipen baimena okerra izan daiteke. Honek partzialki instalatutako plugin bat eta wiki instalazioa ezegonkor utzi dezake.';
+$lang['error_delete'] = 'Akats bat gertatu da <em>%s</em> plugin-a ezabatzeko saiakera egitean. Arrazoia ziurrenik fitxategi edo direktorio atzipen baimen nahikoak ez izatea da.';
+$lang['enabled'] = '%s Plugin-a gaitua.';
+$lang['notenabled'] = '%s Plugin-a ezin izan da gaitu, egiaztatu fitxategi baimenak.';
+$lang['disabled'] = '%s Plugin-a ezgaitua.';
+$lang['notdisabled'] = '%s Plugin-a ezin izan da ezgaitu, egiaztatu fitxategi baimenak. ';
+$lang['packageinstalled'] = 'Plugin paketea (%d plugin(s): %s) arrakastaz instalatua izan da.';
diff --git a/lib/plugins/plugin/lang/fa/admin_plugin.txt b/lib/plugins/plugin/lang/fa/admin_plugin.txt
new file mode 100644
index 000000000..cd11fb460
--- /dev/null
+++ b/lib/plugins/plugin/lang/fa/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== مدیریت افزونه‌ها ======
+
+در این صفحه شما می‌توانید [[doku>plugins|افزونه‌های]] Dokuwiki را مدیریت کنید. برای امکان دریافت و نصب افزونه‌ها، باید به شاخه‌ی افزونه‌ها (lib/plugin) دسترسی نوشتن برای وب‌سرور را محیا کنید. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/fa/lang.php b/lib/plugins/plugin/lang/fa/lang.php
new file mode 100644
index 000000000..8f3fb8a41
--- /dev/null
+++ b/lib/plugins/plugin/lang/fa/lang.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Persian language file
+ *
+ * @author behrad eslamifar <behrad_es@yahoo.com)
+ * @author Mohsen Firoozmandan <info@mambolearn.com>
+ * @author omidmr@gmail.com
+ * @author Omid Mottaghi <omidmr@gmail.com>
+ * @author Mohammad Reza Shoaei <shoaei@gmail.com>
+ */
+$lang['menu'] = 'مدیریت افزونه‌ها';
+$lang['download'] = 'دریافت و نصب افزونه';
+$lang['manage'] = 'افزونه‌های نصب شده';
+$lang['btn_info'] = 'مشخصات';
+$lang['btn_update'] = 'بروزرسانی';
+$lang['btn_delete'] = 'حذف';
+$lang['btn_settings'] = 'تنظیمات';
+$lang['btn_download'] = 'دانلود';
+$lang['btn_enable'] = 'ذخیره';
+$lang['url'] = 'آدرس';
+$lang['installed'] = 'نصب شده:';
+$lang['lastupdate'] = 'آخرین بروزرسانی:';
+$lang['source'] = 'منبع:';
+$lang['unknown'] = 'ناشناس';
+$lang['updating'] = 'در حال به روز رسانی...';
+$lang['updated'] = 'افزونه‌ی %s با موفقیت به روز رسانی شد';
+$lang['updates'] = 'افزونه‌های زیر با موفقیت به روز رسانی شده است.';
+$lang['update_none'] = 'به روز رسانی‌ای یافت نشد .';
+$lang['deleting'] = 'در حال حذف...';
+$lang['deleted'] = 'افزونه‌ی %s پاک شد.';
+$lang['downloading'] = 'در حال دریافت...';
+$lang['downloaded'] = 'افزونه‌ی %s با موفقیت نصب شد';
+$lang['downloads'] = 'افزونه‌های زیر با موفقیت نصب شدند:';
+$lang['download_none'] = 'هیچ افزونه‌ای یافت نشد، یا یک مشکل ناشناخته در زمان دریافت و نصب پیش آمده است.';
+$lang['plugin'] = 'افزونه:';
+$lang['components'] = 'کامپوننت';
+$lang['noinfo'] = 'این افزونه هیچ اطلاعاتی را برنگردانده است، ممکن است بی‌اعتبار باشد.';
+$lang['name'] = 'اسم:';
+$lang['date'] = 'تاریخ:';
+$lang['type'] = 'نوع:';
+$lang['desc'] = 'توضیحات:';
+$lang['author'] = 'نویسنده:';
+$lang['www'] = 'وب‌سایت:';
+$lang['error'] = 'یک مشکل ناشناخته پیش آمده.';
+$lang['error_download'] = 'توانایی دریافت افزونه‌ی %s نمی‌باشد.';
+$lang['error_badurl'] = 'آدرس مشکل دارد - توانایی تشخیص نام فایل از آدرس وجود ندارد';
+$lang['error_dircreate'] = 'امکان ایجاد شاخه‌ی موقتی برای دریافت فایل نیست.';
+$lang['error_decompress'] = 'باز کردن فایل با مشکل مواجه شد. این اشکال ممکن است به خاطر دریافت ناقصِ فایل باشد که باید دوباره تلاش کنید، یا فرمت فشرده‌سازی شناخته شده نیست، که باید این افزونه رو دستی نصب کنید.';
+$lang['error_copy'] = 'توانایی کپی کردن فایل‌های افزونه‌ی <em>%s</em> در زمان نصب وجود ندارد. ممکن است دسترسی شاخه‌ی افزونه‌ها مشکل داشته باشد. این مشکل ممکن است باعث نصب ناقص افزونه شود و ویکی را با مشکل مواجه کند.';
+$lang['error_delete'] = 'توانایی حذف افزونه‌ی <em>%s</em> وجود ندارد. این مشکل به خاطر دسترسی فایل یا شاخه‌ی افزونه پیش می‌آید.';
+$lang['enabled'] = 'افزونه‌ی %s فعال شد.';
+$lang['notenabled'] = 'افزونه‌ی %s قابلیت فعال کردن ندارد، دسترسی‌ها را چک کنید.';
+$lang['disabled'] = 'افزونه‌ی %s غیرفعال شد.';
+$lang['notdisabled'] = 'افزونه‌ی %s قابلیت غیرفعال کردن ندارد، دسترسی‌ها را چک کنید.';
+$lang['packageinstalled'] = 'بسته افزونه (%d افزونه: %s) به درستی نصب شد.';
diff --git a/lib/plugins/plugin/lang/fi/admin_plugin.txt b/lib/plugins/plugin/lang/fi/admin_plugin.txt
new file mode 100644
index 000000000..9cdfa1c11
--- /dev/null
+++ b/lib/plugins/plugin/lang/fi/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Liitännäisten hallinta ======
+
+Tällä sivulla voit hallita DokuWikin [[doku>plugins|liitännäisiä]]. Voidaksesi ladata ja asentaa liitännäisiä pitää web-palvelimella olla kirjoitusoikeudet plugin hakemistoon.
diff --git a/lib/plugins/plugin/lang/fi/lang.php b/lib/plugins/plugin/lang/fi/lang.php
new file mode 100644
index 000000000..923029a6f
--- /dev/null
+++ b/lib/plugins/plugin/lang/fi/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Finnish language file
+ *
+ * @author otto@valjakko.net
+ * @author Otto Vainio <otto@valjakko.net>
+ * @author Teemu Mattila <ghcsystems@gmail.com>
+ * @author Sami Olmari <sami@olmari.fi>
+ */
+$lang['menu'] = 'Ylläpidä liitännäisiä';
+$lang['download'] = 'Lataa ja asenna uusi liitännäinen';
+$lang['manage'] = 'Asennetut liitännäiset';
+$lang['btn_info'] = 'tietoa';
+$lang['btn_update'] = 'päivitä';
+$lang['btn_delete'] = 'poista';
+$lang['btn_settings'] = 'asetukset';
+$lang['btn_download'] = 'Lataa';
+$lang['btn_enable'] = 'Tallenna';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Asennettu:';
+$lang['lastupdate'] = 'Päivitetty viimeksi:';
+$lang['source'] = 'Lähde:';
+$lang['unknown'] = 'tuntematon';
+$lang['updating'] = 'Päivitetään ...';
+$lang['updated'] = 'Liitännäinen %s päivitetty onnistuneesti';
+$lang['updates'] = 'Seuraavat liitännäiset on päivitetty onnistuneesti';
+$lang['update_none'] = 'Päivityksiä ei löytynyt';
+$lang['deleting'] = 'Poistetaan ...';
+$lang['deleted'] = 'Liitännäinen %s poistettu.';
+$lang['downloading'] = 'Ladataan ...';
+$lang['downloaded'] = 'Liitännäinen %s asennettu onnistuneesti';
+$lang['downloads'] = 'Seuraavat liitännäiset on asennettu onnistuneesti';
+$lang['download_none'] = 'Liitännäisiä ei löytynyt tai on tapahtunut joku tuntematon virhe latauksen ja asennuksen aikana.';
+$lang['plugin'] = 'Liitännäinen:';
+$lang['components'] = 'Osa';
+$lang['noinfo'] = 'Liitännäinen ei palauttanut mitään tietoa ja se voi olla epäkelpo.';
+$lang['name'] = 'Nimi:';
+$lang['date'] = 'Päiväys:';
+$lang['type'] = 'Tyyppi:';
+$lang['desc'] = 'Kuvaus:';
+$lang['author'] = 'Tekijä:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Tapahtui tuntematon virhe.';
+$lang['error_download'] = 'Liitännäistiedoston %s latauksessa tapahtui tuntematon virhe.';
+$lang['error_badurl'] = 'URL vaikuttaa olleen virheellinen. Siitä ei pystytty päättelemään tiedoston nimeä';
+$lang['error_dircreate'] = 'Ei pystytty luomaan väliaikaista hakemistoa latausta varten';
+$lang['error_decompress'] = 'Liitännäishallinta ei pystynyt purkamaan ladattua tiedostoa. Lataus voi olla epäonnistunut. Siinä tapauksessa voit yrittää uudestaan. Pakkaustapa voi myös olla tuntematon. Siinä tapauksessa sinun pitää ladata ja asentaa liitännäinen käsin.';
+$lang['error_copy'] = 'Tiedoston kopioinnissa tapahtui liitännäisen <em>%s</em> asennuksen aikana virhe. Levy voi olla täynnä tai kansioiden oikeudet voivat olla väärin. Liitännäinen voi olla osittain asennettu ja tämä voi jättää wikiasennukseesi epävakaaseen tilaan.';
+$lang['error_delete'] = 'Liitännäisen <em>%s</em> poistossa tapahtui virhe. Todennäköisin syy on puutteelliset tiedoston tai hakemiston oikeudet';
+$lang['enabled'] = 'Liitännäinen %s käytössä';
+$lang['notenabled'] = 'Liitännäistä %s ei voitu ottaa käyttöön. Tarkista tiedostojen oikeudet.';
+$lang['disabled'] = 'Liitännäinen %s pois käytössä';
+$lang['notdisabled'] = 'Liitännäistä %s ei voitu ottaa pois käytöstä. Tarkista tiedostojen oikeudet.';
+$lang['packageinstalled'] = 'Pluginpaketti (%d plugin: %s:) asennettu onnistuneesti.';
diff --git a/lib/plugins/plugin/lang/fr/admin_plugin.txt b/lib/plugins/plugin/lang/fr/admin_plugin.txt
new file mode 100644
index 000000000..f90b627f3
--- /dev/null
+++ b/lib/plugins/plugin/lang/fr/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== Gestion des modules externes ======
+
+Cette page vous permet de gérer tout ce qui a trait aux [[doku>fr:plugins|modules externes]] de DokuWiki. Pour télécharger et installer un module, le répertoire « ''plugin'' » doit être accessible en écriture pour le serveur Web.
+
diff --git a/lib/plugins/plugin/lang/fr/lang.php b/lib/plugins/plugin/lang/fr/lang.php
new file mode 100644
index 000000000..bb0b49872
--- /dev/null
+++ b/lib/plugins/plugin/lang/fr/lang.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * french language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Guy Brand <gb@unistra.fr>
+ * @author Delassaux Julien <julien@delassaux.fr>
+ * @author Maurice A. LeBlanc <leblancma@cooptel.qc.ca>
+ * @author stephane.gully@gmail.com
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author olivier duperray <duperray.olivier@laposte.net>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author Philippe Bajoit <philippe.bajoit@gmail.com>
+ * @author Florian Gaub <floriang@floriang.net>
+ * @author Samuel Dorsaz samuel.dorsaz@novelion.net
+ * @author Johan Guilbaud <guilbaud.johan@gmail.com>
+ * @author schplurtz@laposte.net
+ * @author skimpax@gmail.com
+ */
+$lang['menu'] = 'Gestion des modules externes';
+$lang['download'] = 'Télécharger et installer un nouveau module';
+$lang['manage'] = 'Modules installés';
+$lang['btn_info'] = 'Info';
+$lang['btn_update'] = 'Mettre à jour';
+$lang['btn_delete'] = 'Supprimer';
+$lang['btn_settings'] = 'Paramètres';
+$lang['btn_download'] = 'Télécharger';
+$lang['btn_enable'] = 'Enregistrer';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Installé :';
+$lang['lastupdate'] = 'Dernière mise à jour :';
+$lang['source'] = 'Source :';
+$lang['unknown'] = 'inconnu';
+$lang['updating'] = 'Mise à jour…';
+$lang['updated'] = 'Modules %s mis à jour avec succès';
+$lang['updates'] = 'Les modules suivants ont été mis à jour avec succès';
+$lang['update_none'] = 'Aucune mise à jour n\'a été trouvée.';
+$lang['deleting'] = 'Suppression…';
+$lang['deleted'] = 'Module %s supprimé.';
+$lang['downloading'] = 'Téléchargement…';
+$lang['downloaded'] = 'Module %s installé avec succès';
+$lang['downloads'] = 'Les modules suivants ont été installés avec succès :';
+$lang['download_none'] = 'Aucun module n\'était trouvé, ou un problème inconnu est survenu durant le téléchargement et l\'installation.';
+$lang['plugin'] = 'Module :';
+$lang['components'] = 'Composants';
+$lang['noinfo'] = 'Ce module externe n\'a transmis aucune information, il pourrait être invalide.';
+$lang['name'] = 'Nom :';
+$lang['date'] = 'Date :';
+$lang['type'] = 'Type :';
+$lang['desc'] = 'Description :';
+$lang['author'] = 'Auteur :';
+$lang['www'] = 'Site web :';
+$lang['error'] = 'Une erreur inconnue est survenue.';
+$lang['error_download'] = 'Impossible de télécharger le fichier du module : %s';
+$lang['error_badurl'] = 'URL suspecte. Impossible de déterminer le nom du fichier à partir de l\'URL';
+$lang['error_dircreate'] = 'Impossible de créer le répertoire temporaire pour réceptionner le téléchargement';
+$lang['error_decompress'] = 'Le gestionnaire de modules externes a été incapable de décompresser le fichier téléchargé. Ceci peut être le résultat d\'un mauvais téléchargement, auquel cas vous devriez réessayer ; ou bien le format de compression est inconnu, auquel cas vous devez télécharger et installer le module manuellement.';
+$lang['error_copy'] = 'Une erreur de copie est survenue lors de l\'installation des fichiers du module <em>%s</em> : votre disque est peut-être plein ou les droits d\'accès au fichier sont incorrects. Il a pu en résulter une installation partielle du module rendant votre installation du wiki instable.';
+$lang['error_delete'] = 'Une erreur est survenue à la suppression du module <em>%s</em>. La raison la plus probable est l\'insuffisance des droits sur les fichiers ou le répertoire.';
+$lang['enabled'] = 'Module %s activé.';
+$lang['notenabled'] = 'Le module %s n\'a pas pu être activé, vérifiez le fichier des permissions.';
+$lang['disabled'] = 'Module %s désactivé.';
+$lang['notdisabled'] = 'Le module %s n\'a pas pu être désactivé, vérifiez le fichier des permissions.';
+$lang['packageinstalled'] = 'Ensemble de modules (%d module(s): %s) installé avec succès.';
diff --git a/lib/plugins/plugin/lang/gl/admin_plugin.txt b/lib/plugins/plugin/lang/gl/admin_plugin.txt
new file mode 100644
index 000000000..216285a8d
--- /dev/null
+++ b/lib/plugins/plugin/lang/gl/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Xestión de Extensións ======
+
+Nesta páxina podes xestionar todas as accións posíbeis cos [[doku>plugins|extensións]] do DokuWiki. Para poder descargar e instalar unha extensión, o teu cartafol de extensións debe ser escribíbel polo servidor web.
diff --git a/lib/plugins/plugin/lang/gl/lang.php b/lib/plugins/plugin/lang/gl/lang.php
new file mode 100644
index 000000000..a314b71b9
--- /dev/null
+++ b/lib/plugins/plugin/lang/gl/lang.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Galicianlanguage file
+ *
+ * @author Medúlio <medulio@ciberirmandade.org>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ */
+$lang['menu'] = 'Xestionar Extensións';
+$lang['download'] = 'Descargar e instalar unha nova extensión';
+$lang['manage'] = 'Extensións Instalados';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'actualización';
+$lang['btn_delete'] = 'eliminar';
+$lang['btn_settings'] = 'configuración';
+$lang['btn_download'] = 'Descargar';
+$lang['btn_enable'] = 'Gardar';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalado:';
+$lang['lastupdate'] = 'Última actualización:';
+$lang['source'] = 'Fonte:';
+$lang['unknown'] = 'descoñecido';
+$lang['updating'] = 'Actualizando...';
+$lang['updated'] = 'Actualizouse correctamente a extensión %s';
+$lang['updates'] = 'Actualizáronse correctamente as seguintes extensións';
+$lang['update_none'] = 'Non se atoparon actualizacións.';
+$lang['deleting'] = 'Eliminando...';
+$lang['deleted'] = 'Eliminado a extensión %s.';
+$lang['downloading'] = 'Descargando...';
+$lang['downloaded'] = 'Instalouse correctamente a extensión %s';
+$lang['downloads'] = 'Instaláronse correctamente as seguintes extensións:';
+$lang['download_none'] = 'Non se atoparon extensións, ou aconteceu un problema descoñecido durante a descarga e instalación.';
+$lang['plugin'] = 'Extensión:';
+$lang['components'] = 'Compoñentes';
+$lang['noinfo'] = 'Esta extensión non devolveu información ningunha. Pode que non sexa válida.';
+$lang['name'] = 'Nome:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipo:';
+$lang['desc'] = 'Descrición:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Houbo un erro descoñecido.';
+$lang['error_download'] = 'Non se puido descargar o arquivo de extensión: %s';
+$lang['error_badurl'] = 'URL posiblemente incorrecto - non se puido determinar o nome do arquivo mediante o URL';
+$lang['error_dircreate'] = 'Non se puido crear un cartafol temporal para recibir a descarga';
+$lang['error_decompress'] = 'O xestor de extensións non foi quen de descomprimir o arquivo descargado. Isto podería ser causado por unha descarga corrupta, polo que, en tal caso, podes tentalo de novo; ou pode que o formato de compresión sexa descoñecido, co que precisarás descargar e instalar a extensión de xeito manual.';
+$lang['error_copy'] = 'Houbo un erro de copia de arquivo ao tentar instalar a extensión <em>%s</em>: pode que o disco estea cheo ou que os permisos de acceso sexan incorrectos. Isto podería dar lugar a unha instalación parcial da extensión e facer que a túa instalación do wiki se volva inestable.';
+$lang['error_delete'] = 'Houbo un erro ao tentar eliminar a extensión <em>%s</em>. O máis probable é que sexa causado por permisos de acceso ao arquivo ou directorio insuficientes.';
+$lang['enabled'] = 'Extensión %s activado.';
+$lang['notenabled'] = 'A extensión %s non puido ser activada, comproba os permisos de arquivo.';
+$lang['disabled'] = 'Extensión %s desactivada.';
+$lang['notdisabled'] = 'A extensión %s non puido ser desactivada, comproba os permisos de arquivo.';
+$lang['packageinstalled'] = 'Paquete de extensión (%d plugin(s): %s) instalado axeitadamente.';
diff --git a/lib/plugins/plugin/lang/he/admin_plugin.txt b/lib/plugins/plugin/lang/he/admin_plugin.txt
new file mode 100644
index 000000000..206d368db
--- /dev/null
+++ b/lib/plugins/plugin/lang/he/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== ניהול הרחבות ======
+
+בדף זה ניתן לנהל כל דבר הקשור ל[[doku>plugins|הרחבות]] של DokuWiki. כדי שניתן יהיה להוריד ולהתקין הרחבה על תיקית ה-plugins שלך להיות ברת כתיבה על ידי שרת הרשת.
+
+
diff --git a/lib/plugins/plugin/lang/he/lang.php b/lib/plugins/plugin/lang/he/lang.php
new file mode 100644
index 000000000..47253e335
--- /dev/null
+++ b/lib/plugins/plugin/lang/he/lang.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * hebrew language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author DoK <kamberd@yahoo.com>
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ * @author Moshe Kaplan <mokplan@gmail.com>
+ * @author Yaron Yogev <yaronyogev@gmail.com>
+ * @author Yaron Shahrabani <sh.yaron@gmail.com>
+ */
+$lang['menu'] = 'ניהול הרחבות';
+$lang['download'] = 'הורדת והתקנת הרחבה חדשה';
+$lang['manage'] = 'הרחבות מותקנות';
+$lang['btn_info'] = 'מידע';
+$lang['btn_update'] = 'עידכון';
+$lang['btn_delete'] = 'מחיקה';
+$lang['btn_settings'] = 'הגדרות';
+$lang['btn_download'] = 'הורדה';
+$lang['btn_enable'] = 'שמירה';
+$lang['url'] = 'URL';
+$lang['installed'] = 'מותקנות:';
+$lang['lastupdate'] = 'עודכנו לאחרונה:';
+$lang['source'] = 'מקור:';
+$lang['unknown'] = 'לא ידוע';
+$lang['updating'] = 'מעדכן ...';
+$lang['updated'] = 'ההרחבה %s עודכנה בהצלחה';
+$lang['updates'] = 'ההרחבות הבאות עודכנו בהצלחה';
+$lang['update_none'] = 'לא נמצאו עידכונים.';
+$lang['deleting'] = 'מוחק ...';
+$lang['deleted'] = 'ההרחבה %s נמחקה.';
+$lang['downloading'] = 'מוריד ...';
+$lang['downloaded'] = 'ההרחבה %s הותקנה בהצלחה';
+$lang['downloads'] = 'ההרחבות הבאות הותקנו בהצלחה:';
+$lang['download_none'] = 'לא נמצאו הרחבות או שחלה בעיה בלתי ידועה במהלך ההורדה וההתקנה.';
+$lang['plugin'] = 'הרחבה:';
+$lang['components'] = 'רכיבים';
+$lang['noinfo'] = 'הרחבה זו לא השיבה מידע, יתכן כי היא אינה בתוקף.';
+$lang['name'] = 'שם:';
+$lang['date'] = 'תאריך:';
+$lang['type'] = 'סוג:';
+$lang['desc'] = 'תיאור:';
+$lang['author'] = 'מחבר:';
+$lang['www'] = 'רשת:';
+$lang['error'] = 'שגיאה לא ידועה ארעה.';
+$lang['error_download'] = 'כשל בהורדת קובץ ההרחבה: %s';
+$lang['error_badurl'] = 'כנראה כתובת שגויה - כשל בקביעת שם הקובץ מהכתובת';
+$lang['error_dircreate'] = 'כשל ביצירת תיקיה זמנית לקבלת ההורדה';
+$lang['error_decompress'] = 'מנהל ההרחבות כשל בפרישת הקובץ שהורד. יתכן כי זו תוצאה של הורדה תקולה ובמקרה זה עליך לנסות שנית; או שיתכן כי תסדיר הכיווץ אינו ידוע, במקרה זה יהיה עליך להוריד ולהתקין את ההרחבה ידנית.';
+$lang['error_copy'] = 'חלה שגיאה בהעתקת הקובץ בניסיון להתקין קבצים להרחבה <em>%s</em>: ייתכן כי הדיסק מלא או שהרשאות הגישה לקבצים שגויות. יתכן כי בשל כך נוצרה התקנה חלקית של ההרחבה שתשאיר את התקנת הויקי שלך לא יציבה.';
+$lang['error_delete'] = 'חלה שגיאה בעת ניסיון למחיקת ההרחבה <em>%s</em>. הסיבה הסבירה ביותר היא הרשאות גישה לקבצים ולספריות שאינן מספקות';
+$lang['enabled'] = 'תוסף %s מופעל.';
+$lang['notenabled'] = 'לא ניתן להפעיל את התוסף %s, בדוק הרשאות קבצים.';
+$lang['disabled'] = 'תוסף %s מושבת.';
+$lang['notdisabled'] = 'לא ניתן להשבית את התוסף %s, בדוק הרשאות קבצים.';
diff --git a/lib/plugins/plugin/lang/hi/lang.php b/lib/plugins/plugin/lang/hi/lang.php
new file mode 100644
index 000000000..ab29c6550
--- /dev/null
+++ b/lib/plugins/plugin/lang/hi/lang.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Hindi language file
+ *
+ * @author Abhinav Tyagi <abhinavtyagi11@gmail.com>
+ * @author yndesai@gmail.com
+ */
+$lang['unknown'] = 'अज्ञात';
+$lang['deleted'] = 'मिटाया हुआ';
+$lang['date'] = 'दिनांक:';
+$lang['author'] = 'लेखक:';
+$lang['error'] = 'अज्ञात त्रुटि हुइ';
diff --git a/lib/plugins/plugin/lang/hr/lang.php b/lib/plugins/plugin/lang/hr/lang.php
new file mode 100644
index 000000000..96f1d6afe
--- /dev/null
+++ b/lib/plugins/plugin/lang/hr/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Croatian language file
+ *
+ * @author Branko Rihtman <theney@gmail.com>
+ * @author Dražen Odobašić <dodobasic@gmail.com>
+ * @author Dejan Igrec dejan.igrec@gmail.com
+ */
diff --git a/lib/plugins/plugin/lang/hu/admin_plugin.txt b/lib/plugins/plugin/lang/hu/admin_plugin.txt
new file mode 100644
index 000000000..afa08d349
--- /dev/null
+++ b/lib/plugins/plugin/lang/hu/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== Bővítménykezelő ======
+
+Ezen az oldalon a Dokuwiki [[doku>plugins|bővítményeivel]] kapcsolatos teendőket láthatod el. A webszervernek tudni kell írnia a //plugin// könyvtárat, hogy új bővítményeket tudj ezen a felületen keresztül letölteni és telepíteni.
+
diff --git a/lib/plugins/plugin/lang/hu/lang.php b/lib/plugins/plugin/lang/hu/lang.php
new file mode 100644
index 000000000..34309a53f
--- /dev/null
+++ b/lib/plugins/plugin/lang/hu/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Hungarian language file
+ *
+ * @author Sandor TIHANYI <stihanyi+dw@gmail.com>
+ * @author Siaynoq Mage <siaynoqmage@gmail.com>
+ * @author schilling.janos@gmail.com
+ * @author Szabó Dávid <szabo.david@gyumolcstarhely.hu>
+ * @author Sándor TIHANYI <stihanyi+dw@gmail.com>
+ * @author David Szabo <szabo.david@gyumolcstarhely.hu>
+ */
+$lang['menu'] = 'Bővítménykezelő';
+$lang['download'] = 'Új bővítmény letöltése és telepítése';
+$lang['manage'] = 'Telepített bővítmények';
+$lang['btn_info'] = 'infó';
+$lang['btn_update'] = 'frissítés';
+$lang['btn_delete'] = 'törlés';
+$lang['btn_settings'] = 'beállítások';
+$lang['btn_download'] = 'Letöltés';
+$lang['btn_enable'] = 'Mentés';
+$lang['url'] = 'URL:';
+$lang['installed'] = 'Telepítve:';
+$lang['lastupdate'] = 'Utolsó frissítés:';
+$lang['source'] = 'Forrás:';
+$lang['unknown'] = 'ismeretlen';
+$lang['updating'] = 'Frissítés...';
+$lang['updated'] = 'A %s bővítmény sikeresen frissült.';
+$lang['updates'] = 'A következő bővítmények sikeresen frissültek:';
+$lang['update_none'] = 'Nem találtam újabb verziót.';
+$lang['deleting'] = 'Törlés...';
+$lang['deleted'] = 'A %s bővítményt eltávolítottam.';
+$lang['downloading'] = 'Letöltés...';
+$lang['downloaded'] = 'A %s bővítmény sikeresen feltelepült.';
+$lang['downloads'] = 'A következő bővítmények sikeresen feltelepültek:';
+$lang['download_none'] = 'Nem találtam bővítményt, vagy ismeretlen hiba történt a letöltés/telepítés közben.';
+$lang['plugin'] = 'Bővítmény:';
+$lang['components'] = 'Részek';
+$lang['noinfo'] = 'Ez a bővítmény nem tartalmaz infót, lehet, hogy hibás.';
+$lang['name'] = 'Név:';
+$lang['date'] = 'Dátum:';
+$lang['type'] = 'Típus:';
+$lang['desc'] = 'Leírás:';
+$lang['author'] = 'Szerző:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Ismeretlen hiba lépett fel.';
+$lang['error_download'] = 'Nem tudom letölteni a bővítmény fájlt: %s';
+$lang['error_badurl'] = 'Feltehetően rossz URL - nem tudom meghatározni a fájlnevet az URL-ből.';
+$lang['error_dircreate'] = 'Nem tudom létrehozni az átmeneti könyvtárat a letöltéshez.';
+$lang['error_decompress'] = 'A Bővítménykezelő nem tudta a letöltött állományt kicsomagolni. Ennek oka lehet hibás letöltés, ebben az esetben újra letöltéssel próbálkozhatsz, esetleg a tömörítés módja ismeretlen, ebben az esetben kézzel kell letölteni és telepíteni a bővítményt.';
+$lang['error_copy'] = 'Fájl másolási hiba történt a(z) <em>%s</em> bővítmény telepítése közben: vagy a lemezterület fogyott el, vagy az állomány hozzáférési jogosultságok nem megfelelőek. Emiatt előfordulhat, hogy a bővítményt csak részben sikerült telepíteni, és a wiki összeomolhat.';
+$lang['error_delete'] = 'Hiba történt a(z) <em>%s</em> bővítmény eltávolítása közben. A legvalószínűbb ok, hogy a könyvtár vagy állomány hozzáférési jogosultságok nem megfelelőek.';
+$lang['enabled'] = 'A(z) %s bővítmény bekapcsolva.';
+$lang['notenabled'] = 'A(z) %s bővítmény engedélyezése nem sikerült. Ellenőrizze a fájl-hozzáférési engedélyeket.';
+$lang['disabled'] = 'A(z) %s bővítmény kikapcsolva.';
+$lang['notdisabled'] = 'A(z) %s bővítmény kikapcsolása nem sikerült. Ellenőrizze a fájl-hozzáférési engedélyeket.';
+$lang['packageinstalled'] = 'A bővítmény csomag(ok) feltelepült(ek): %d plugin(s): %s';
diff --git a/lib/plugins/plugin/lang/ia/admin_plugin.txt b/lib/plugins/plugin/lang/ia/admin_plugin.txt
new file mode 100644
index 000000000..c7f758c16
--- /dev/null
+++ b/lib/plugins/plugin/lang/ia/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Gestion de plug-ins ======
+
+In iste pagina tu pote gerer omne cosas con relation al [[doku>plugins|plug-ins]] de DokuWiki. Pro poter discargar e installar un plug-in, le directorio de plug-ins debe permitter le accesso de scriptura al servitor web. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/ia/lang.php b/lib/plugins/plugin/lang/ia/lang.php
new file mode 100644
index 000000000..523f8581d
--- /dev/null
+++ b/lib/plugins/plugin/lang/ia/lang.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Interlingua language file
+ *
+ * @author robocap <robocap1@gmail.com>
+ * @author Martijn Dekker <martijn@inlv.org>
+ */
+$lang['menu'] = 'Gestion de plug-ins';
+$lang['download'] = 'Discargar e installar un nove plug-in';
+$lang['manage'] = 'Plug-ins installate';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'actualisar';
+$lang['btn_delete'] = 'deler';
+$lang['btn_settings'] = 'configurationes';
+$lang['btn_download'] = 'Discargar';
+$lang['btn_enable'] = 'Salveguardar';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Installate:';
+$lang['lastupdate'] = 'Ultime actualisation:';
+$lang['source'] = 'Origine:';
+$lang['unknown'] = 'incognite';
+$lang['updating'] = 'Actualisation…';
+$lang['updated'] = 'Actualisation del plug-in %s succedite';
+$lang['updates'] = 'Le sequente plug-ins ha essite actualisate con successo';
+$lang['update_none'] = 'Nulle actualisation trovate.';
+$lang['deleting'] = 'Deletion…';
+$lang['deleted'] = 'Le plug-in %s ha essite delite.';
+$lang['downloading'] = 'Discargamento…';
+$lang['downloaded'] = 'Installation del plug-in %s succedite.';
+$lang['downloads'] = 'Le sequente plug-ins ha essite installate con successo:';
+$lang['download_none'] = 'Nulle plug-in trovate, o il ha occurrite un problema incognite durante le discargamento e installation.';
+$lang['plugin'] = 'Plug-in:';
+$lang['components'] = 'Componentes';
+$lang['noinfo'] = 'Iste plug-in retornava nulle information; illo pote esser invalide.';
+$lang['name'] = 'Nomine:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Typo:';
+$lang['desc'] = 'Description:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Un error incognite ha occurrite.';
+$lang['error_download'] = 'Impossibile discargar le file del plug-in: %s';
+$lang['error_badurl'] = 'URL probabilemente invalide; impossibile determinar le nomine del file ex le URL';
+$lang['error_dircreate'] = 'Impossibile crear le dossier temporari pro reciper le discargamento';
+$lang['error_decompress'] = 'Le gestor de plug-ins non poteva decomprimer le file discargate. Isto pote esser le resultato de un discargamento defectuose, in le qual caso tu deberea probar lo de novo; o le formato de compression pote esser incognite, in le qual caso tu debe discargar e installar le plug-in manualmente.';
+$lang['error_copy'] = 'Il occurreva un error durante le tentativa de installar files pro le plugin <em>%s</em>: le disco pote esser plen o le permissiones de accesso a files pote esser incorrecte. Isto pote haber resultate in un plug-in partialmente installate e lassar tu installation del wiki instabile.';
+$lang['error_delete'] = 'Il occurreva un error durante le tentativa de deler le plug-in <em>%s</em>. Le causa le plus probabile es insufficiente permissiones de files o directorios.';
+$lang['enabled'] = 'Plug-in %s activate.';
+$lang['notenabled'] = 'Le plug-in %s non poteva esser activate; verifica le permissiones de accesso a files.';
+$lang['disabled'] = 'Plug-in %s disactivate.';
+$lang['notdisabled'] = 'Le plug-in %s non poteva esser disactivate; verifica le permissiones de accesso a files.';
diff --git a/lib/plugins/plugin/lang/id-ni/lang.php b/lib/plugins/plugin/lang/id-ni/lang.php
new file mode 100644
index 000000000..d367340b7
--- /dev/null
+++ b/lib/plugins/plugin/lang/id-ni/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * idni language file
+ *
+ * @author Harefa <fidelis@harefa.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/plugin/lang/id/lang.php b/lib/plugins/plugin/lang/id/lang.php
new file mode 100644
index 000000000..f3a1fe4e6
--- /dev/null
+++ b/lib/plugins/plugin/lang/id/lang.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Indonesian language file
+ *
+ * @author Irwan Butar Butar <irwansah.putra@gmail.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
+$lang['btn_info'] = 'Info';
+$lang['btn_update'] = 'Baharui';
+$lang['btn_delete'] = 'Hapus';
+$lang['btn_settings'] = 'Pengaturan';
+$lang['btn_download'] = 'Unduh';
+$lang['btn_enable'] = 'Simpan';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instal';
+$lang['lastupdate'] = 'Pembaharuan terakhir:';
+$lang['source'] = 'Sumber:';
+$lang['unknown'] = 'Tidak kenal';
+$lang['updating'] = 'Terbaharui ...';
+$lang['update_none'] = 'Tidak ditemukan pembaharuan';
+$lang['deleting'] = 'Terhapus ...';
+$lang['deleted'] = 'Hapus Plugin %s.';
+$lang['downloading'] = 'Unduh ...';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Komponen';
+$lang['name'] = 'Nama:';
+$lang['date'] = 'Tanggal:';
+$lang['type'] = 'Tipe:';
+$lang['desc'] = 'Penjelasan:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
diff --git a/lib/plugins/plugin/lang/is/lang.php b/lib/plugins/plugin/lang/is/lang.php
new file mode 100644
index 000000000..0ef1243ef
--- /dev/null
+++ b/lib/plugins/plugin/lang/is/lang.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Icelandic language file
+ *
+ * @author Hrannar Baldursson <hrannar.baldursson@gmail.com>
+ * @author Ólafur Gunnlaugsson <oli@audiotools.com>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ */
+$lang['menu'] = 'Umsýsla viðbóta';
+$lang['download'] = 'Hlaða niður og innsetja viðbót';
+$lang['manage'] = 'Uppsettar viðbætur';
+$lang['btn_info'] = 'upplýsingar';
+$lang['btn_update'] = 'uppfæra';
+$lang['btn_delete'] = 'eyða';
+$lang['btn_settings'] = 'stillingar';
+$lang['btn_download'] = 'Niðurhal';
+$lang['btn_enable'] = 'Vista';
+$lang['url'] = 'Veffang';
+$lang['installed'] = 'Innsett:';
+$lang['lastupdate'] = 'Síðast uppfærð:';
+$lang['source'] = 'Gjafi:';
+$lang['unknown'] = 'óþekkt';
+$lang['updating'] = 'Uppfæri viðbót';
+$lang['updated'] = '%s viðbótin hefur verið uppfærð';
+$lang['updates'] = 'Eftirfarandi viðbætur hafa verið uppfærðar';
+$lang['update_none'] = 'Engar uppfærslur fundust.';
+$lang['deleting'] = 'Eyði viðbót';
+$lang['deleted'] = 'Viðbót %s eytt';
+$lang['downloading'] = 'Hleð viðbót niður ...';
+$lang['downloaded'] = 'Viðbót %s hlóðst inn';
+$lang['downloads'] = 'Eftirfarandi viðbótum hefur verið hlaðið inn:';
+$lang['download_none'] = 'Engin viðbót finnst, hugsanlega hefur komið upp villa við niðurhal eða uppsetningu.';
+$lang['plugin'] = 'Viðbót:';
+$lang['components'] = 'Einingar';
+$lang['noinfo'] = 'Þessi viðbót skilaði ekki upplýsingum og er hugsanlega ónýt.';
+$lang['name'] = 'Nafn:';
+$lang['date'] = 'Dagsetning:';
+$lang['type'] = 'Tegund:';
+$lang['desc'] = 'Lýsing:';
+$lang['author'] = 'Höfundur:';
+$lang['www'] = 'Vefur:';
+$lang['error'] = 'Óskilgreind villa';
+$lang['error_download'] = 'Niðurhal viðbótar %s mistókst';
+$lang['error_decompress'] = 'Viðbótastjórinn gat ekki afþjappað skránna. Þetta gæti verið vegna misheppnaðs niðurhals, ef svo er reyndu niðurhal aftur. Það er einnig mögulegt að skráin sé þjöppuð með aðferð sem að er Dokuwiki óþekkt, í því tilfelli er best að vista viðhengið á tölvunni þinni, afþjappa hana þar og svo hlaða skránum upp handvirkt.';
+$lang['enabled'] = 'Viðbót %s hefur verið ræst.';
+$lang['notenabled'] = 'Ekki var hægt að ræsa %s viðbótina. Athugaðu stillingar á skráaleyfum.';
+$lang['disabled'] = 'Viðbót %s var gerð óvirk';
diff --git a/lib/plugins/plugin/lang/it/admin_plugin.txt b/lib/plugins/plugin/lang/it/admin_plugin.txt
new file mode 100644
index 000000000..5591f08fe
--- /dev/null
+++ b/lib/plugins/plugin/lang/it/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Gestione Plugin ======
+
+In questa pagina puoi gestire tutto ciò che riguarda i [[doku>plugins|plugin]] di DokuWiki. Per poter scaricare e installare un plugin, il webserver deve avere accesso in scrittura alla directory dei plugin. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/it/lang.php b/lib/plugins/plugin/lang/it/lang.php
new file mode 100644
index 000000000..e675c5530
--- /dev/null
+++ b/lib/plugins/plugin/lang/it/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Italian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Silvia Sargentoni <polinnia@tin.it>
+ * @author Pietro Battiston toobaz@email.it
+ * @author Diego Pierotto ita.translations@tiscali.it
+ * @author ita.translations@tiscali.it
+ * @author Lorenzo Breda <lbreda@gmail.com>
+ * @author snarchio@alice.it
+ * @author robocap <robocap1@gmail.com>
+ * @author Osman Tekin osman.tekin93@hotmail.it
+ * @author Jacopo Corbetta <jacopo.corbetta@gmail.com>
+ */
+$lang['menu'] = 'Gestione Plugin';
+$lang['download'] = 'Scarica e installa un nuovo plugin';
+$lang['manage'] = 'Plugin installati';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'aggiorna';
+$lang['btn_delete'] = 'elimina';
+$lang['btn_settings'] = 'configurazione';
+$lang['btn_download'] = 'Scarica';
+$lang['btn_enable'] = 'Salva';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Installato:';
+$lang['lastupdate'] = 'Ultimo aggiornamento:';
+$lang['source'] = 'Origine:';
+$lang['unknown'] = 'sconosciuto';
+$lang['updating'] = 'Aggiornamento in corso ...';
+$lang['updated'] = 'Aggiornamento plugin %s riuscito';
+$lang['updates'] = 'Aggiornamento dei seguenti plugin riuscito:';
+$lang['update_none'] = 'Nessun aggiornamento trovato.';
+$lang['deleting'] = 'Eliminazione in corso ...';
+$lang['deleted'] = 'Plugin %s eliminato.';
+$lang['downloading'] = 'Scaricamento in corso ...';
+$lang['downloaded'] = 'Installazione plugin %s riuscita';
+$lang['downloads'] = 'Installazione dei seguenti plugin riuscita:';
+$lang['download_none'] = 'Nessun plugin trovato, oppure si è verificato un problema sconosciuto durante il download e l\'installazione.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Componenti';
+$lang['noinfo'] = 'Questo plugin non ha fornito alcuna informazione, potrebbe non essere valido.';
+$lang['name'] = 'Nome:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipo:';
+$lang['desc'] = 'Descrizione:';
+$lang['author'] = 'Autore:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Si è verificato un errore sconosciuto.';
+$lang['error_download'] = 'Impossibile scaricare il plugin: %s';
+$lang['error_badurl'] = 'Possibile URL non corretta - impossibile determinare il nome del file dalla URL fornita';
+$lang['error_dircreate'] = 'Impossibile creare la directory temporanea dove scaricare il file';
+$lang['error_decompress'] = 'Impossibile decomprimere il file scaricato. Questo potrebbe essere il risultato di un download incompleto, in tal caso dovresti provare di nuovo; oppure il formato di compressione potrebbe essere sconosciuto, in questo caso è necessario scaricare e installare il plugin manualmente.';
+$lang['error_copy'] = 'Si è verificato un errore nella copia di un file durante l\'installazione del plugin <em>%s</em>: il disco potrebbe essere pieno oppure i permessi di accesso al file potrebbero non essere corretti. Il plugin potrebbe essere stato installato solo parzialmente, questo potrebbe causare instabilità al sistema.';
+$lang['error_delete'] = 'Si è verificato un errore durante l\'eliminazione del plugin <em>%s</em>. Molto probabilmente i permessi di acesso ai file o alla directory non sono sufficienti';
+$lang['enabled'] = 'Plugin %s abilitato.';
+$lang['notenabled'] = 'Impossibile abilitare il plugin %s, verifica i permessi dei file.';
+$lang['disabled'] = 'Plugin %s disabilitato.';
+$lang['notdisabled'] = 'Impossibile disabilitare il plugin %s, verifica i permessi dei file.';
diff --git a/lib/plugins/plugin/lang/ja/admin_plugin.txt b/lib/plugins/plugin/lang/ja/admin_plugin.txt
new file mode 100644
index 000000000..c3b85351a
--- /dev/null
+++ b/lib/plugins/plugin/lang/ja/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== プラグイン管理 ======
+
+この画面で、DokuWikiで使用するプラグイン [[doku>plugins|plugins]] の管理を行うことが出来ます。 プラグインをダウンロード・インストールするためには、サーバー内のプラグイン用フォルダーを 書き込み可にしておく必要があります。
+
+
diff --git a/lib/plugins/plugin/lang/ja/lang.php b/lib/plugins/plugin/lang/ja/lang.php
new file mode 100644
index 000000000..a96dcc9be
--- /dev/null
+++ b/lib/plugins/plugin/lang/ja/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * japanese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Yuji Takenaka <webmaster@davilin.com>
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Ikuo Obataya <i.obataya@gmail.com>
+ * @author Daniel Dupriest <kououken@gmail.com>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ */
+$lang['menu'] = 'プラグイン管理';
+$lang['download'] = 'プラグインのダウンロードとインストール';
+$lang['manage'] = 'インストール済みプラグイン';
+$lang['btn_info'] = '情報';
+$lang['btn_update'] = '更新';
+$lang['btn_delete'] = '削除';
+$lang['btn_settings'] = '設定';
+$lang['btn_download'] = 'ダウンロード';
+$lang['btn_enable'] = '保存';
+$lang['url'] = 'URL';
+$lang['installed'] = 'インストール:';
+$lang['lastupdate'] = '最終更新日:';
+$lang['source'] = 'ソース:';
+$lang['unknown'] = '不明';
+$lang['updating'] = '更新中...';
+$lang['updated'] = 'プラグイン %s は更新されました';
+$lang['updates'] = '次のプラグインが更新されました:';
+$lang['update_none'] = 'プラグインの更新データはありません。';
+$lang['deleting'] = '削除中...';
+$lang['deleted'] = 'プラグイン %s は削除されました。';
+$lang['downloading'] = 'ダウンロード中...';
+$lang['downloaded'] = 'プラグイン %s がインストールされました';
+$lang['downloads'] = '次のプラグインがインストールされました:';
+$lang['download_none'] = 'プラグインが見つかりませんでした。もしくはダウンロードかインストールの最中に予期せぬエラーが発生しました。';
+$lang['plugin'] = 'プラグイン:';
+$lang['components'] = 'コンポーネント';
+$lang['noinfo'] = 'このプラグインに関する情報がありません。有効なプラグインではないかも知れません。';
+$lang['name'] = '名前:';
+$lang['date'] = '日付:';
+$lang['type'] = 'タイプ:';
+$lang['desc'] = '説明:';
+$lang['author'] = '作者:';
+$lang['www'] = 'ウェブサイト:';
+$lang['error'] = '予期せぬエラーが発生しました。';
+$lang['error_download'] = 'プラグインファイルをダウンロードできません:%s';
+$lang['error_badurl'] = 'URLが正しくないようです - ファイル名が特定できません';
+$lang['error_dircreate'] = 'ダウンロードしたファイルを一時的に保管しておくフォルダが作成できません';
+$lang['error_decompress'] = 'ダウンロードしたファイルを解凍できませんでした。ダウンロードに失敗した可能性があります(もう一度、実行してください);もしくは、不明な圧縮形式であるかもしれません(手動でインストールする必要があります)';
+$lang['error_copy'] = 'プラグインをインストール中にファイルのコピーに失敗しました。<em>%s</em>:ディスク容量や書き込みの権限を確認してください。このエラーによりプラグインのインストールが完全に行われず、Wikiが不安定な状態です。';
+$lang['error_delete'] = 'プラグインの削除中にエラーが発生しました <em>%s</em>。プラグインが不完全なファイルであったか、ディレクトリの権限が正しくないことが原因であると考えられます。';
+$lang['enabled'] = 'プラグイン %s が有効です。';
+$lang['notenabled'] = 'プラグイン %s を有効にすることができません。権限を確認してください。';
+$lang['disabled'] = 'プラグイン %s が無効です。';
+$lang['notdisabled'] = 'プラグイン %s を無効にすることができません。権限を確認してください。';
+$lang['packageinstalled'] = 'プラグインパッケージ(%d plugin(s): %s)は正しくインストールされました。';
diff --git a/lib/plugins/plugin/lang/kk/lang.php b/lib/plugins/plugin/lang/kk/lang.php
new file mode 100644
index 000000000..dde5b9577
--- /dev/null
+++ b/lib/plugins/plugin/lang/kk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * kazakh language file
+ *
+ * @author Nurgozha Kaliaskarov astana08@gmail.com
+ */
diff --git a/lib/plugins/plugin/lang/ko/admin_plugin.txt b/lib/plugins/plugin/lang/ko/admin_plugin.txt
new file mode 100644
index 000000000..22ce0e6e6
--- /dev/null
+++ b/lib/plugins/plugin/lang/ko/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== 플러그인 관리 ======
+
+이 페이지에서 Dokuwiki[[doku>plugins|plugins]]에 관련된 모든 관리 작업을 합니다. 플러그인을 다운로드하거나 설치하기 위해서 웹서버가 플러그인 디렉토리에 대해 쓰기 권한을 가지고 있어야 합니다.
+
+
diff --git a/lib/plugins/plugin/lang/ko/lang.php b/lib/plugins/plugin/lang/ko/lang.php
new file mode 100644
index 000000000..c77c3259d
--- /dev/null
+++ b/lib/plugins/plugin/lang/ko/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * korean language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author jk Lee
+ * @author dongnak@gmail.com
+ * @author Song Younghwan <purluno@gmail.com>
+ * @author SONG Younghwan <purluno@gmail.com>
+ * @author Seung-Chul Yoo <dryoo@live.com>
+ */
+$lang['menu'] = '플러그인 관리자';
+$lang['download'] = '새로운 플러그인 다운로드 및 설치';
+$lang['manage'] = '이미 설치된 플러그인들';
+$lang['btn_info'] = '정보';
+$lang['btn_update'] = '갱신';
+$lang['btn_delete'] = '삭제';
+$lang['btn_settings'] = '설정';
+$lang['btn_download'] = '다운로드';
+$lang['btn_enable'] = '저장';
+$lang['url'] = 'URL';
+$lang['installed'] = '설치된:';
+$lang['lastupdate'] = '가장 최근에 갱신된:';
+$lang['source'] = '소스:';
+$lang['unknown'] = '알 수 없는';
+$lang['updating'] = '갱신 중 ...';
+$lang['updated'] = '%s 플러그인이 성공적으로 갱신되었습니다.';
+$lang['updates'] = '다음 플러그인들이 성공적으로 갱신되었습니다:';
+$lang['update_none'] = '갱신 가능한 플러그인이 없습니다.';
+$lang['deleting'] = '삭제 중 ...';
+$lang['deleted'] = '%s 플러그인이 삭제되었습니다.';
+$lang['downloading'] = '다운로드 중 ...';
+$lang['downloaded'] = '%s 플러그인이 성공적으로 설치되었습니다.';
+$lang['downloads'] = '다음 플러그인들이 성공적으로 설치되었습니다:';
+$lang['download_none'] = '플러그인이 없거나 다운로드/설치 중에 알수 없는 문제가 발생했습니다.';
+$lang['plugin'] = '플러그인:';
+$lang['components'] = '콤퍼넌트들';
+$lang['noinfo'] = '이 플러그인은 어떤 정보도 없습니다. 유효한 플러그인이 아닐 지도 모릅니다.';
+$lang['name'] = '이름:';
+$lang['date'] = '날짜:';
+$lang['type'] = '타입:';
+$lang['desc'] = '설명:';
+$lang['author'] = '제작자:';
+$lang['www'] = '웹:';
+$lang['error'] = '알 수 없는 문제가 발생했습니다.';
+$lang['error_download'] = '플러그인 파일을 다운로드 할 수 없습니다: %s';
+$lang['error_badurl'] = '잘못된 URL같습니다. - URL에서 파일 이름을 알 수 없습니다.';
+$lang['error_dircreate'] = '다운로드를 받기 위한 임시 디렉토리를 만들 수 없습니다.';
+$lang['error_decompress'] = '플러그인 매니저가 다운로드 받은 파일을 압축해제할 수 없습니다.잘못 다운로드 받았을 수도 있으니 다시 한번 시도해보기 바랍니다; 압축 포맷을 알 수 없는 경우에는 다운로드 후 수동으로 직접 설치하기 바랍니다.';
+$lang['error_copy'] = '플러그인 설치하는 동안 파일 복사 에러가 발생했습니다. <em>%s</em>: 디스크가 꽉 찼거나 파일 접근 권한이 잘못된 경우입니다. 플러그인 설치가 부분적으로만 이루어졌을 것입니다.설치가 불완전합니다.';
+$lang['error_delete'] = '<em>%s</em> 플러그인 삭제 도중 에러가 발생했습니다. 대부분의 경우, 불완전한 파일이거나 디렉토리 접근 권한이 잘못된 경우입니다.';
+$lang['enabled'] = '%s 플러그인을 켰습니다.';
+$lang['notenabled'] = '%s 플러그인을 킬 수 없습니다. 파일 권한을 확인하십시오.';
+$lang['disabled'] = '%s 플러그인을 껐습니다.';
+$lang['notdisabled'] = '%s 플러그인을 끌 수 없습니다. 파일 권한을 확인하십시오.';
+$lang['packageinstalled'] = '플러그인 패키지(%d 개의 플러그인: %s)가 성공적으로 설치되었습니다.';
diff --git a/lib/plugins/plugin/lang/la/admin_plugin.txt b/lib/plugins/plugin/lang/la/admin_plugin.txt
new file mode 100644
index 000000000..2a41977fc
--- /dev/null
+++ b/lib/plugins/plugin/lang/la/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Addendorum Administratio ======
+
+In hac pagina omnia uicis [[doku>plugins|plugins]] mutare et administrare potes. Vt addenda capere et his uti, in scrinio addendorum scribere et legere potest. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/la/lang.php b/lib/plugins/plugin/lang/la/lang.php
new file mode 100644
index 000000000..cd2d81cbd
--- /dev/null
+++ b/lib/plugins/plugin/lang/la/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Latin language file
+ *
+ * @author Massimiliano Vassalli <vassalli.max@gmail.com>
+ */
+$lang['menu'] = 'Addendorum administratio';
+$lang['download'] = 'Noua addenda cape';
+$lang['manage'] = 'Addenta in usu';
+$lang['btn_info'] = 'Notae';
+$lang['btn_update'] = 'Nouare';
+$lang['btn_delete'] = 'Delere';
+$lang['btn_settings'] = 'Optiones';
+$lang['btn_download'] = 'Capere';
+$lang['btn_enable'] = 'Seruare';
+$lang['url'] = 'VRL';
+$lang['installed'] = 'In usu:';
+$lang['lastupdate'] = 'Extrema renouatio:';
+$lang['source'] = 'Fons:';
+$lang['unknown'] = 'Ignotum';
+$lang['updating'] = 'Nouans...';
+$lang['updated'] = 'Addenda %s nouata feliciter';
+$lang['updates'] = 'Hae addenda nouata feliciter sunt';
+$lang['update_none'] = 'Nulla renouatio inuenta';
+$lang['deleting'] = 'Delens...';
+$lang['deleted'] = 'Addenda %s deleta.';
+$lang['downloading'] = 'Capens ...';
+$lang['downloaded'] = 'Addenda %s recte in usu';
+$lang['downloads'] = 'Hae addenda feliciter in usu:';
+$lang['download_none'] = 'Nulla addenda reperta aut errores in capiendo sunt.';
+$lang['plugin'] = 'Addenda:';
+$lang['components'] = 'Partes';
+$lang['noinfo'] = 'Addenda alias notas non habent.';
+$lang['name'] = 'Nomen:';
+$lang['date'] = 'Dies:';
+$lang['type'] = 'Genus:';
+$lang['desc'] = 'Descriptio:';
+$lang['author'] = 'Auctor:';
+$lang['www'] = 'Situs interretialis:';
+$lang['error'] = 'Error ignotus.';
+$lang['error_download'] = 'Addenda quae non renouantur: %s';
+$lang['error_badurl'] = 'VRL malum';
+$lang['error_dircreate'] = 'Scrinium temporaneum non creatur, sic nihil capi potest';
+$lang['error_decompress'] = 'Addendorum administrator nouare non potest. Rursum capere nouationes temptat aut manu addenda noua.';
+$lang['error_copy'] = 'Exemplar malum in scrinio addendorum <em>%s</em> est: facultates documenti scrinique fortasse illegitimae sunt. Hic accidit cum addenda partim nouata sunt.';
+$lang['error_delete'] = 'Addenda <em>%s</em> non delentur.';
+$lang['enabled'] = 'Addenda %s apta facta.';
+$lang['notenabled'] = 'Addenda %s quae apta fieri non possunt.';
+$lang['disabled'] = 'Addenda %s non in usu.';
+$lang['notdisabled'] = 'Addenda %s quae inepta fieri non possunt.';
diff --git a/lib/plugins/plugin/lang/lb/admin_plugin.txt b/lib/plugins/plugin/lang/lb/admin_plugin.txt
new file mode 100644
index 000000000..223de10e8
--- /dev/null
+++ b/lib/plugins/plugin/lang/lb/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== Plugin Management ======
+
+Op dëser Säit kanns de alles verwalte wat mat Dokuwiki [[doku>plugins|Pluginen]] ze dinn huet. Fir e Plugin kënnen z'installéieren, muss däi Pluginverzeechnës vum Webserver schreiwbar sinn.
+
diff --git a/lib/plugins/plugin/lang/lb/lang.php b/lib/plugins/plugin/lang/lb/lang.php
new file mode 100644
index 000000000..59acdf7a8
--- /dev/null
+++ b/lib/plugins/plugin/lang/lb/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * lb language file
+ *
+ * @author joel@schintgen.net
+ */
diff --git a/lib/plugins/plugin/lang/lt/admin_plugin.txt b/lib/plugins/plugin/lang/lt/admin_plugin.txt
new file mode 100644
index 000000000..1254b776c
--- /dev/null
+++ b/lib/plugins/plugin/lang/lt/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Priedų Administravimas ======
+
+Šiame puslapyje galite administruoti, darbui su Dokuwiki, reikalingu įrankius [[doku>plugins|plugins]]. Tam kad parsiųsti ir įdiegti kokį nors priedą jūsų web serveris privalo turėti įrašymo teises priedų kataloge.
diff --git a/lib/plugins/plugin/lang/lt/lang.php b/lib/plugins/plugin/lang/lt/lang.php
new file mode 100644
index 000000000..c5b2fa11e
--- /dev/null
+++ b/lib/plugins/plugin/lang/lt/lang.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Lithuanian language file
+ *
+ * @author audrius.klevas@gmail.com
+ * @author Arunas Vaitekunas <aras@fan.lt>
+ */
+$lang['name'] = 'Vardas:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipas:';
+$lang['desc'] = 'Aprašas:';
+$lang['author'] = 'Autorius:';
+$lang['www'] = 'Tinklapis:';
diff --git a/lib/plugins/plugin/lang/lv/admin_plugin.txt b/lib/plugins/plugin/lang/lv/admin_plugin.txt
new file mode 100644
index 000000000..80335062f
--- /dev/null
+++ b/lib/plugins/plugin/lang/lv/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Moduļu pārvaldīšana ======
+
+Šajā lapā varat pārvaldīt visu, kas saistīts ar Dokuwiki [[doku>plugins|moduļiem]]. Lai varētu lejupielādēt un uzstādīt moduļus, to direktorijai serverī vajag rakstīšanas tiesības.
diff --git a/lib/plugins/plugin/lang/lv/lang.php b/lib/plugins/plugin/lang/lv/lang.php
new file mode 100644
index 000000000..0f6103899
--- /dev/null
+++ b/lib/plugins/plugin/lang/lv/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Latvian, Lettish language file
+ *
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['menu'] = 'Moduļu pārvaldība';
+$lang['download'] = 'Lejupielādēt un instalēt jaunu moduli.';
+$lang['manage'] = 'Instalētie moduļi';
+$lang['btn_info'] = 'uzziņa';
+$lang['btn_update'] = 'atjaunināt';
+$lang['btn_delete'] = 'dzēst';
+$lang['btn_settings'] = 'parametri';
+$lang['btn_download'] = 'Lejupielādēt';
+$lang['btn_enable'] = 'Saglabāt';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalēts:';
+$lang['lastupdate'] = 'Atjaunināts:';
+$lang['source'] = 'Avots:';
+$lang['unknown'] = 'nav zināms';
+$lang['updating'] = 'Atjauninu...';
+$lang['updated'] = 'Modulis %s veiksmīgi atjaunināts';
+$lang['updates'] = 'Veiksmīgi atjaunināti moduļi:';
+$lang['update_none'] = 'Jauninājums nav atrasts';
+$lang['deleting'] = 'Dzēšu...';
+$lang['deleted'] = 'Modulis %s dzēsts';
+$lang['downloading'] = 'Lejupielādēju...';
+$lang['downloaded'] = 'Modulis %s veiksmīgi instalēts';
+$lang['downloads'] = 'Veiksmīgi instalēti moduļi: ';
+$lang['download_none'] = 'Neviens modulis nav atrasts vai arī gadījusies nezinām kļūme lejupielādes un instalācijas gaitā.';
+$lang['plugin'] = 'Modulis:';
+$lang['components'] = 'Sastāvdaļas';
+$lang['noinfo'] = 'Modulis nesniedz informāciju, tas varbūt ir bojāts.';
+$lang['name'] = 'Nosaukums:';
+$lang['date'] = 'Datums:';
+$lang['type'] = 'Tips:';
+$lang['desc'] = 'Apraksts:';
+$lang['author'] = 'Autors:';
+$lang['www'] = 'Mājaslapa:';
+$lang['error'] = 'Gadījās nezināma kļūme.';
+$lang['error_download'] = 'Nevar lejupielādēt moduļa failu %s';
+$lang['error_badurl'] = 'Aizdomas par aplamu URL - jo no tā nevar noteikt faila vārdu.';
+$lang['error_dircreate'] = 'Nevar izveidot pagaidu direktoriju, kur saglabāt lejupielādēto. ';
+$lang['error_decompress'] = 'Moduļu pārvaldnieks nevar atspiest lejupielādēto failu. Vai nu neizdevusi es lejupielāde, mēģiniet atkārtot, vai arī nezinām arhīva formāts un tad modulis jāielādē un jāinstalē tev pašam.';
+$lang['error_copy'] = 'Faila kopēšanas kļūda instalējot moduli<em>%s</em>: disks pārpildīts vai aplamas piekļuves tiesības. Rezultātā var iegūt daļēji instalētu moduli un nestabilu Wiki sistēmu.';
+$lang['error_delete'] = 'Kļūme dzēšot moduli <em>%s</em>. Ticamākais iemesls ir direktorijas pieejas tiesību trūkums. ';
+$lang['enabled'] = 'Modulis %s pieslēgts.';
+$lang['notenabled'] = 'Moduli %s nevar pieslēgt, pārbaudi failu tiesības.';
+$lang['disabled'] = 'Modulis %s atslēgts.';
+$lang['notdisabled'] = 'Moduli %s nevar atslēgt, pārbaudi failu tiesības.';
diff --git a/lib/plugins/plugin/lang/mk/lang.php b/lib/plugins/plugin/lang/mk/lang.php
new file mode 100644
index 000000000..747d61638
--- /dev/null
+++ b/lib/plugins/plugin/lang/mk/lang.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Macedonian language file
+ *
+ * @author Dimitar Talevski <dimi3.14@gmail.com>
+ */
+$lang['menu'] = 'Уреди ги приклучоците';
+$lang['download'] = 'Симни и инсталирај нов приклучок';
+$lang['manage'] = 'Инсталирани приклучоци';
+$lang['btn_info'] = 'информации';
+$lang['btn_update'] = 'ажурирај';
+$lang['btn_delete'] = 'избриши';
+$lang['btn_settings'] = 'поставувања';
+$lang['btn_download'] = 'Симни';
+$lang['btn_enable'] = 'Зачувај';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Инсталирани:';
+$lang['lastupdate'] = 'Последно ажурирани:';
+$lang['source'] = 'Извор:';
+$lang['unknown'] = 'непознат';
+$lang['updating'] = 'Ажурирам...';
+$lang['updated'] = 'Приклучокот %s е успешно ажуриран';
+$lang['updates'] = 'Следниве приклучоци се успешно ажурирани';
+$lang['update_none'] = 'Нема потребни ажурирања.';
+$lang['deleting'] = 'Бришам...';
+$lang['deleted'] = 'Приклучокот %s е избришан.';
+$lang['downloading'] = 'Симнувам...';
+$lang['downloaded'] = 'Приклучокот %s е успешно инсталиран';
+$lang['downloads'] = 'Следниве приклучоци се успешно инсталирани';
+$lang['download_none'] = 'Нема пронајдени приклучоци, или имаше непознат проблем при симнување и инсталирање.';
+$lang['plugin'] = 'Приклучок:';
+$lang['components'] = 'Компоненти';
+$lang['noinfo'] = 'Овој приклучок не врати информации, може да не е валиден.';
+$lang['name'] = 'Име:';
+$lang['date'] = 'Датум:';
+$lang['type'] = 'Тип:';
+$lang['desc'] = 'Опис:';
+$lang['author'] = 'Автор:';
+$lang['www'] = 'Веб:';
+$lang['error'] = 'Се појави непозната грешка.';
+$lang['error_download'] = 'Не сум во можност да ја симнам датотеката за приклучокот: %s';
+$lang['enabled'] = 'Приклучокот %s е овозможен.';
+$lang['disabled'] = 'Приклучокот %s е оневозможен.';
diff --git a/lib/plugins/plugin/lang/mr/admin_plugin.txt b/lib/plugins/plugin/lang/mr/admin_plugin.txt
new file mode 100644
index 000000000..a925a560f
--- /dev/null
+++ b/lib/plugins/plugin/lang/mr/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== प्लगिन व्यवस्थापन ======
+
+या पानावर तुम्ही डॉक्युविकि [[doku>plugins|प्लगिन]] च्या सर्व बाबींची व्यवस्था लावू शकता.
+प्लगिन डाउनलोड व इन्स्टॉल करण्यासाठी तुमच्या प्लगिन फोल्डरवर तुमच्या वेबसर्वरला लेखनाची परवानगी असली पाहिजे. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/mr/lang.php b/lib/plugins/plugin/lang/mr/lang.php
new file mode 100644
index 000000000..3f81739fa
--- /dev/null
+++ b/lib/plugins/plugin/lang/mr/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Marathi language file
+ *
+ * @author ghatothkach@hotmail.com
+ * @author Padmanabh Kulkarni <kulkarnipadmanabh@gmail.com>
+ * @author Padmanabh Kulkarni<kulkarnipadmanabh@gmail.com>
+ * @author shantanoo@gmail.com
+ */
+$lang['menu'] = 'प्लगिनची व्यवस्था लावा';
+$lang['download'] = 'नवीन प्लगिन डाउनलोड करून इन्स्टॉल करा';
+$lang['manage'] = 'इन्स्टॉल केलेले प्लगिन';
+$lang['btn_info'] = 'माहिती';
+$lang['btn_update'] = 'अद्ययावत';
+$lang['btn_delete'] = 'डिलीट';
+$lang['btn_settings'] = 'सेटिंग';
+$lang['btn_download'] = 'डाउनलोड';
+$lang['btn_enable'] = 'सुरक्षित';
+$lang['url'] = 'URL';
+$lang['installed'] = 'इन्स्टॉलची वेळ :';
+$lang['lastupdate'] = 'शेवटच्या बदलाची वेळ :';
+$lang['source'] = 'स्त्रोत :';
+$lang['unknown'] = 'अगम्य';
+$lang['updating'] = 'अद्ययावत करतोय ...';
+$lang['updated'] = 'प्लगिन %s यशास्विरित्य अद्ययावत केला.';
+$lang['updates'] = 'खालील प्लगिन यशस्वीरीत्या अद्ययावत झाले';
+$lang['update_none'] = 'काही बदल मिळाले नाहीत.';
+$lang['deleting'] = 'डिलीट करतोय ...';
+$lang['deleted'] = '%s प्लगिन डिलीट केला.';
+$lang['downloading'] = 'डाउनलोड करतोय ...';
+$lang['downloaded'] = '%s प्लगिन यशस्वीरीत्या इन्स्टॉल झाला.';
+$lang['downloads'] = 'खालील प्लगिन यशस्वीरीत्या इन्स्टॉल झाले : ';
+$lang['download_none'] = 'एकही प्लगिन मिळाला नाही, किंवा डाउनलोड आणि इन्स्टॉल मधे काही अज्ञात अडचण आली असावी.';
+$lang['plugin'] = 'प्लगिन : ';
+$lang['components'] = 'भाग : ';
+$lang['noinfo'] = 'या प्लगिनने काही माहिती दिली नाही. बहुधा हा अवैध असावा.';
+$lang['name'] = 'नाव :';
+$lang['date'] = 'दिनांक :';
+$lang['type'] = 'टाइप : ';
+$lang['desc'] = 'वर्णन : ';
+$lang['author'] = 'लेखक : ';
+$lang['www'] = 'वेब : ';
+$lang['error'] = 'अज्ञात अडचण आली.';
+$lang['error_download'] = 'डाउनलोड न झालेली प्लगिन फाइल : %s';
+$lang['error_badurl'] = 'बहुधा चुकीचे URL - URL वरून फाइलचे नाव ठरवता आले नाही.';
+$lang['error_dircreate'] = 'डाउनलोड साठवण्यासाठी तात्पुरता फोल्डर तयार करू शकलो नाही';
+$lang['error_decompress'] = 'प्लगिन व्यवस्थापक डाउनलोड केलेली फाइल विस्तारित करू शकला नाही. हे कदाचित डाउनलोड नीट न झाल्यामुळे असावं; असे असल्यास तुमची परत डाउनलोड करण्याचा प्रयत्न करू शकता; किंवा प्लगिन संक्षिप्त करण्यास वापरलेली पद्धत अनाकलनीय आहे; तसे असल्यास तुम्हाला स्वतः प्लगिन डाउनलोड व इन्स्टॉल करावा लागेल.';
+$lang['error_copy'] = '<em>%s</em> प्लगिनसाठी फाइल इन्स्टॉल करताना फाइल कॉपी करू शकलो नाही : डिस्क भरली असेल किंवा फाइल वरील परवानग्या बरोबर नसतील. यामुळे प्लगिन अर्धवट इन्स्टॉल जाला असण्याची व त्यामुळे तुमची विकी ख़राब होण्याची शक्यता आहे.';
+$lang['error_delete'] = '<em>%s</em> प्लगिन डिलीट करताना काही चूक झाली आहे. फाइल किंवा डिरेक्टरी वरील परवानग्या बरोबर नसणे हे याचं मुख्य कारण असू शकतं.';
+$lang['enabled'] = '%s प्लगइन चालू केला.';
+$lang['notenabled'] = '%s प्लगइन चालू करू शकलो नाही, फाइलच्या परवानग्या तपासा.';
+$lang['disabled'] = '%s प्लगइन बंद केला.';
+$lang['notdisabled'] = '%s प्लगइन बंद करू शकलो नाही, फाइलच्या परवानग्या तपासा.';
diff --git a/lib/plugins/plugin/lang/ms/lang.php b/lib/plugins/plugin/lang/ms/lang.php
new file mode 100644
index 000000000..77ad2a1c1
--- /dev/null
+++ b/lib/plugins/plugin/lang/ms/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Malay language file
+ *
+ * @author Markos
+ */
diff --git a/lib/plugins/plugin/lang/ne/lang.php b/lib/plugins/plugin/lang/ne/lang.php
new file mode 100644
index 000000000..27c4f3b60
--- /dev/null
+++ b/lib/plugins/plugin/lang/ne/lang.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Nepali language file
+ *
+ * @author Saroj Kumar Dhakal <lotusnagarkot@gmail.com>
+ * @author SarojKumar Dhakal <lotusnagarkot@yahoo.com>
+ * @author Saroj Dhakal<lotusnagarkot@yahoo.com>
+ */
+$lang['menu'] = 'प्लगिन व्यवस्थापन गर्नुहोस।';
+$lang['download'] = 'नयाँ प्लगिन डाउनलोड गरी स्थापना गर्नुहोस्';
+$lang['manage'] = 'स्थापित प्लगिनहरु';
+$lang['btn_info'] = 'जानकारी';
+$lang['btn_update'] = 'अध्यावधिक गर्नुहोस';
+$lang['btn_delete'] = 'मेटाउनुहोस्';
+$lang['btn_settings'] = 'व्यवस्थापन';
+$lang['btn_download'] = 'डाउनलोड गर्नुहोस्';
+$lang['btn_enable'] = 'वचत गर्नुहोस्';
+$lang['url'] = 'URL';
+$lang['installed'] = 'स्थापित';
+$lang['lastupdate'] = 'अन्तिम अध्यावधिक :';
+$lang['source'] = 'स्रोत:';
+$lang['unknown'] = 'थाह नभएको';
+$lang['updating'] = 'अध्यावधिक गर्दै......';
+$lang['updated'] = 'प्लगिन %s सफलतापूर्वक अध्यावधिक भयो ';
+$lang['updates'] = 'निम्न प्लगिनहरु सफलतापूर्वक अध्यावधिक भए।';
+$lang['update_none'] = 'कुनै पनि अध्यावधिकम भेटिएन ।';
+$lang['deleting'] = 'हटाउदै ......';
+$lang['deleted'] = 'प्लगिन %s हटाइयो ।';
+$lang['downloading'] = 'डाउनलोड गर्दै ........';
+$lang['downloaded'] = 'प्लगिन %s सफलतापूर्वक स्थापित भयो ';
+$lang['downloads'] = 'निम्न प्लगिनहरु सफलतापूर्वक स्थापित भए';
+$lang['download_none'] = 'कुनै पनि प्लगइन भेटिएन, या डाउनलोड गर्दा र स्थापना गर्दा त्रुटि भयो ।';
+$lang['plugin'] = 'प्लगिन:';
+$lang['components'] = 'पुर्जाहरु ';
+$lang['noinfo'] = 'यो प्लगइनले कुनै पनि जनाकारी दिएन , यो अमान्य हुनसक्छ ।';
+$lang['name'] = 'नाम:';
+$lang['date'] = 'मिति:';
+$lang['type'] = 'प्रकार :';
+$lang['desc'] = 'जानकारी:';
+$lang['author'] = 'जारीकर्ता:';
+$lang['www'] = 'वेब:';
+$lang['error'] = 'अज्ञात त्रुटि फेला पर्‌यो ।';
+$lang['error_download'] = 'प्लहइन फाइल: %s डाउनलोड गर्न असमर्थ ।';
+$lang['error_badurl'] = 'शंकास्पद खराब url - Url बाट फाइल नाम निश्चित गर्न असमर्थ ।';
+$lang['error_dircreate'] = 'डाउनलोड प्राप्त गर्नको निमि्त्त अस्थाइ फोल्डर निर्माण गर्न असमर्थ ।';
diff --git a/lib/plugins/plugin/lang/nl/admin_plugin.txt b/lib/plugins/plugin/lang/nl/admin_plugin.txt
new file mode 100644
index 000000000..36731b0b0
--- /dev/null
+++ b/lib/plugins/plugin/lang/nl/admin_plugin.txt
@@ -0,0 +1,3 @@
+===== Pluginmanager =====
+
+Op deze pagina kunt u alle DokuWiki [[doku>plugins|plugins]] beheren. Om plugins te kunnen downloaden en installeren, moet de plugin-directory schrijfbaar zijn voor de webserver. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/nl/lang.php b/lib/plugins/plugin/lang/nl/lang.php
new file mode 100644
index 000000000..0599c3184
--- /dev/null
+++ b/lib/plugins/plugin/lang/nl/lang.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Dutch language file
+ *
+ * @author Wouter Schoot <wouter@schoot.org>
+ * @author John de Graaff <john@de-graaff.net>
+ * @author Niels Schoot <niels.schoot@quintiq.com>
+ * @author Dion Nicolaas <dion@nicolaas.net>
+ * @author Danny Rotsaert <danny.rotsaert@edpnet.be>
+ * @author Marijn Hofstra hofstra.m@gmail.com
+ * @author Matthias Carchon webmaster@c-mattic.be
+ * @author Marijn Hofstra <hofstra.m@gmail.com>
+ * @author Timon Van Overveldt <timonvo@gmail.com>
+ * @author Jeroen
+ * @author Ricardo Guijt <ricardoguijt@gmail.com>
+ */
+$lang['menu'] = 'Plugins beheren';
+$lang['download'] = 'Download en installeer een nieuwe plugin';
+$lang['manage'] = 'Geïnstalleerde plugins';
+$lang['btn_info'] = 'informatie';
+$lang['btn_update'] = 'bijwerken';
+$lang['btn_delete'] = 'verwijderen';
+$lang['btn_settings'] = 'instellingen';
+$lang['btn_download'] = 'Download';
+$lang['btn_enable'] = 'Opslaan';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Geïnstalleerd:';
+$lang['lastupdate'] = 'Laatst bijgewerkt:';
+$lang['source'] = 'Bron:';
+$lang['unknown'] = 'onbekend';
+$lang['updating'] = 'Bijwerken ...';
+$lang['updated'] = 'Plugin %s succesvol bijgewerkt';
+$lang['updates'] = 'De volgende plugins zijn succesvol bijgewerkt';
+$lang['update_none'] = 'Geen updates gevonden.';
+$lang['deleting'] = 'Verwijderen ...';
+$lang['deleted'] = 'Plugin %s verwijderd.';
+$lang['downloading'] = 'Downloaden ...';
+$lang['downloaded'] = 'Plugin %s succesvol geïnstalleerd';
+$lang['downloads'] = 'De volgende plugins zijn succesvol geïnstalleerd:';
+$lang['download_none'] = 'Geen plugins gevonden, of er is een onbekende fout opgetreden tijdens het downloaden en installeren.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Onderdelen';
+$lang['noinfo'] = 'Deze plugin gaf geen informatie terug, misschien is hij defect.';
+$lang['name'] = 'Naam:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Type:';
+$lang['desc'] = 'Omschrijving:';
+$lang['author'] = 'Auteur:';
+$lang['www'] = 'Weblocatie:';
+$lang['error'] = 'Er is een onbekende fout opgetreden.';
+$lang['error_download'] = 'Kan het volgende plugin bestand niet downloaden: %s';
+$lang['error_badurl'] = 'Vermoedelijk onjuiste url - kan de filename niet uit de url afleiden';
+$lang['error_dircreate'] = 'Kan geen tijdelijke directory aanmaken voor de download';
+$lang['error_decompress'] = 'De pluginmanager kan het gedownloade bestand niet uitpakken. Dit kan het resultaat zijn van een mislukte download: probeer het opnieuw; of het compressieformaat is onbekend: in dat geval moet je de plugin handmatig downloaden en installeren.';
+$lang['error_copy'] = 'Er was een probleem met het kopiëren van een bestand tijdens de installatie van plugin <em>%s</em>: de schijf kan vol zijn of onjuiste toegangsrechten hebben. Dit kan tot gevolg hebben dat de plugin slechts gedeeltelijk geïnstalleerd is en kan uw wiki onstabiel maken.';
+$lang['error_delete'] = 'Er is een probleem opgetreden tijdens het verwijderen van plugin <em>%s</em>. De meest voorkomende oorzaak is onjuiste toegangsrechten op bestanden of directory\'s.';
+$lang['enabled'] = 'Plugin %s ingeschakeld.';
+$lang['notenabled'] = 'Plugin %s kon niet worden ingeschakeld, controleer bestandsrechten.';
+$lang['disabled'] = 'Plugin %s uitgeschakeld.';
+$lang['notdisabled'] = 'Plugin %s kon niet worden uitgeschakeld, controleer bestandsrechten.';
+$lang['packageinstalled'] = 'Plugin package (%d plugin%s: %s) succesvol geïnstalleerd.';
diff --git a/lib/plugins/plugin/lang/no/admin_plugin.txt b/lib/plugins/plugin/lang/no/admin_plugin.txt
new file mode 100644
index 000000000..1765b671d
--- /dev/null
+++ b/lib/plugins/plugin/lang/no/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Behandle programtillegg ======
+
+På denne siden kan du behandle alt som har å gjøre med DokuWikis [[doku>plugins|tillegg]]. For å kunne laste ned og installere et tillegg må webserveren ha skrivetilgang til mappen for tillegg.
diff --git a/lib/plugins/plugin/lang/no/lang.php b/lib/plugins/plugin/lang/no/lang.php
new file mode 100644
index 000000000..829d29387
--- /dev/null
+++ b/lib/plugins/plugin/lang/no/lang.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Norwegianlanguage file
+ *
+ * @author Thomas Nygreen <nygreen@gmail.com>
+ * @author Arild Burud <arildb@met.no>
+ * @author Torkill Bruland <torkar-b@online.no>
+ * @author Rune M. Andersen <rune.andersen@gmail.com>
+ * @author Jakob Vad Nielsen (me@jakobnielsen.net)
+ * @author Kjell Tore Næsgaard <kjell.t.nasgaard@ntnu.no>
+ * @author Knut Staring <knutst@gmail.com>
+ * @author Lisa Ditlefsen <lisa@vervesearch.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author Rune Rasmussen syntaxerror.no@gmail.com
+ * @author Jon Bøe <jonmagneboe@hotmail.com>
+ * @author Egil Hansen <egil@rosetta.no>
+ */
+$lang['menu'] = 'Behandle programtillegg';
+$lang['download'] = 'Last ned og installer et programtillegg';
+$lang['manage'] = 'Installerte programtillegg';
+$lang['btn_info'] = 'informasjon';
+$lang['btn_update'] = 'oppdater';
+$lang['btn_delete'] = 'slett';
+$lang['btn_settings'] = 'innstillinger';
+$lang['btn_download'] = 'Last ned';
+$lang['btn_enable'] = 'Lagre';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Installert:';
+$lang['lastupdate'] = 'Sist oppdatert:';
+$lang['source'] = 'Kilde:';
+$lang['unknown'] = 'ukjent';
+$lang['updating'] = 'Oppdaterer ...';
+$lang['updated'] = 'Tillegget %s er oppdatert';
+$lang['updates'] = 'Følgende programtillegg har blitt oppdatert';
+$lang['update_none'] = 'Ingen oppdateringer funnet.';
+$lang['deleting'] = 'Sletter ...';
+$lang['deleted'] = 'Tillegget %s ble slettet.';
+$lang['downloading'] = 'Laster ned ...';
+$lang['downloaded'] = 'Tillegget %s ble installert';
+$lang['downloads'] = 'De følgende tilleggene ble installert';
+$lang['download_none'] = 'Ingen tillegg funnet, eller det har vært et ukjent problem under nedlasting og installering.';
+$lang['plugin'] = 'Tillegg:';
+$lang['components'] = 'Komponenter';
+$lang['noinfo'] = 'Tillegget ga ikke noe informasjon. Det kan være ugyldig.';
+$lang['name'] = 'Navn:';
+$lang['date'] = 'Dato:';
+$lang['type'] = 'Type:';
+$lang['desc'] = 'Beskrivelse:';
+$lang['author'] = 'Forfatter:';
+$lang['www'] = 'Nett:';
+$lang['error'] = 'En ukjent feil oppstod.';
+$lang['error_download'] = 'Klarte ikke å laste ned tillegget i filen: %s';
+$lang['error_badurl'] = 'Mistenker feil URL - klarte ikke å finne filnavnet i URLen';
+$lang['error_dircreate'] = 'Klarte ikke å lage en midlertidig mappe for å laste ned';
+$lang['error_decompress'] = 'Tilleggsbehandleren klarte ikke å dekomprimere den nedlastede filen. Dette kan være på grunn av en feilet nedlasting, i så fall bør du prøve igjen, eller kompresjonsformatet kan være ukjent, i så fall må du laste ned og installere tillegget manuelt.';
+$lang['error_copy'] = 'Det skjedde en feil ved kopiering av en fil under installasjonen av <em>%s</em>: disken kan være full eller rettighetene satt feil. Dette kan ha ført til et delvist installert tillegg og gjort wikien ubrukelig.';
+$lang['error_delete'] = 'Det skjedde en feil under forsøket på å slette tillegget <em>%s</em>. Den mest sannsynlige grunnen er utilstrekkelige rettigheter for filene eller mappene.';
+$lang['enabled'] = 'Tillegget %s aktivert';
+$lang['notenabled'] = 'Plugin %s kunne ikke aktiveres, sjekk filrettighetene.';
+$lang['disabled'] = 'Plugin %s deaktivert';
+$lang['notdisabled'] = 'Plugin %s kunne ikke deaktiveres, sjekk filrettighetene.';
+$lang['packageinstalled'] = 'Installasjonen av tilleggspakka (%d tillegg: %s) var vellykka';
diff --git a/lib/plugins/plugin/lang/pl/admin_plugin.txt b/lib/plugins/plugin/lang/pl/admin_plugin.txt
new file mode 100644
index 000000000..f01048198
--- /dev/null
+++ b/lib/plugins/plugin/lang/pl/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Menadżer wtyczek ======
+
+Na tej stronie możesz zarządzać wszystkim co jest związane z [[doku>plugins|wtyczkami]] Dokuwiki. Aby móc ściągnąć i zainstalować wtyczkę, serwer WWW musi mieć prawo do zapisu w katalogu ''plugins''.
+
+
diff --git a/lib/plugins/plugin/lang/pl/lang.php b/lib/plugins/plugin/lang/pl/lang.php
new file mode 100644
index 000000000..02459f1de
--- /dev/null
+++ b/lib/plugins/plugin/lang/pl/lang.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * polish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Michał Tkacz <mehow@autocom.pl>
+ * @author Grzegorz Żur <grzegorz.zur@gmail.com>
+ * @author Mariusz Kujawski <marinespl@gmail.com>
+ * @author Maciej Kurczewski <pipijajko@gmail.com>
+ * @author Sławomir Boczek <slawkens@gmail.com>
+ * @author sleshek@wp.pl
+ * @author Leszek Stachowski <shazarre@gmail.com>
+ * @author maros <dobrimaros@yahoo.pl>
+ * @author Grzegorz Widła <dzesdzes@gmail.com>
+ * @author Łukasz Chmaj <teachmeter@gmail.com>
+ * @author Begina Felicysym <begina.felicysym@wp.eu>
+ */
+$lang['menu'] = 'Menadżer wtyczek';
+$lang['download'] = 'Ściągnij i zainstaluj nową wtyczkę';
+$lang['manage'] = 'Zainstalowane Wtyczki';
+$lang['btn_info'] = 'Informacje';
+$lang['btn_update'] = 'Aktualizuj';
+$lang['btn_delete'] = 'Usuń';
+$lang['btn_settings'] = 'Ustawienia';
+$lang['btn_download'] = 'Pobierz';
+$lang['btn_enable'] = 'Zapisz';
+$lang['url'] = 'Adres URL';
+$lang['installed'] = 'Instalacja:';
+$lang['lastupdate'] = 'Ostatnio zaktualizowana:';
+$lang['source'] = 'Źródło:';
+$lang['unknown'] = 'nieznane';
+$lang['updating'] = 'Aktualizuję...';
+$lang['updated'] = 'Aktualizacja wtyczki %s pomyślnie ściągnięta';
+$lang['updates'] = 'Aktualizacje następujących wtyczek zostały pomyślnie ściągnięte';
+$lang['update_none'] = 'Nie znaleziono aktualizacji.';
+$lang['deleting'] = 'Usuwam...';
+$lang['deleted'] = 'Wtyczka %s usunięta.';
+$lang['downloading'] = 'Pobieram...';
+$lang['downloaded'] = 'Wtyczka %s pomyślnie zainstalowana';
+$lang['downloads'] = 'Następujące wtyczki zostały pomyślnie zainstalowane:';
+$lang['download_none'] = 'Nie znaleziono wtyczek lub wystąpił nieznany problem podczas ściągania i instalacji.';
+$lang['plugin'] = 'Wtyczka:';
+$lang['components'] = 'Składniki';
+$lang['noinfo'] = 'Ta wtyczka nie zwróciła żadnych informacji, może być niepoprawna.';
+$lang['name'] = 'Nazwa:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Typ:';
+$lang['desc'] = 'Opis:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'WWW:';
+$lang['error'] = 'Wystąpił nieznany błąd.';
+$lang['error_download'] = 'Nie powiodło się ściągnięcie pliku wtyczki: %s';
+$lang['error_badurl'] = 'Prawdopodobnie zły url - nie da się ustalić nazwy pliku na podstawie urla';
+$lang['error_dircreate'] = 'Nie powiodło się stworzenie tymczasowego katalogu na pobrane pliki';
+$lang['error_decompress'] = 'Menadżer wtyczek nie był w stanie rozpakować ściągniętego pliku. Może to być spowodowane przez nieudany transfer (w takim przypadku powinieneś spróbować ponownie) lub nieznany format kompresji (w takim przypadku będziesz musiał ściągnąć i zainstalować wtyczkę ręcznie).';
+$lang['error_copy'] = 'Wystąpił błąd podczas kopiowania pliku w trakcie instalacji wtyczki %s: być może dysk jest pełny lub prawa dostępu są niepoprawne. Efektem może być częściowo zainstalowana wtyczka co może spowodować niestabilność Twojej instalacji wiki.';
+$lang['error_delete'] = 'Wystąpił błąd przy próbie usunięcia wtyczki <em>%s</em>. Prawdopodobną przyczyną są niewystarczające uprawnienia do katalogu.';
+$lang['enabled'] = 'Wtyczka %s włączona.';
+$lang['notenabled'] = 'Nie udało się uruchomić wtyczki %s, sprawdź uprawnienia dostępu do plików.';
+$lang['disabled'] = 'Wtyczka %s wyłączona.';
+$lang['notdisabled'] = 'Nie udało się wyłączyć wtyczki %s, sprawdź uprawnienia dostępu do plików.';
+$lang['packageinstalled'] = 'Pakiet wtyczek (%d wtyczki:% s) zainstalowany pomyślnie.';
diff --git a/lib/plugins/plugin/lang/pt-br/admin_plugin.txt b/lib/plugins/plugin/lang/pt-br/admin_plugin.txt
new file mode 100644
index 000000000..9e49f5136
--- /dev/null
+++ b/lib/plugins/plugin/lang/pt-br/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Gerenciamento de Plug-ins ======
+
+Nesta página você pode gerenciar tudo relacionado aos [[doku>plugins|plug-ins]] do DokuWiki. Para você baixar e instalar um plug-in o servidor web deve ter permissão de escrita na pasta onde ficam os plug-ins.
diff --git a/lib/plugins/plugin/lang/pt-br/lang.php b/lib/plugins/plugin/lang/pt-br/lang.php
new file mode 100644
index 000000000..26e73f4fc
--- /dev/null
+++ b/lib/plugins/plugin/lang/pt-br/lang.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Lucien Raven <lucienraven@yahoo.com.br>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Flávio Veras <flaviove@gmail.com>
+ * @author Jeferson Propheta <jeferson.propheta@gmail.com>
+ * @author jair.henrique@gmail.com
+ * @author Luis Dantas <luis@dantas.com>
+ * @author Frederico Guimarães <frederico@teia.bio.br>
+ * @author Jair Henrique <jair.henrique@gmail.com>
+ * @author Luis Dantas <luisdantas@gmail.com>
+ * @author Sergio Motta sergio@cisne.com.br
+ * @author Isaias Masiero Filho <masiero@masiero.org>
+ * @author Balaco Baco <balacobaco@imap.cc>
+ */
+$lang['menu'] = 'Gerenciar Plug-ins';
+$lang['download'] = 'Baixar e instalar um novo plug-in';
+$lang['manage'] = 'Plug-ins instalados';
+$lang['btn_info'] = 'informações';
+$lang['btn_update'] = 'atualizar';
+$lang['btn_delete'] = 'excluir';
+$lang['btn_settings'] = 'configurações';
+$lang['btn_download'] = 'Baixar';
+$lang['btn_enable'] = 'Salvar';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalação:';
+$lang['lastupdate'] = 'Última atualização:';
+$lang['source'] = 'Fonte:';
+$lang['unknown'] = 'desconhecida';
+$lang['updating'] = 'Atualizando...';
+$lang['updated'] = 'O plug-in %s foi atualizado com sucesso';
+$lang['updates'] = 'Os seguintes plug-ins foram atualizados com sucesso';
+$lang['update_none'] = 'Não foi encontrada nenhuma atualização.';
+$lang['deleting'] = 'Excluindo...';
+$lang['deleted'] = 'O plug-in %s foi excluído.';
+$lang['downloading'] = 'Baixando...';
+$lang['downloaded'] = 'O plug-in %s foi instalado com sucesso';
+$lang['downloads'] = 'Os seguintes plug-ins foram instalados com sucesso:';
+$lang['download_none'] = 'O plug-in não foi encontrado ou então ocorreu um problema desconhecido durante a transferência e instalação.';
+$lang['plugin'] = 'Plug-in:';
+$lang['components'] = 'Componentes';
+$lang['noinfo'] = 'Esse plug-in não retornou nenhuma informação. Ele pode ser inválido.';
+$lang['name'] = 'Nome:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipo:';
+$lang['desc'] = 'Descrição:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Ocorreu um erro desconhecido.';
+$lang['error_download'] = 'Não foi possível baixar o arquivo de plug-in: %s';
+$lang['error_badurl'] = 'Suspeita de URL mal formatada - não foi possível determinar o nome do arquivo a partir da URL';
+$lang['error_dircreate'] = 'Não foi possível criar a pasta temporária para receber a transferência';
+$lang['error_decompress'] = 'O gerenciador de plug-ins não conseguiu descompactar o arquivo transferido. Isso pode ser resultado de: uma corrupção do arquivo durante a transferência, nesse caso, você deve tentar novamente; ou o formato da compactação pode ser desconhecido, nesse caso você deve transferir e instalar o plug-in manualmente.';
+$lang['error_copy'] = 'Ocorreu um erro de cópia de arquivo na tentativa de instalar o plug-in <em>%s</em>: o disco pode estar cheio ou as permissões de acesso ao arquivo podem estar erradas. Isso pode resultar em um plug-in parcialmente instalado e tornar o seu wiki instável.';
+$lang['error_delete'] = 'Ocorreu um erro na tentativa de excluir o plug-in <em>%s</em>. A causa mais provável é a permissão de acesso insuficiente ao diretório ou ao arquivo.';
+$lang['enabled'] = 'O plug-in %s foi habilitado.';
+$lang['notenabled'] = 'Não foi possível habilitar o plug-in %s. Verifique as permissões de acesso.';
+$lang['disabled'] = 'O plug-in %s foi desabilitado.';
+$lang['notdisabled'] = 'Não foi possível desabilitar o plug-in %s. Verifique as permissões de acesso.';
+$lang['packageinstalled'] = 'O pacote do plugin (%d plugin(s): %s) foi instalado com sucesso.';
diff --git a/lib/plugins/plugin/lang/pt/admin_plugin.txt b/lib/plugins/plugin/lang/pt/admin_plugin.txt
new file mode 100644
index 000000000..2cc470193
--- /dev/null
+++ b/lib/plugins/plugin/lang/pt/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Gestor de Plugins ======
+
+Nesta página pode gerir tudo o que tenha a haver com [[doku>plugins|plugins]] DokuWiki. Atenção que a pasta que contém os plugins precisa de ter permissões de escrita para se poder efectuar o download. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/pt/lang.php b/lib/plugins/plugin/lang/pt/lang.php
new file mode 100644
index 000000000..dccd4f738
--- /dev/null
+++ b/lib/plugins/plugin/lang/pt/lang.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Portugueselanguage file
+ *
+ * @author José Monteiro <Jose.Monteiro@DoWeDo-IT.com>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Fil <fil@meteopt.com>
+ * @author André Neves <drakferion@gmail.com>
+ * @author José Campos zecarlosdecampos@gmail.com
+ */
+$lang['menu'] = 'Gerir Plugins';
+$lang['download'] = 'Descarregar e instalar um novo plugin';
+$lang['manage'] = 'Plugins Instalados';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'actualizar';
+$lang['btn_delete'] = 'remover';
+$lang['btn_settings'] = 'configurações';
+$lang['btn_download'] = 'Descarregar';
+$lang['btn_enable'] = 'Guardar';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalado em:';
+$lang['lastupdate'] = 'Actualizado em:';
+$lang['source'] = 'Fonte:';
+$lang['unknown'] = 'desconhecida';
+$lang['updating'] = 'Actualizando ...';
+$lang['updated'] = 'Plugin %s actualizado com sucesso.';
+$lang['updates'] = 'Os seguintes plguins foram actualizados com sucesso:';
+$lang['update_none'] = 'Não foram encontradas actualizações.';
+$lang['deleting'] = 'Removendo ...';
+$lang['deleted'] = 'Plugin %s removido.';
+$lang['downloading'] = 'Descarregando ...';
+$lang['downloaded'] = 'Plugin %s instalado com sucesso.';
+$lang['downloads'] = 'Os seguintes plguins foram instalados com sucesso:';
+$lang['download_none'] = 'Nenhum plugin encontrado ou ocorreu um problema ao descarregar ou instalar.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Componentes';
+$lang['noinfo'] = 'Este plugin não retornou qualquer informação, pode estar inválido.';
+$lang['name'] = 'Nome:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipo:';
+$lang['desc'] = 'Descrição:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Sítio:';
+$lang['error'] = 'Ocorreu um erro desconhecido.';
+$lang['error_download'] = 'Impossível descarregar o ficheiro do plugin: %s';
+$lang['error_badurl'] = 'URL suspeito ou errado - impossível determinar o ficheiro a partir do URL';
+$lang['error_dircreate'] = 'Impossível criar pasta temporária para receber os ficheiros a descarregar';
+$lang['error_decompress'] = 'O gestor de plugins foi incapaz de descomprimir o ficheiro transferido. Isto pode ter sido causado por uma má transferência, caso no qual você deverá tentar de novo, ou por um formato de compressão desconhecido, caso no qual você deve instalar o plugin manualmente.';
+$lang['error_copy'] = 'Ocorreu um erro na cópia do ficheiro na tentativa de instalar o plugin <em>%s</em>: o disco pode estar cheio ou as permissões de acesso do ficheiro podem estar erradas. Isto pode resultar em um plugin parcialmente instalado e deixar a instalação do seu wiki instável.';
+$lang['error_delete'] = 'Ocorreu um erro na tentativa de remover o plug-in <em>%s</em>. A causa mais provável é a permissão de acesso à directoria ou ao ficheiro insuficiente.';
+$lang['enabled'] = 'Plugin %s habilitado.';
+$lang['notenabled'] = 'Plugin %s não pôde ser habilitado, verifique as permissões.';
+$lang['disabled'] = 'Plugin %s desabilitado.';
+$lang['notdisabled'] = 'Plugin %s não pôde ser desabilitado, verifique as permissões.';
+$lang['packageinstalled'] = 'Pacote de Plugins (%d plugin(s): %s) instalado com sucesso.';
diff --git a/lib/plugins/plugin/lang/ro/admin_plugin.txt b/lib/plugins/plugin/lang/ro/admin_plugin.txt
new file mode 100644
index 000000000..a2956e45d
--- /dev/null
+++ b/lib/plugins/plugin/lang/ro/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Managementul Plugin-urilor ======
+
+In această pagină puteţi administra orice [[doku>plugins|plugin]] Dokuwiki. Pentru a descărca şi instala un plugin, directorul acestora trebuie să ofere webserver-ului acces la scriere.
diff --git a/lib/plugins/plugin/lang/ro/lang.php b/lib/plugins/plugin/lang/ro/lang.php
new file mode 100644
index 000000000..798ada1c7
--- /dev/null
+++ b/lib/plugins/plugin/lang/ro/lang.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Romanian language file
+ *
+ * @author Sergiu Baltariu <s_baltariu@yahoo.com>
+ * @author s_baltariu@yahoo.com
+ * @author Emanuel-Emeric Andrasi <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrași <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andraşi <em.andrasi@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrasi <em.andrasi@mandrivausers.ro>
+ * @author Marius OLAR <olarmariusalex@gmail.com>
+ * @author Emanuel-Emeric Andrași <em.andrasi@mandrivausers.ro>
+ */
+$lang['menu'] = 'Administrează plugin-uri';
+$lang['download'] = 'Descarcă şi instalează un nou plugin';
+$lang['manage'] = 'Plugin-uri instalate';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'actualizare';
+$lang['btn_delete'] = 'ştergere';
+$lang['btn_settings'] = 'setări';
+$lang['btn_download'] = 'Descarcă';
+$lang['btn_enable'] = 'Salvează';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalat:';
+$lang['lastupdate'] = 'Ultima actualizare:';
+$lang['source'] = 'Sursa:';
+$lang['unknown'] = 'necunoscut';
+$lang['updating'] = 'Se actualizează ...';
+$lang['updated'] = 'Plugin-ul %s a fost actualizat cu succes';
+$lang['updates'] = 'Următoarele plugin-uri au fost actualizate cu succes';
+$lang['update_none'] = 'Nu a fost găsită nici o actualizare.';
+$lang['deleting'] = 'Se şterge ...';
+$lang['deleted'] = 'Plugin-ul %s a fost şters.';
+$lang['downloading'] = 'Se descarcă ...';
+$lang['downloaded'] = 'Plugin-ul %s a fost instalat cu succes';
+$lang['downloads'] = 'Următoarele plugin-uri au fost instalate cu succes';
+$lang['download_none'] = 'Nici un plugin nu a fost găsit, sau o problemă necunoscută a apărut în timpul descărcării şi instalării.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Componente';
+$lang['noinfo'] = 'Acest plugin nu a furnizat nici o informaţie; ar putea fi invalid.';
+$lang['name'] = 'Nume:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tip:';
+$lang['desc'] = 'Descriere:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'A intervenit o eroare necunoscută.';
+$lang['error_download'] = 'Nu a fost posibilă descărcarea plugin-ului: %s';
+$lang['error_badurl'] = 'url suspectat ca fiind eronat - nu a putut fi determinat numele fişierului din url';
+$lang['error_dircreate'] = 'Nu a putut fi creat directorul temporar pentru descărcarea fişierului';
+$lang['error_decompress'] = 'Administratorul de plugin-uri nu a putut dezarhiva fişierul descărcat. Aceasta se poate datora unei erori la descărcare, caz în care trebuie să încercaţi din nou; sau formatul de arhivare este necunoscut, caz în care va trebui să descărcaţi şi să instalaţi plugin-ul manual.';
+$lang['error_copy'] = 'O eroare la copiere a apărut la instalarea fişierelor plugin-ului <em>%s</em>: discul poate fi plin sau drepturile de acces ale fişierelor sunt incorecte. Aceasta poate avea ca rezultat o instalare parţială a plugin-ului şi o instabilitate a instalării wiki.';
+$lang['error_delete'] = 'O eroare a apărut la ştergerea plugin-ului <em>%s</em>. Cea mai probabilă cauză sunt drepturile de acces insuficiente ale fişierului sau directorului.';
+$lang['enabled'] = 'Plugin %s activat.';
+$lang['notenabled'] = 'Plugin-ul %s nu poate fi activat, verificaţi permisiunile fişierului.';
+$lang['disabled'] = 'Plugin %s dezactivat.';
+$lang['notdisabled'] = 'Plugin-ul %s nu poate fi dezactivat, verificaţi permisiunile fişierului.';
+$lang['packageinstalled'] = 'Pachet modul (%d modul(e): %s) instalat cu succes.';
diff --git a/lib/plugins/plugin/lang/ru/admin_plugin.txt b/lib/plugins/plugin/lang/ru/admin_plugin.txt
new file mode 100644
index 000000000..3e00e4150
--- /dev/null
+++ b/lib/plugins/plugin/lang/ru/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Управление плагинами ======
+
+Здесь вы можете делать всё, что связано с [[doku>plugins|плагинами]] «ДокуВики». Для того, чтобы скачивать и устанавливать плагины, директория плагинов должна быть доступна для записи веб-сервером.
+
+
diff --git a/lib/plugins/plugin/lang/ru/lang.php b/lib/plugins/plugin/lang/ru/lang.php
new file mode 100644
index 000000000..757b607f5
--- /dev/null
+++ b/lib/plugins/plugin/lang/ru/lang.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * russian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Denis Simakov <akinoame1@gmail.com>
+ * @author Andrew Pleshakov <beotiger@mail.ru>
+ * @author Змей Этерийский evil_snake@eternion.ru
+ * @author Hikaru Nakajima <jisatsu@mail.ru>
+ * @author Alexei Tereschenko <alexeitlex@yahoo.com>
+ * @author Irina Ponomareva irinaponomareva@webperfectionist.com
+ * @author Alexander Sorkin <kibizoid@gmail.com>
+ * @author Kirill Krasnov <krasnovforum@gmail.com>
+ * @author Vlad Tsybenko <vlad.development@gmail.com>
+ * @author Aleksey Osadchiy <rfc@nm.ru>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Ladyko Andrey <fylh@succexy.spb.ru>
+ * @author Eugene <windy.wanderer@gmail.com>
+ */
+$lang['menu'] = 'Управление плагинами';
+$lang['download'] = 'Скачать и установить новый плагин';
+$lang['manage'] = 'Установленные плагины';
+$lang['btn_info'] = 'данные';
+$lang['btn_update'] = 'обновить';
+$lang['btn_delete'] = 'удалить';
+$lang['btn_settings'] = 'настройки';
+$lang['btn_download'] = 'Скачать';
+$lang['btn_enable'] = 'Сохранить';
+$lang['url'] = 'Адрес';
+$lang['installed'] = 'Установлен:';
+$lang['lastupdate'] = 'Последнее обновление:';
+$lang['source'] = 'Источник:';
+$lang['unknown'] = 'неизвестно';
+$lang['updating'] = 'Обновление...';
+$lang['updated'] = 'Плагин %s успешно обновлён';
+$lang['updates'] = 'Следующие плагины были успешно обновлены';
+$lang['update_none'] = 'Обновления не найдены.';
+$lang['deleting'] = 'Удаление...';
+$lang['deleted'] = 'Плагин %s удалён.';
+$lang['downloading'] = 'Скачивание...';
+$lang['downloaded'] = 'Плагин %s успешно установлен';
+$lang['downloads'] = 'Следующие плагины были успешно установлены:';
+$lang['download_none'] = 'Плагины не найдены или возникла неизвестная проблема в процессе скачивания и установки.';
+$lang['plugin'] = 'Плагин:';
+$lang['components'] = 'Компоненты';
+$lang['noinfo'] = 'Этот плагин не сообщил никаких данных, он может быть нерабочим.';
+$lang['name'] = 'Название:';
+$lang['date'] = 'Дата:';
+$lang['type'] = 'Тип:';
+$lang['desc'] = 'Описание:';
+$lang['author'] = 'Автор:';
+$lang['www'] = 'Странца:';
+$lang['error'] = 'Произошла неизвестная ошибка.';
+$lang['error_download'] = 'Не могу скачать файл плагина: %s';
+$lang['error_badurl'] = 'Возможно неправильный адрес — не могу определить имя файла из адреса';
+$lang['error_dircreate'] = 'Не могу создать временную директорию для скачивания';
+$lang['error_decompress'] = 'Менеджеру плагинов не удалось распаковать скачанный файл. Это может быть результатом ошибки при скачивании, в этом случае вы можете попробовать снова, или же плагин упакован неизвестным архиватором, тогда вам необходимо скачать и установить плагин вручную.';
+$lang['error_copy'] = 'Произошла ошибка копирования при попытке установки файлов для плагина <em>%s</em>: переполнение диска или неправильные права доступа. Это могло привести к частичной установке плагина и неустойчивости вашей вики.';
+$lang['error_delete'] = 'Произошла ошибка при попытке удалить плагин <em>%s</em>. Наиболее вероятно, что нет необходимых прав доступа к файлам или директориям';
+$lang['enabled'] = 'Плагин %s включён.';
+$lang['notenabled'] = 'Не удалось включить плагин %s. Проверьте системные права доступа к файлам.';
+$lang['disabled'] = 'Плагин %s отключён.';
+$lang['notdisabled'] = 'Не удалось отключить плагин %s. Проверьте системные права доступа к файлам.';
diff --git a/lib/plugins/plugin/lang/sk/admin_plugin.txt b/lib/plugins/plugin/lang/sk/admin_plugin.txt
new file mode 100644
index 000000000..ad3ae7f58
--- /dev/null
+++ b/lib/plugins/plugin/lang/sk/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== Správa pluginov ======
+
+Na tejto stránke je možné spravovať [[doku>plugins|pluginy]] Dokuwiki. Aby bolo možné sťahovať a inštalovať pluginy, musí mať webový server prístup pre zápis do adresára //plugin//.
+
diff --git a/lib/plugins/plugin/lang/sk/lang.php b/lib/plugins/plugin/lang/sk/lang.php
new file mode 100644
index 000000000..5024872f1
--- /dev/null
+++ b/lib/plugins/plugin/lang/sk/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Slovak language file
+ *
+ * @author Ondrej Végh <ov@vsieti.sk>
+ * @author Michal Mesko <michal.mesko@gmail.com>
+ * @author exusik@gmail.com
+ * @author Martin Michalek <michalek.dev@gmail.com>
+ */
+$lang['menu'] = 'Správa pluginov';
+$lang['download'] = 'Stiahnuť a nainštalovať plugin';
+$lang['manage'] = 'Nainštalované pluginy';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'aktualizovať';
+$lang['btn_delete'] = 'zmazať';
+$lang['btn_settings'] = 'nastavenia';
+$lang['btn_download'] = 'Stiahnuť';
+$lang['btn_enable'] = 'Uložiť';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Nainštalovaný:';
+$lang['lastupdate'] = 'Aktualizovaný:';
+$lang['source'] = 'Zdroj:';
+$lang['unknown'] = 'neznámy';
+$lang['updating'] = 'Aktualizuje sa ...';
+$lang['updated'] = 'Plugin %s bol úspešne aktualizovaný';
+$lang['updates'] = 'Nasledujúce pluginy bol úspešne aktualizované:';
+$lang['update_none'] = 'Neboli nájdené žiadne aktualizácie.';
+$lang['deleting'] = 'Vymazáva sa ...';
+$lang['deleted'] = 'Plugin %s bol zmazaný.';
+$lang['downloading'] = 'Sťahuje sa ...';
+$lang['downloaded'] = 'Plugin %s bol úspešne stiahnutý';
+$lang['downloads'] = 'Nasledujúce pluginy bol úspešne stiahnuté:';
+$lang['download_none'] = 'Neboli nájdené žiadne pluginy alebo nastal neznámy problém počas sťahovania a inštalácie pluginov.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Súčasti';
+$lang['noinfo'] = 'Tento plugin neobsahuje žiadne informácie, je možné, že je chybný.';
+$lang['name'] = 'názov:';
+$lang['date'] = 'Dátum:';
+$lang['type'] = 'Typ:';
+$lang['desc'] = 'Popis:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Nastala neznáma chyba.';
+$lang['error_download'] = 'Nie je možné stiahnuť súbor pluginu: %s';
+$lang['error_badurl'] = 'Pravdepodobne zlá url adresa - nie je možné z nej určiť meno súboru';
+$lang['error_dircreate'] = 'Nie je možné vytvoriť dočasný adresár pre uloženie sťahovaného súboru';
+$lang['error_decompress'] = 'Správca pluginov nedokáže dekomprimovať stiahnutý súbor. Môže to byť dôsledok zlého stiahnutia, v tom prípade to skúste znovu, alebo môže ísť o neznámy formát súboru, v tom prípade musíte stiahnuť a nainštalovať plugin manuálne.';
+$lang['error_copy'] = 'Nastala chyba kopírovania súboru počas pokusu inštalovať súbory pluginu<em>%s</em>: disk môže byť plný alebo prístupové práva k súboru môžu byť nesprávne. Toto môže mať za následok čiastočne nainštalovanie pluginu a nestabilitu vašej DokuWiki.';
+$lang['error_delete'] = 'Nastala chyba počas pokusu o zmazanie pluginu <em>%s</em>. Najpravdepodobnejším dôvodom môžu byť nedostatočné prístupové práva pre súbor alebo adresár';
+$lang['enabled'] = 'Plugin %s aktivovaný.';
+$lang['notenabled'] = 'Plugin %s nemôže byť aktivovaný, skontrolujte prístupové práva.';
+$lang['disabled'] = 'Plugin %s deaktivovaný.';
+$lang['notdisabled'] = 'Plugin %s nemôže byť deaktivovaný, skontrolujte prístupové práva.';
+$lang['packageinstalled'] = 'Plugin package (%d plugin(s): %s) úspešne inštalovaný.';
diff --git a/lib/plugins/plugin/lang/sl/admin_plugin.txt b/lib/plugins/plugin/lang/sl/admin_plugin.txt
new file mode 100644
index 000000000..5fd02e1ba
--- /dev/null
+++ b/lib/plugins/plugin/lang/sl/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Upravljanje vstavkov ======
+
+Na tej strani je mogoče spreminjati in prilagajati nastavitve DokuWiki [[doku>plugins|vstavkov]]. Za prejemanje in nameščanje vstavkov v ustrezne mape, morajo imeti te določena ustrezna dovoljenja za pisanje spletnega strežnika.
diff --git a/lib/plugins/plugin/lang/sl/lang.php b/lib/plugins/plugin/lang/sl/lang.php
new file mode 100644
index 000000000..3e5f8c8af
--- /dev/null
+++ b/lib/plugins/plugin/lang/sl/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Slovenian language file
+ *
+ * @author Dejan Levec <webphp@gmail.com>
+ * @author Boštjan Seničar <senicar@gmail.com>
+ * @author Gregor Skumavc (grega.skumavc@gmail.com)
+ * @author Matej Urbančič (mateju@svn.gnome.org)
+ */
+$lang['menu'] = 'Upravljanje vstavkov';
+$lang['download'] = 'Prejmi in namesti nov vstavek';
+$lang['manage'] = 'Nameščeni vstavki';
+$lang['btn_info'] = 'Podrobnosti';
+$lang['btn_update'] = 'Posodobi';
+$lang['btn_delete'] = 'Izbriši';
+$lang['btn_settings'] = 'Nastavitve';
+$lang['btn_download'] = 'Prejmi';
+$lang['btn_enable'] = 'Shrani';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Nameščeno:';
+$lang['lastupdate'] = 'Nazadnje posodobljeno:';
+$lang['source'] = 'Vir:';
+$lang['unknown'] = 'neznano';
+$lang['updating'] = 'Posodabljanje ...';
+$lang['updated'] = 'Vstavek %s je uspešno posodobljen';
+$lang['updates'] = 'Navedeni vstavki so uspešno posodobljeni';
+$lang['update_none'] = 'Posodobitev ni mogoče najti.';
+$lang['deleting'] = 'Brisanje ...';
+$lang['deleted'] = 'Vstavek %s je izbrisan.';
+$lang['downloading'] = 'Prejemanje ...';
+$lang['downloaded'] = 'Vstavek %s je uspešno nameščen';
+$lang['downloads'] = 'Navedeni vstavki so uspešno nameščeni:';
+$lang['download_none'] = 'Vstavkov ni mogoče najti ali pa je prišlo do napake med prejemanjem in nameščanjem.';
+$lang['plugin'] = 'Vstavek:';
+$lang['components'] = 'Sestavni deli';
+$lang['noinfo'] = 'Vstavek nima vpisanih podrobnih podatkov, kar pomeni, da je morda neveljaven.';
+$lang['name'] = 'Ime:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Vrsta:';
+$lang['desc'] = 'Opis:';
+$lang['author'] = 'Avtor:';
+$lang['www'] = 'Spletna stran:';
+$lang['error'] = 'Prišlo je do neznane napake.';
+$lang['error_download'] = 'Ni mogoče prejeti datoteke vstavka: %s';
+$lang['error_badurl'] = 'Napaka naslova URL - ni mogoče določiti imena datoteke iz naslova URL';
+$lang['error_dircreate'] = 'Ni mogoče ustvariti začasne mape za prejemanje';
+$lang['error_decompress'] = 'Z upravljalnikom vstavkov ni mogoče razširiti prejetega arhiva vstavka. Najverjetneje je prišlo do napake med prejemanjem datoteke ali pa zapis arhiva ni znan. Poskusite znova ali pa napako odpravite z ročnim nameščanjem vstavka.';
+$lang['error_copy'] = 'Prišlo je do napake med nameščanjem datotek vstavka <em>%s</em>: najverjetneje so težave s prostorom za namestitev ali pa ni ustreznih dovoljenj za nameščanje. Zaradi nepopolne namestitve lahko nastopijo težave v delovanju sistema Wiki.';
+$lang['error_delete'] = 'Prišlo je do napake med brisanjem vstavka <em>%s</em>: najverjetneje ni ustreznih dovoljenj za dostop do datoteke ali mape';
+$lang['enabled'] = 'Vstavek %s je omogočen.';
+$lang['notenabled'] = 'Vstavka %s ni mogoče omogočiti zaradi neustreznih dovoljen.';
+$lang['disabled'] = 'Vstavek %s je onemogočen.';
+$lang['notdisabled'] = 'Vstavka %s ni mogoče onemogočiti zaradi neustreznih dovoljen.';
+$lang['packageinstalled'] = 'Paket vstavka (%d vstavkov: %s) je uspešno nameščen.';
diff --git a/lib/plugins/plugin/lang/sq/admin_plugin.txt b/lib/plugins/plugin/lang/sq/admin_plugin.txt
new file mode 100644
index 000000000..2e1f19234
--- /dev/null
+++ b/lib/plugins/plugin/lang/sq/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Menaxhimi i Plugin-eve ======
+
+Në këtë faqe mund të menaxhoni çdo gjë që ka të bëjë me [[doku>plugins|plugin-et]] Dokuwiki. Që të jetë në gjendje për të shkarkuar dhe instaluar një plugin, dosja e plugin-it duhet të jetë e shkrueshme nga webserver-i. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/sq/lang.php b/lib/plugins/plugin/lang/sq/lang.php
new file mode 100644
index 000000000..9ddcf527f
--- /dev/null
+++ b/lib/plugins/plugin/lang/sq/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Albanian language file
+ *
+ * @author Leonard Elezi leonard.elezi@depinfo.info
+ */
+$lang['menu'] = 'Menaxho Plugin-et';
+$lang['download'] = 'Shkarko dhe instalo një plugin të ri';
+$lang['manage'] = 'Plugin-et e Instaluar';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'përditëso';
+$lang['btn_delete'] = 'fshi';
+$lang['btn_settings'] = 'settings';
+$lang['btn_download'] = 'Shkarko';
+$lang['btn_enable'] = 'Ruaj';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Të instaluar:';
+$lang['lastupdate'] = 'Përditësuar së fundmi:';
+$lang['source'] = 'Kodi Burim:';
+$lang['unknown'] = 'e panjohur';
+$lang['updating'] = 'Duke u përditësuar...';
+$lang['updated'] = 'Plugini %s u përditësua me sukses';
+$lang['updates'] = 'Plugin-et e mëposhtme u përditësuan me sukses';
+$lang['update_none'] = 'Nuk u gjetën përditësime.';
+$lang['deleting'] = 'Duke fshirë...';
+$lang['deleted'] = 'Plugini %s u fshi.';
+$lang['downloading'] = 'Duke shkarkuar...';
+$lang['downloaded'] = 'Plugini %s u instalua me sukses';
+$lang['downloads'] = 'Plugin-et e mëposhtëm u instaluan me sukses:';
+$lang['download_none'] = 'Asnjë plugin nuk u gjend, ose ka ndodhur një gabim i panjohur gjatë shkarkimit dhe instalimit.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Përbërësit:';
+$lang['noinfo'] = 'Ky plugin nuk ktheu asnjë informacion, mund të jetë i pavlefshëm.';
+$lang['name'] = 'Emri:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipi:';
+$lang['desc'] = 'Përshkrimi:';
+$lang['author'] = 'Autori:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Ndodhi një gabim i panjohur.';
+$lang['error_download'] = 'Nuk mundi të shkarkohej skedari i plugin-it: %s';
+$lang['error_badurl'] = 'Dyshohet url e prishur - nuk mund të gjendet emri i skedarit nga url-ja';
+$lang['error_dircreate'] = 'Nuk mundi të krijohej dosja e përkohshme për të marë shkarkimin.';
+$lang['error_decompress'] = 'Menaxhuesi i plugin-eve nuk ishte në gjendje të dekompresonte skedarin e shkarkuar. Kjo mund të jetë si rezultat i një shkarkimi të keq, në këtë rast duhet të provoni përsëri; ose formati i kompresimit mund të jetë i panjohur, në këtë rast do t\'ju duhet ta shkarkoni dhe instaloni plugin-in manualisht.';
+$lang['error_copy'] = 'Ndodhi gabim kopjim-skedari gjatë përpjekjes për të instaluar skedarët për plugin-in <em>%s</em>: disku mund të jetë plotë ose të drejtat për aksesim skedari mund të jenë të gabuara. Kjo mund të ketë shkaktuar një instalim të pjesshëm të plugin-it dhe ta lërë instalimin e wiki-t tënd të paqëndrueshëm.';
+$lang['error_delete'] = 'Ndodhi një gabim gjatë përpjekjes për të fshirë plugin-in <em>%s</em>. Shkaku më i mundshëm është të drejta të pamjaftueshme për aksesim skedari ose dosjeje.';
+$lang['enabled'] = 'Plugini %s u aktivizua.';
+$lang['notenabled'] = 'Plugini %s nuk mundi të aktivizohej, kontrollo të drejtat e aksesit për skedarin.';
+$lang['disabled'] = 'Plugin %s është i paaktivizuar.';
+$lang['notdisabled'] = 'Plugini %s nuk mundi të çaktivizohej, kontrollo të drejtat e aksesit për skedarin.';
diff --git a/lib/plugins/plugin/lang/sr/admin_plugin.txt b/lib/plugins/plugin/lang/sr/admin_plugin.txt
new file mode 100644
index 000000000..6262ece40
--- /dev/null
+++ b/lib/plugins/plugin/lang/sr/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Управљач додацима ======
+
+На овој страни можете управљати са свим у вези DokuWiki [[doku>plugins|додацима]]. Да бисте имали могућност преузимања и инсталирања додатака, фасцикла за додатке мора имати дозволу за писање. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/sr/lang.php b/lib/plugins/plugin/lang/sr/lang.php
new file mode 100644
index 000000000..bc22770a1
--- /dev/null
+++ b/lib/plugins/plugin/lang/sr/lang.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Serbian language file
+ *
+ * @author Иван Петровић petrovicivan@ubuntusrbija.org
+ * @author Ivan Petrovic <petrovicivan@ubuntusrbija.org>
+ * @author Miroslav Šolti <solti.miroslav@gmail.com>
+ */
+$lang['menu'] = 'Управљач додацима';
+$lang['download'] = 'Преузми и инсталирај нови додатак';
+$lang['manage'] = 'Инсталирани додаци';
+$lang['btn_info'] = 'инфо';
+$lang['btn_update'] = 'ажурирај';
+$lang['btn_delete'] = 'обриши';
+$lang['btn_settings'] = 'поставке';
+$lang['btn_download'] = 'Преузми';
+$lang['btn_enable'] = 'Сачувај';
+$lang['url'] = 'УРЛ';
+$lang['installed'] = 'Инсталирани:';
+$lang['lastupdate'] = 'Последњи пут ажурирани:';
+$lang['source'] = 'Извор:';
+$lang['unknown'] = 'непознат';
+$lang['updating'] = 'Ажурирање:';
+$lang['updated'] = 'Додатак %s је успешно ажуриран';
+$lang['updates'] = 'Следећи додаци су успешно ажурирани';
+$lang['update_none'] = 'Нема доступних ажурирања.';
+$lang['deleting'] = 'Брисање...';
+$lang['deleted'] = 'Додатак %s је обрисан.';
+$lang['downloading'] = 'Преузимање...';
+$lang['downloaded'] = 'Додатак %s је успешно инсталиран';
+$lang['downloads'] = 'Следећи додаци су успешно инсталирани:';
+$lang['download_none'] = 'Нема додатака, или се јавио непознат проблем током преузимања или инсталирања.';
+$lang['plugin'] = 'Додатак:';
+$lang['components'] = 'Компоненте';
+$lang['noinfo'] = 'Овај додатак не враћа никакве информације, можда је неисправан.';
+$lang['name'] = 'Име:';
+$lang['date'] = 'Датум:';
+$lang['type'] = 'Врста:';
+$lang['desc'] = 'Опис:';
+$lang['author'] = 'Аутор:';
+$lang['www'] = 'Веб:';
+$lang['error'] = 'Десила се непозната грешка.';
+$lang['error_download'] = 'Немогуће је преузети додатак: %s';
+$lang['error_badurl'] = 'Сумњам на лош УРЛ - немогу да одредим назив датотеке ';
+$lang['error_dircreate'] = 'Немогућност прављења привремене фасцикле за преузимање';
+$lang['error_decompress'] = 'Управљач додацима није у могућности да распакује преузету датотеку. Разлог може да буде лошег преузимања, у том случају пробајте још једном; или је непознат облик компресије, у том случају ручно преузмите и инсталирајте додатак.';
+$lang['error_copy'] = 'Појавила се грешка у копирању у току иснталације додатка <em>%s</em>: складиште је можда пуно или дозволе за уписивање нису постављене како треба. Резултат може бити делимично инсталиран додатак и вики у нестабилном стању.';
+$lang['error_delete'] = 'Појавила се грешка у покушају брисања додатка <em>%s</em>. Нејчешћи узрок је недостатак потребних дозвола за операције са датотекама или фасциклама';
+$lang['enabled'] = 'Додатај %s је укључен.';
+$lang['notenabled'] = 'Додатак %s није могуће укључити, проверите дозволе приступа.';
+$lang['disabled'] = 'Додатај %s је исукључен.';
+$lang['notdisabled'] = 'Додатак %s није могуће исукључити, проверите дозволе приступа.';
diff --git a/lib/plugins/plugin/lang/sv/admin_plugin.txt b/lib/plugins/plugin/lang/sv/admin_plugin.txt
new file mode 100644
index 000000000..e490e5e60
--- /dev/null
+++ b/lib/plugins/plugin/lang/sv/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Hantera insticksmoduler ======
+
+På den här sidan kan man hantera allting som har att göra med Dokuwikis [[doku>plugins|insticksmoduler]]. För att man ska kunna ladda ned och installera en modul måste katalogen för insticksmoduler vara skrivbar av webbservern.
+
+
diff --git a/lib/plugins/plugin/lang/sv/lang.php b/lib/plugins/plugin/lang/sv/lang.php
new file mode 100644
index 000000000..5892e42b5
--- /dev/null
+++ b/lib/plugins/plugin/lang/sv/lang.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * swedish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Per Foreby <per@foreby.se>
+ * @author Nicklas Henriksson <nicklas[at]nihe.se>
+ * @author Håkan Sandell <hakan.sandell[at]mydata.se>
+ * @author Dennis Karlsson
+ * @author Tormod Otter Johansson <tormod@latast.se>
+ * @author emil@sys.nu
+ * @author Pontus Bergendahl <pontus.bergendahl@gmail.com>
+ * @author Tormod Johansson tormod.otter.johansson@gmail.com
+ * @author Emil Lind <emil@sys.nu>
+ * @author Bogge Bogge <bogge@bogge.com>
+ * @author Peter Åström <eaustreum@gmail.com>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ * @author mikael@mallander.net
+ */
+$lang['menu'] = 'Hantera insticksmoduler';
+$lang['download'] = 'Ladda ned och installera en ny insticksmodul';
+$lang['manage'] = 'Installerade insticksmoduler';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'uppdatera';
+$lang['btn_delete'] = 'radera';
+$lang['btn_settings'] = 'inställningar';
+$lang['btn_download'] = 'Ladda ned';
+$lang['btn_enable'] = 'Spara';
+$lang['url'] = 'Webbadress';
+$lang['installed'] = 'Installerad:';
+$lang['lastupdate'] = 'Senast uppdaterad:';
+$lang['source'] = 'Källa:';
+$lang['unknown'] = 'okänd';
+$lang['updating'] = 'Uppdaterar ...';
+$lang['updated'] = 'Insticksmodulen %s uppdaterades';
+$lang['updates'] = 'Följande Insticksmoduler har uppdaterats';
+$lang['update_none'] = 'Inga uppdateringar hittades.';
+$lang['deleting'] = 'Raderar ...';
+$lang['deleted'] = 'Insticksmodulen %s raderad.';
+$lang['downloading'] = 'Laddar ned ...';
+$lang['downloaded'] = 'Insticksmodulen %s installerades';
+$lang['downloads'] = 'Följande insticksmoduler har installerats:';
+$lang['download_none'] = 'Inga insticksmoduler hittades, eller så har det uppstått ett okänt fel under nedladdning och installation.';
+$lang['plugin'] = 'Insticksmodul:';
+$lang['components'] = 'Komponenter';
+$lang['noinfo'] = 'Den här insticksmodulen returnerade ingen information, den kan vara ogiltig.';
+$lang['name'] = 'Namn:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Typ:';
+$lang['desc'] = 'Beskrivning:';
+$lang['author'] = 'Författare:';
+$lang['www'] = 'Webb:';
+$lang['error'] = 'Ett okänt fel har inträffat.';
+$lang['error_download'] = 'Kan inte ladda ned fil till insticksmodul: %s';
+$lang['error_badurl'] = 'Misstänkt felaktig webbadress - kan inte bestämma filnamnet från webbadressen';
+$lang['error_dircreate'] = 'Kan inte skapa tillfällig katalog för nedladdade filer';
+$lang['error_decompress'] = 'Hanteraren för insticksmoduler kunde inte dekomprimera den nedladdade filen. Detta kan vara resultatet av en misslyckad nedladdning, och i så fall bör du försöka igen; eller så kan det komprimerade formatet vara okänt, och då måste du ladda ned och installera insticksmodulen manuellt.';
+$lang['error_copy'] = 'Ett filkopieringsfel uppstod under försöket att installera filerna till insticksmodulen <em>%s</em>: disken kan vara full eller så kan filskyddet vara felaktigt. Detta kan ha lett till en delvis installerad insticksmodul, och gjort din wiki-installation instabil.';
+$lang['error_delete'] = 'Ett fel uppstod vid försöket att radera insticksmodulen <em>%s</em>. Den troligaste orsaken är otillräcklig behörighet till filer eller kataloger';
+$lang['enabled'] = 'Tilläggsmodulen %s är aktiverad.';
+$lang['notenabled'] = 'Tilläggsmodulen %s kunde inte aktiveras, kontrollera filrättigheterna.';
+$lang['disabled'] = 'Tiläggsmodulen %s är avaktiverad.';
+$lang['notdisabled'] = 'Tilläggsmodulen %s kunde inte avaktiveras, kontrollera filrättigheterna.';
diff --git a/lib/plugins/plugin/lang/th/admin_plugin.txt b/lib/plugins/plugin/lang/th/admin_plugin.txt
new file mode 100644
index 000000000..8611654be
--- /dev/null
+++ b/lib/plugins/plugin/lang/th/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== ตัวจัดการโปรแกรมเสริม ======
+
+ในหน้านี้คุณสามารถจัดการทุกๆอย่างที่จะต้องทำงานกับ [[doku>plugins|plugins]]โดกุวิกิ เพื่อที่จะสามารถดาวน์โหลดและติดตั้งโปรแกรมเสริม ตัวโฟลเดอร์โปรแกรมเสริม(plugin) จะต้องสามารถเขียนได้โดยเว็บเซิร์ฟเวอร์ \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/th/lang.php b/lib/plugins/plugin/lang/th/lang.php
new file mode 100644
index 000000000..dab094bcd
--- /dev/null
+++ b/lib/plugins/plugin/lang/th/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Thai language file
+ *
+ * @author Komgrit Niyomrath <n.komgrit@gmail.com>
+ * @author Kittithat Arnontavilas mrtomyum@gmail.com
+ * @author Arthit Suriyawongkul <arthit@gmail.com>
+ * @author Kittithat Arnontavilas <mrtomyum@gmail.com>
+ * @author Thanasak Sompaisansin <jombthep@gmail.com>
+ */
+$lang['menu'] = 'จัดการปลั๊กอิน';
+$lang['download'] = 'ดาวน์โหลดและติดตั้งปลั๊กอินใหม่';
+$lang['manage'] = 'ปลั๊กอินที่ติดตั้งไว้แล้ว';
+$lang['btn_info'] = 'ข้อมูล';
+$lang['btn_update'] = 'ปรับปรุง';
+$lang['btn_delete'] = 'ลบ';
+$lang['btn_settings'] = 'ตั้งค่า';
+$lang['btn_download'] = 'ดาวน์โหลด';
+$lang['btn_enable'] = 'บันทึก';
+$lang['url'] = 'ที่อยู่เว็บ';
+$lang['installed'] = 'ติดตั้งแล้ว:';
+$lang['lastupdate'] = 'ปรับปรุงล่าสุด:';
+$lang['source'] = 'ต้นกำเนิด';
+$lang['unknown'] = 'ไม่มีข้อมูล';
+$lang['updating'] = 'กำลังปรับปรุง ...';
+$lang['updated'] = 'โปรแกรมเสริม %s ได้รับการปรับปรุงสำเร็จแล้ว';
+$lang['updates'] = 'โปรแกรมเสริมต่อไปนี้ได้รับการปรับปรุงสำเร็จแล้ว';
+$lang['update_none'] = 'ไม่พบการปรับปรุงใดๆ';
+$lang['deleting'] = 'กำลังลบ ...';
+$lang['deleted'] = 'โปรแกรมเสริม %s ถูกลบแล้ว';
+$lang['downloading'] = 'กำลังดาวโหลด ...';
+$lang['downloaded'] = 'โปรแกรมเสริม %s ถูกติดตั้งสำเร็จแล้ว';
+$lang['downloads'] = 'โปรแกรมเสริมต่อไปนี้ได้รับการปรับปรุงสำเร็จแล้ว:';
+$lang['download_none'] = 'ไม่พบโปรแกรมเสริม, หรือมีปัญหาบางประการเกิดขึ้นระหว่างการดาวน์โหลด และติดตั้ง';
+$lang['plugin'] = 'โปรแกรมเสริม:';
+$lang['components'] = '่สวนประกอบ';
+$lang['noinfo'] = 'โปรแกรมเสริมนี้ไม่บอกข้อมูล, มันอาจไม่ใช่โปรแกรมเสริมจริง';
+$lang['name'] = 'ชื่อ:';
+$lang['date'] = 'วันที่:';
+$lang['type'] = 'ชนิด:';
+$lang['desc'] = 'รายละเอียด:';
+$lang['author'] = 'ผู้แต่ง:';
+$lang['www'] = 'เว็บ:';
+$lang['error'] = 'เกิดความผิดพลาดที่ระบุไม่ได้';
+$lang['error_download'] = 'ไม่สามารถดาวน์โหลดไฟล์โปรแกรมเสริม: %s';
+$lang['error_dircreate'] = 'ไม่สามารถสร้างโฟลเดอร์ชั่วคราวเพื่อที่จะรองรับการดาวน์โหลด';
+$lang['enabled'] = 'เปิดใช้งานโปรแกรมเสริม %s แล้ว';
+$lang['notenabled'] = 'โปรแกรมเสริม %s ไม่สามารถเปิดใช้งาน, กรุณาตรวจสอบสิทธิ์ของไฟล์';
+$lang['disabled'] = 'ปิดการใช้งานโปรแกรมเสริม %s แล้ว';
+$lang['notdisabled'] = 'โปรแกรมเสริม %s ไม่สามารถปิดการใช้งานได้, กรุณาตรวจสอบสิทธิ์ของไฟล์';
diff --git a/lib/plugins/plugin/lang/tr/admin_plugin.txt b/lib/plugins/plugin/lang/tr/admin_plugin.txt
new file mode 100644
index 000000000..956d701f6
--- /dev/null
+++ b/lib/plugins/plugin/lang/tr/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Eklenti Yönetimi ======
+
+Bu sayfada DokuWiki [[doku>plugins|eklentileri]] ile ilgili herşeyi düzenleyebilirsiniz. Eklenti kurup indirmek için, eklenti dizininin yazılabilir olması gerekmektedir.
diff --git a/lib/plugins/plugin/lang/tr/lang.php b/lib/plugins/plugin/lang/tr/lang.php
new file mode 100644
index 000000000..9a655e400
--- /dev/null
+++ b/lib/plugins/plugin/lang/tr/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Turkish language file
+ *
+ * @author Aydın Coşkuner <aydinweb@gmail.com>
+ * @author Cihan Kahveci <kahvecicihan@gmail.com>
+ * @author Yavuz Selim <yavuzselim@gmail.com>
+ * @author Caleb Maclennan <caleb@alerque.com>
+ */
+$lang['menu'] = 'Eklenti Yönetimi';
+$lang['download'] = 'Yeni bir eklenti indirip kur';
+$lang['manage'] = 'Kurulmuş Eklentiler';
+$lang['btn_info'] = 'bilgi';
+$lang['btn_update'] = 'güncelle';
+$lang['btn_delete'] = 'sil';
+$lang['btn_settings'] = 'Ayarlar';
+$lang['btn_download'] = 'İndir';
+$lang['btn_enable'] = 'Kaydet';
+$lang['url'] = 'Web Adresi';
+$lang['installed'] = 'Kuruldu:';
+$lang['lastupdate'] = 'Son güncelleştirme:';
+$lang['source'] = 'Kaynak:';
+$lang['unknown'] = 'bilinmiyor';
+$lang['updating'] = 'Güncelleştiriyor ...';
+$lang['updated'] = '%s eklentisi başarıyla güncellendi';
+$lang['updates'] = 'Şu eklentiler başarıyla güncellendi';
+$lang['update_none'] = 'Yeni bir güncelleme bulunamadı.';
+$lang['deleting'] = 'Siliniyor ...';
+$lang['deleted'] = '%s eklentisi silindi.';
+$lang['downloading'] = 'İndiriyor ...';
+$lang['downloaded'] = '%s eklentisi başarıyla kuruldu';
+$lang['downloads'] = 'Şu eklentiler başarıyla kuruldu:';
+$lang['download_none'] = 'Eklenti bulunamadı veya indirirken/kurarken bilinmeyen bir hata oluştu.';
+$lang['plugin'] = 'Eklenti:';
+$lang['components'] = 'Parçalar';
+$lang['noinfo'] = 'Bu eklentinin bilgileri alınamadı, geçerli bir eklenti olmayabilir.';
+$lang['name'] = 'Ad:';
+$lang['date'] = 'Tarih:';
+$lang['type'] = 'Tür:';
+$lang['desc'] = 'Açıklama:';
+$lang['author'] = 'Yazar:';
+$lang['www'] = 'Web Adresi:';
+$lang['error'] = 'Bilinmeyen bir hata oluştu.';
+$lang['error_download'] = 'Şu eklenti indirilemedi: %s';
+$lang['error_badurl'] = 'Yanlış adres olabilir - verilen adresten dosya adı alınamadı';
+$lang['error_dircreate'] = 'İndirmek için geçici klasör oluşturulamadı';
+$lang['error_decompress'] = 'Eklenti yöneticisi indirilen sıkıştırılmış dosyayı açamadı. Bu yanlış indirmeden kaynaklanabilir (bu durumda tekrar denemelisiniz). Ya da indirilen dosyanın sıkıştırma biçimi bilinmemektedir (bu durumda eklentiyi indirerek kendiniz kurmalısınız).';
+$lang['error_copy'] = '<em>%s</em> eklentisi dosyalarını kurmaya çalışırken kopyalama hatası ortaya çıktı. Sürücü dolu olabilir veya yazma yetkisi bulunmuyor olabilir. Bunun sebebi tam kurulmamış bir eklentinin wiki kurulumunu bozması olabilir.';
+$lang['error_delete'] = '<em>%s</em> eklentisini silerken bir hata oluştu. Bu hata yetersiz dosya/klasör erişim yetkisinden kaynaklanabilir.';
+$lang['enabled'] = '%s eklentisi etkinleştirildi.';
+$lang['notenabled'] = '%s eklentisi etkinleştirilemedi, dosya yetkilerini kontrol edin.';
+$lang['disabled'] = '%s eklentisi devre dışı bırakıldı.';
+$lang['notdisabled'] = '%s eklentisi devre dışı bırakılamadı, dosya yetkilerini kontrol edin.';
diff --git a/lib/plugins/plugin/lang/uk/admin_plugin.txt b/lib/plugins/plugin/lang/uk/admin_plugin.txt
new file mode 100644
index 000000000..7bdf8e5e5
--- /dev/null
+++ b/lib/plugins/plugin/lang/uk/admin_plugin.txt
@@ -0,0 +1,7 @@
+====== Керування доданками ======
+
+Тут ви можете керувати [[doku>plugins|доданками]] ДокуВікі. Для того, щоб завантажувати та встановлювати доданки, папка доданків повинна бути доступна для запису веб-сервером.
+
+
+
+
diff --git a/lib/plugins/plugin/lang/uk/lang.php b/lib/plugins/plugin/lang/uk/lang.php
new file mode 100644
index 000000000..036900f4e
--- /dev/null
+++ b/lib/plugins/plugin/lang/uk/lang.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * ukrainian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Oleksiy Voronin (ovoronin@gmail.com)
+ * @author serg_stetsuk@ukr.net
+ * @author okunia@gmail.com
+ * @author Oleksandr Kunytsia <okunia@gmail.com>
+ * @author Uko uko@uar.net
+ * @author Ulrikhe Lukoie <lukoie@gmail>.com
+ * @author Kate Arzamastseva pshns@ukr.net
+ */
+$lang['menu'] = 'Керування доданками';
+$lang['download'] = 'Завантажити та встановити новий доданок';
+$lang['manage'] = 'Встановлені доданки';
+$lang['btn_info'] = 'дані';
+$lang['btn_update'] = 'оновити';
+$lang['btn_delete'] = 'видалити';
+$lang['btn_settings'] = 'параметри';
+$lang['btn_download'] = 'Завантажити';
+$lang['btn_enable'] = 'Зберегти';
+$lang['url'] = 'Адреса';
+$lang['installed'] = 'Встановлено:';
+$lang['lastupdate'] = 'Останнє оновлення:';
+$lang['source'] = 'Джерело:';
+$lang['unknown'] = 'невідомо';
+$lang['updating'] = 'Оновлення ...';
+$lang['updated'] = 'Доданок %s успішно оновлено';
+$lang['updates'] = 'Наступні доданки були успішно оновлені';
+$lang['update_none'] = 'Оновлення не знайдено.';
+$lang['deleting'] = 'Видалення ...';
+$lang['deleted'] = 'Доданок %s видалено.';
+$lang['downloading'] = 'Завантаження ...';
+$lang['downloaded'] = 'Доданок %s успішно встановлено';
+$lang['downloads'] = 'Наступні доданки були успішно встановлені:';
+$lang['download_none'] = 'Доданки не знайдено або виникла невідома проблема в процессі завантаження та установки.';
+$lang['plugin'] = 'Доданок:';
+$lang['components'] = 'Компоненти';
+$lang['noinfo'] = 'Цей доданок не повідомив ніяких даних, він може бути не працюючим.';
+$lang['name'] = 'Назва:';
+$lang['date'] = 'Дата:';
+$lang['type'] = 'Тип:';
+$lang['desc'] = 'Опис:';
+$lang['author'] = 'Автор:';
+$lang['www'] = 'Сторінка:';
+$lang['error'] = 'Виникла невідома помилка.';
+$lang['error_download'] = 'Не можу завантажити файл доданка: %s';
+$lang['error_badurl'] = 'Можливо, невірна адреса - не можливо визначити ім\'я файлу з адреси';
+$lang['error_dircreate'] = 'Не можливо створити тимчасову папку для завантаження';
+$lang['error_decompress'] = 'Менеджеру доданків не вдалося розпакувати завантажений файл. Це може бути результатом помилки при завантаженні, в цьому разі ви можете спробувати знову; або ж доданок упакований невідомим архіватором, тоді вам необхідно завантажити та встановити доданок вручну.';
+$lang['error_copy'] = 'Виникла помилка копіювання при спробі установки файлів для доданка <em>%s</em>: переповнення диску або невірні права доступу. Це могло привести до часткової установки доданка и нестійкості вашої Вікі.';
+$lang['error_delete'] = 'При спробі вилучення доданка <em>%s</em> виникла помилка. Найбільш вірогідно, що немає необхідних прав доступу до файлів або директорії';
+$lang['enabled'] = 'Доданок %s увімкнено.';
+$lang['notenabled'] = 'Не вдається увімкнути доданок %s. Перевірте права доступу до файлу.';
+$lang['disabled'] = 'Доданок %s вимкнено.';
+$lang['notdisabled'] = 'Не вдається вимкнути доданок %s. Перевірте права доступу до файлу.';
+$lang['packageinstalled'] = 'Пакет плагінів (%d plugin(s): %s) успішно встановлений.';
diff --git a/lib/plugins/plugin/lang/zh-tw/admin_plugin.txt b/lib/plugins/plugin/lang/zh-tw/admin_plugin.txt
new file mode 100644
index 000000000..84d095f51
--- /dev/null
+++ b/lib/plugins/plugin/lang/zh-tw/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== 插件管理器 ======
+
+您可以用本頁管理與 Dokuwiki [[doku>plugins|插件]] 相關的選項。若要正常下載及安裝插件,插件所在的資料夾必須允許網頁伺服器寫入。
diff --git a/lib/plugins/plugin/lang/zh-tw/lang.php b/lib/plugins/plugin/lang/zh-tw/lang.php
new file mode 100644
index 000000000..54234212d
--- /dev/null
+++ b/lib/plugins/plugin/lang/zh-tw/lang.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Chinese Traditional language file
+ *
+ * @author Li-Jiun Huang <ljhuang.tw@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-simptrad.html
+ * @author Wayne San <waynesan@zerozone.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmai.com>
+ * @author Cheng-Wei Chien <e.cwchien@gmail.com>
+ * @author Danny Lin
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '管理插件 (Plugins)';
+$lang['download'] = '下載與安裝插件';
+$lang['manage'] = '已安裝的插件';
+$lang['btn_info'] = '資訊';
+$lang['btn_update'] = '更新';
+$lang['btn_delete'] = '刪除';
+$lang['btn_settings'] = '設定';
+$lang['btn_download'] = '下載';
+$lang['btn_enable'] = '儲存';
+$lang['url'] = 'URL';
+$lang['installed'] = '安裝:';
+$lang['lastupdate'] = '上次更新:';
+$lang['source'] = '來源:';
+$lang['unknown'] = '未知';
+$lang['updating'] = '更新中 ...';
+$lang['updated'] = '插件 %s 成功地更新';
+$lang['updates'] = '以下的插件已經成功地更新';
+$lang['update_none'] = '找不到更新';
+$lang['deleting'] = '刪除中 ...';
+$lang['deleted'] = '插件 %s 已刪除。';
+$lang['downloading'] = '下載中 ...';
+$lang['downloaded'] = '插件 %s 已成功地安裝';
+$lang['downloads'] = '以下的插件已成功地安裝:';
+$lang['download_none'] = '找不到插件,或在下載與安裝時發生了未知的問題';
+$lang['plugin'] = '插件:';
+$lang['components'] = '元件';
+$lang['noinfo'] = '此插件沒有回傳任何資訊,可能是無效的';
+$lang['name'] = '名稱:';
+$lang['date'] = '日期:';
+$lang['type'] = '類型:';
+$lang['desc'] = '描述:';
+$lang['author'] = '作者:';
+$lang['www'] = '網頁:';
+$lang['error'] = '一個未知的錯誤發生。';
+$lang['error_download'] = '無法下載插件檔案: %s';
+$lang['error_badurl'] = 'URL 可能有問題 - 從 URL 中無法得知文件名';
+$lang['error_dircreate'] = '無法建立暫存目錄來接收下載的內容';
+$lang['error_decompress'] = '插件管理器無法解壓下載的文件。這可能是由於下載出現錯誤,遇到這種情況,請您再次嘗試;或者是壓縮格式無法識別,遇到這種情況,您需要手動下載並安裝該插件。';
+$lang['error_copy'] = '嘗試安裝插件 <em>%s</em> 的相關文件時發生複製錯誤:可能是磁碟空間不足或檔案存取權限錯誤。這可能是由於未安裝完全的插件使維基系統不穩定導致。';
+$lang['error_delete'] = '嘗試刪除插件 <em>%s</em> 時發生錯誤。最可能原因是檔案或目錄存取權限不足';
+$lang['enabled'] = '插件 %s 已啟用。';
+$lang['notenabled'] = '插件 %s 無法啟用,請檢查檔案權限。';
+$lang['disabled'] = '插件 %s 已停用。';
+$lang['notdisabled'] = '插件 %s 無法停用,請檢查檔案權限。';
+$lang['packageinstalled'] = '插件 (%d 插件%s: %s) 已成功地安裝。';
diff --git a/lib/plugins/plugin/lang/zh/admin_plugin.txt b/lib/plugins/plugin/lang/zh/admin_plugin.txt
new file mode 100644
index 000000000..1618071a4
--- /dev/null
+++ b/lib/plugins/plugin/lang/zh/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== 插件管理器 ======
+
+本页中您可以管理与 Dokuwiki [[doku>plugins|插件]] 相关的选项。 要通过插件管理器正常下载并安装插件,插件所在的文件夹必须可写。
+
+
diff --git a/lib/plugins/plugin/lang/zh/lang.php b/lib/plugins/plugin/lang/zh/lang.php
new file mode 100644
index 000000000..58f05fbd9
--- /dev/null
+++ b/lib/plugins/plugin/lang/zh/lang.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * english language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-tradsimp.html
+ * @author George Sheraton guxd@163.com
+ * @author Simon zhan <simonzhan@21cn.com>
+ * @author mr.jinyi@gmail.com
+ * @author ben <ben@livetom.com>
+ * @author lainme <lainme993@gmail.com>
+ * @author caii <zhoucaiqi@gmail.com>
+ * @author Hiphen Lee <jacob.b.leung@gmail.com>
+ * @author caii, patent agent in China <zhoucaiqi@gmail.com>
+ * @author lainme993@gmail.com
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '插件管理器';
+$lang['download'] = '下载并安装新的插件';
+$lang['manage'] = '已安装的插件';
+$lang['btn_info'] = '信息';
+$lang['btn_update'] = '升级';
+$lang['btn_delete'] = '删除';
+$lang['btn_settings'] = '设置';
+$lang['btn_download'] = '下载';
+$lang['btn_enable'] = '保存';
+$lang['url'] = 'URL';
+$lang['installed'] = '已安装:';
+$lang['lastupdate'] = '最后更新于:';
+$lang['source'] = '来源:';
+$lang['unknown'] = '未知';
+$lang['updating'] = '正在升级...';
+$lang['updated'] = '插件 %s 升级成功';
+$lang['updates'] = '下列插件升级成功:';
+$lang['update_none'] = '未找到更新。';
+$lang['deleting'] = '正在删除...';
+$lang['deleted'] = '插件 %s 已删除';
+$lang['downloading'] = '正在下载...';
+$lang['downloaded'] = '插件 %s 安装成功';
+$lang['downloads'] = '下列插件安装成功:';
+$lang['download_none'] = '未找到插件,或下载和安装过程中出现了未知错误。';
+$lang['plugin'] = '插件:';
+$lang['components'] = '组件';
+$lang['noinfo'] = '该插件没有任何信息,有可能是无效插件。';
+$lang['name'] = '名称:';
+$lang['date'] = '日期:';
+$lang['type'] = '类别:';
+$lang['desc'] = '描述:';
+$lang['author'] = '作者:';
+$lang['www'] = '网址:';
+$lang['error'] = '产生了未知错误。';
+$lang['error_download'] = '无法下载插件:%s';
+$lang['error_badurl'] = 'URL 可能有问题 - 从 URL 中无法得知文件名';
+$lang['error_dircreate'] = '无法创建用于接收下载文件的';
+$lang['error_decompress'] = '插件管理器无法解压下载的文件。这可能是由于下载出现错误,遇到这种情况,请您再次尝试;或者是压缩格式无法识别,遇到这种情况,您需要手动下载并安装该插件。';
+$lang['error_copy'] = '尝试安装插件 <em>%s</em> 的相关文件时产生一个复制错误:磁盘空间已满或文件访问权限错误。这可能是由于一个安装了一部分的插件,并使得您的维基系统不稳定。';
+$lang['error_delete'] = '尝试删除插件 <em>%s</em> 时产生一个错误。最有可能的情况是文件或路径的访问权限不够';
+$lang['enabled'] = '%s 插件启用';
+$lang['notenabled'] = '%s插件启用失败,请检查文件权限。';
+$lang['disabled'] = '%s 插件禁用';
+$lang['notdisabled'] = '%s插件禁用失败,请检查文件权限。';
+$lang['packageinstalled'] = '插件 (%d plugin%s: %s) 已成功安装。';
diff --git a/lib/plugins/plugin/rtl.css b/lib/plugins/plugin/rtl.css
new file mode 100644
index 000000000..6ababd8e0
--- /dev/null
+++ b/lib/plugins/plugin/rtl.css
@@ -0,0 +1,51 @@
+
+#plugin__manager .pm_menu,
+#plugin__manager .pm_info,
+#plugin__manager p,
+#plugin__manager label {
+ text-align: right;
+}
+
+#plugin__manager .pm_menu {
+ float: right;
+}
+
+#plugin__manager .pm_info {
+ float: left;
+}
+
+#plugin__manager .pm_info dt {
+ float: right;
+ clear: right;
+}
+
+#plugin__manager .pm_info dd {
+ margin: 0 7em 0 0;
+}
+
+#plugin__manager .common fieldset {
+ text-align: right;
+}
+
+
+#plugin__manager .plugins .legend {
+ text-align: right;
+ float: right;
+}
+
+#plugin__manager .plugins .enable {
+ float: right;
+ margin-right: 0;
+ margin-left: 0.5em;
+}
+
+#plugin__manager .plugins .button {
+ float: left;
+ margin-right: 0.5em;
+}
+
+
+#plugin__manager .plugins fieldset.buttons .button {
+ float: right;
+}
+
diff --git a/lib/plugins/plugin/style.css b/lib/plugins/plugin/style.css
new file mode 100644
index 000000000..de6cca579
--- /dev/null
+++ b/lib/plugins/plugin/style.css
@@ -0,0 +1,156 @@
+/*
+ * admin plugin extension - style additions
+ *
+ * @author Christopher Smith chris@jalakai.co.uk
+ * @link http://wiki.jalakai.co.uk/dokuwiki/doku.php/tutorials/adminplugin
+ */
+
+#plugin__manager h2 {
+ margin-left: 0;
+}
+
+#plugin__manager form {
+ display: block;
+ margin: 0;
+ padding: 0;
+}
+
+#plugin__manager legend {
+ display: none;
+}
+
+#plugin__manager fieldset {
+ width: auto;
+}
+
+#plugin__manager .button {
+ margin: 0;
+}
+
+#plugin__manager p,
+#plugin__manager label {
+ text-align: left;
+}
+
+#plugin__manager .hidden {
+ display: none;
+}
+
+#plugin__manager .new {
+ background: #dee7ec;
+}
+
+/* IE won't understand but doesn't require it */
+#plugin__manager input[disabled] {
+ color: #ccc;
+ border-color: #ccc;
+}
+
+#plugin__manager .pm_menu,
+#plugin__manager .pm_info {
+ margin-left: 0;
+ text-align: left;
+}
+
+#plugin__manager .pm_menu {
+ float: left;
+ width: 48%;
+}
+
+#plugin__manager .pm_info {
+ float: right;
+ width: 50%;
+}
+
+#plugin__manager .common fieldset {
+ margin: 0;
+ padding: 0 0 1.0em 0;
+ text-align: left;
+ border: none;
+}
+
+#plugin__manager .common label {
+ padding: 0 0 0.5em 0;
+}
+
+#plugin__manager .common input.edit {
+ width: 24em;
+ margin: 0.5em;
+}
+
+#plugin__manager .plugins fieldset {
+ color: #000;
+ background: #fff;
+ text-align: right;
+ border-top: none;
+ border-right: none;
+ border-left: none;
+}
+
+#plugin__manager .plugins fieldset.protected {
+ background: #fdd;
+ color: #000;
+}
+
+#plugin__manager .plugins fieldset.disabled {
+ background: #e0e0e0;
+ color: #a8a8a8;
+}
+
+#plugin__manager .plugins .legend {
+ color: #000;
+ background: inherit;
+ display: block;
+ margin: 0;
+ padding: 0;
+ font-size: 1em;
+ line-height: 1.4em;
+ font-weight: normal;
+ text-align: left;
+ float: left;
+ padding: 0;
+ clear: none;
+}
+
+#plugin__manager .plugins .button {
+ font-size: 95%;
+}
+
+#plugin__manager .plugins fieldset.buttons {
+ border: none;
+}
+
+#plugin__manager .plugins fieldset.buttons .button {
+ float: left;
+}
+
+#plugin__manager .pm_info h3 {
+ margin-left: 0;
+}
+
+#plugin__manager .pm_info dl {
+ margin: 1em 0;
+ padding: 0;
+}
+
+#plugin__manager .pm_info dt {
+ width: 6em;
+ float: left;
+ clear: left;
+ margin: 0;
+ padding: 0;
+}
+
+#plugin__manager .pm_info dd {
+ margin: 0 0 0 7em;
+ padding: 0;
+ background: none;
+}
+
+#plugin__manager .plugins .enable {
+ float: left;
+ width: auto;
+ margin-right: 0.5em;
+}
+
+/* end admin plugin styles */
diff --git a/lib/plugins/popularity/action.php b/lib/plugins/popularity/action.php
new file mode 100644
index 000000000..bf11efba6
--- /dev/null
+++ b/lib/plugins/popularity/action.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Popularity Feedback Plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+require_once(DOKU_PLUGIN.'action.php');
+require_once(DOKU_PLUGIN.'popularity/admin.php');
+
+class action_plugin_popularity extends Dokuwiki_Action_Plugin {
+ var $helper;
+
+ function action_plugin_popularity(){
+ $this->helper = $this->loadHelper('popularity', false);
+ }
+
+ /**
+ * Register its handlers with the dokuwiki's event controller
+ */
+ function register(&$controller) {
+ $controller->register_hook('INDEXER_TASKS_RUN', 'AFTER', $this, '_autosubmit', array());
+ }
+
+ function _autosubmit(&$event, $param){
+ //Do we have to send the data now
+ if ( !$this->helper->isAutosubmitEnabled() || $this->_isTooEarlyToSubmit() ){
+ return;
+ }
+
+ //Actually send it
+ $status = $this->helper->sendData( $this->helper->gatherAsString() );
+
+
+ if ( $status !== '' ){
+ //If an error occured, log it
+ io_saveFile( $this->helper->autosubmitErrorFile, $status );
+ } else {
+ //If the data has been sent successfully, previous log of errors are useless
+ @unlink($this->helper->autosubmitErrorFile);
+ //Update the last time we sent data
+ touch ( $this->helper->autosubmitFile );
+ }
+
+ $event->stopPropagation();
+ $event->preventDefault();
+ }
+
+ /**
+ * Check if it's time to send autosubmit data
+ * (we should have check if autosubmit is enabled first)
+ */
+ function _isTooEarlyToSubmit(){
+ $lastSubmit = $this->helper->lastSentTime();
+ return $lastSubmit + 24*60*60*30 > time();
+ }
+}
diff --git a/lib/plugins/popularity/admin.php b/lib/plugins/popularity/admin.php
new file mode 100644
index 000000000..a04e98a66
--- /dev/null
+++ b/lib/plugins/popularity/admin.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ * Popularity Feedback Plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_popularity extends DokuWiki_Admin_Plugin {
+ var $version;
+ var $helper;
+ var $sentStatus = null;
+
+ function admin_plugin_popularity(){
+ $this->helper = $this->loadHelper('popularity', false);
+
+ $pluginInfo = $this->getInfo();
+ $this->version = $pluginInfo['date'];
+ }
+
+ /**
+ * return prompt for admin menu
+ */
+ function getMenuText($language) {
+ return $this->getLang('name');
+ }
+
+ /**
+ * return sort order for position in admin menu
+ */
+ function getMenuSort() {
+ return 2000;
+ }
+
+ /**
+ * Accessible for managers
+ */
+ function forAdminOnly() {
+ return false;
+ }
+
+
+ /**
+ * handle user request
+ */
+ function handle() {
+ //Send the data
+ if ( isset($_REQUEST['data']) ){
+ $this->sentStatus = $this->helper->sendData( $_REQUEST['data'] );
+ if ( $this->sentStatus === '' ){
+ //Update the last time we sent the data
+ touch ( $this->helper->popularityLastSubmitFile );
+ }
+ //Deal with the autosubmit option
+ $this->_enableAutosubmit( isset($_REQUEST['autosubmit']) );
+ }
+ }
+
+ /**
+ * Enable or disable autosubmit
+ * @param bool $enable If TRUE, it will enable autosubmit. Else, it will disable it.
+ */
+ function _enableAutosubmit( $enable ){
+ if ( $enable ){
+ io_saveFile( $this->helper->autosubmitFile, ' ');
+ } else {
+ @unlink($this->helper->autosubmitFile);
+ }
+ }
+
+ /**
+ * Output HTML form
+ */
+ function html() {
+ if ( ! isset($_REQUEST['data']) ){
+ echo $this->locale_xhtml('intro');
+
+ //If there was an error the last time we tried to autosubmit, warn the user
+ if ( $this->helper->isAutoSubmitEnabled() ){
+ if ( @file_exists($this->helper->autosubmitErrorFile) ){
+ echo $this->getLang('autosubmitError');
+ echo io_readFile( $this->helper->autosubmitErrorFile );
+ }
+ }
+
+ flush();
+ echo $this->buildForm('server');
+
+ //Print the last time the data was sent
+ $lastSent = $this->helper->lastSentTime();
+ if ( $lastSent !== 0 ){
+ echo $this->getLang('lastSent') . ' ' . datetime_h($lastSent);
+ }
+ } else {
+ //If we just submitted the form
+ if ( $this->sentStatus === '' ){
+ //If we successfully sent the data
+ echo $this->locale_xhtml('submitted');
+ } else {
+ //If we failed to submit the data, try directly with the browser
+ echo $this->getLang('submissionFailed') . $this->sentStatus . '<br />';
+ echo $this->getLang('submitDirectly');
+ echo $this->buildForm('browser', $_REQUEST['data']);
+ }
+ }
+ }
+
+
+ /**
+ * Build the form which presents the data to be sent
+ * @param string $submit How is the data supposed to be sent? (may be: 'browser' or 'server')
+ * @param string $data The popularity data, if it has already been computed. NULL otherwise.
+ * @return The form, as an html string
+ */
+ function buildForm($submissionMode, $data = null){
+ $url = ($submissionMode === 'browser' ? $this->helper->submitUrl : script());
+ if ( is_null($data) ){
+ $data = $this->helper->gatherAsString();
+ }
+
+ $form = '<form method="post" action="'. $url .'" accept-charset="utf-8">'
+ .'<fieldset style="width: 60%;">'
+ .'<textarea class="edit" rows="10" cols="80" readonly="readonly" name="data">'
+ .$data
+ .'</textarea><br />';
+
+ //If we submit via the server, we give the opportunity to suscribe to the autosubmission option
+ if ( $submissionMode !== 'browser' ){
+ $form .= '<label for="autosubmit">'
+ .'<input type="checkbox" name="autosubmit" id="autosubmit" '
+ .($this->helper->isAutosubmitEnabled() ? 'checked' : '' )
+ .'/>' . $this->getLang('autosubmit') .'<br />'
+ .'</label>'
+ .'<input type="hidden" name="do" value="admin" />'
+ .'<input type="hidden" name="page" value="popularity" />';
+ }
+ $form .= '<input type="submit" class="button" value="'.$this->getLang('submit').'"/>'
+ .'</fieldset>'
+ .'</form>';
+ return $form;
+ }
+}
diff --git a/lib/plugins/popularity/helper.php b/lib/plugins/popularity/helper.php
new file mode 100644
index 000000000..af1e8a706
--- /dev/null
+++ b/lib/plugins/popularity/helper.php
@@ -0,0 +1,292 @@
+<?php
+/**
+ * Popularity Feedback Plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+class helper_plugin_popularity extends Dokuwiki_Plugin {
+ /**
+ * The url where the data should be sent
+ */
+ var $submitUrl = 'http://update.dokuwiki.org/popularity.php';
+
+ /**
+ * Name of the file which determine if the the autosubmit is enabled,
+ * and when it was submited for the last time
+ */
+ var $autosubmitFile;
+
+ /**
+ * File where the last error which happened when we tried to autosubmit, will be log
+ */
+ var $autosubmitErrorFile;
+
+ /**
+ * Name of the file which determine when the popularity data was manually
+ * submitted for the last time
+ * (If this file doesn't exist, the data has never been sent)
+ */
+ var $popularityLastSubmitFile;
+
+
+ function helper_plugin_popularity(){
+ global $conf;
+ $this->autosubmitFile = $conf['cachedir'].'/autosubmit.txt';
+ $this->autosubmitErrorFile = $conf['cachedir'].'/autosubmitError.txt';
+ $this->popularityLastSubmitFile = $conf['cachedir'].'/lastSubmitTime.txt';
+ }
+
+ function getMethods(){
+ $result = array();
+ $result[] = array(
+ 'name' => 'isAutoSubmitEnabled',
+ 'desc' => 'Check if autosubmit is enabled',
+ 'params' => array(),
+ 'return' => array('result' => 'bool')
+ );
+ $result[] = array(
+ 'name' => 'sendData',
+ 'desc' => 'Send the popularity data',
+ 'params' => array('data' => 'string'),
+ 'return' => array()
+ );
+ $result[] = array(
+ 'name' => 'gatherAsString',
+ 'desc' => 'Gather the popularity data',
+ 'params' => array(),
+ 'return' => array('data' => 'string')
+ );
+ $result[] = array(
+ 'name' => 'lastSentTime',
+ 'desc' => 'Compute the last time popularity data was sent',
+ 'params' => array(),
+ 'return' => array('data' => 'int')
+ );
+ return $result;
+
+ }
+
+ /**
+ * Check if autosubmit is enabled
+ * @return TRUE if we should send data once a month, FALSE otherwise
+ */
+ function isAutoSubmitEnabled(){
+ return @file_exists($this->autosubmitFile);
+ }
+
+ /**
+ * Send the data, to the submit url
+ * @param string $data The popularity data
+ * @return An empty string if everything worked fine, a string describing the error otherwise
+ */
+ function sendData($data){
+ $error = '';
+ $httpClient = new DokuHTTPClient();
+ $status = $httpClient->sendRequest($this->submitUrl, $data, 'POST');
+ if ( ! $status ){
+ $error = $httpClient->error;
+ }
+ return $error;
+ }
+
+ /**
+ * Compute the last time the data was sent. If it has never been sent, we return 0.
+ */
+ function lastSentTime(){
+ $manualSubmission = @filemtime($this->popularityLastSubmitFile);
+ $autoSubmission = @filemtime($this->autosubmitFile);
+
+ return max((int) $manualSubmission, (int) $autoSubmission);
+ }
+
+ /**
+ * Gather all information
+ * @return The popularity data as a string
+ */
+ function gatherAsString(){
+ $data = $this->_gather();
+ $string = '';
+ foreach($data as $key => $val){
+ if(is_array($val)) foreach($val as $v){
+ $string .= hsc($key)."\t".hsc($v)."\n";
+ }else{
+ $string .= hsc($key)."\t".hsc($val)."\n";
+ }
+ }
+ return $string;
+ }
+
+ /**
+ * Gather all information
+ * @return The popularity data as an array
+ */
+ function _gather(){
+ global $conf;
+ global $auth;
+ $data = array();
+ $phptime = ini_get('max_execution_time');
+ @set_time_limit(0);
+
+ // version
+ $data['anon_id'] = md5(auth_cookiesalt());
+ $data['version'] = getVersion();
+ $data['popversion'] = $this->version;
+ $data['language'] = $conf['lang'];
+ $data['now'] = time();
+ $data['popauto'] = (int) $this->isAutoSubmitEnabled();
+
+ // some config values
+ $data['conf_useacl'] = $conf['useacl'];
+ $data['conf_authtype'] = $conf['authtype'];
+ $data['conf_template'] = $conf['template'];
+
+ // number and size of pages
+ $list = array();
+ search($list,$conf['datadir'],array($this,'_search_count'),'','');
+ $data['page_count'] = $list['file_count'];
+ $data['page_size'] = $list['file_size'];
+ $data['page_biggest'] = $list['file_max'];
+ $data['page_smallest'] = $list['file_min'];
+ $data['page_nscount'] = $list['dir_count'];
+ $data['page_nsnest'] = $list['dir_nest'];
+ if($list['file_count']) $data['page_avg'] = $list['file_size'] / $list['file_count'];
+ $data['page_oldest'] = $list['file_oldest'];
+ unset($list);
+
+ // number and size of media
+ $list = array();
+ search($list,$conf['mediadir'],array($this,'_search_count'),array('all'=>true));
+ $data['media_count'] = $list['file_count'];
+ $data['media_size'] = $list['file_size'];
+ $data['media_biggest'] = $list['file_max'];
+ $data['media_smallest'] = $list['file_min'];
+ $data['media_nscount'] = $list['dir_count'];
+ $data['media_nsnest'] = $list['dir_nest'];
+ if($list['file_count']) $data['media_avg'] = $list['file_size'] / $list['file_count'];
+ unset($list);
+
+ // number and size of cache
+ $list = array();
+ search($list,$conf['cachedir'],array($this,'_search_count'),array('all'=>true));
+ $data['cache_count'] = $list['file_count'];
+ $data['cache_size'] = $list['file_size'];
+ $data['cache_biggest'] = $list['file_max'];
+ $data['cache_smallest'] = $list['file_min'];
+ if($list['file_count']) $data['cache_avg'] = $list['file_size'] / $list['file_count'];
+ unset($list);
+
+ // number and size of index
+ $list = array();
+ search($list,$conf['indexdir'],array($this,'_search_count'),array('all'=>true));
+ $data['index_count'] = $list['file_count'];
+ $data['index_size'] = $list['file_size'];
+ $data['index_biggest'] = $list['file_max'];
+ $data['index_smallest'] = $list['file_min'];
+ if($list['file_count']) $data['index_avg'] = $list['file_size'] / $list['file_count'];
+ unset($list);
+
+ // number and size of meta
+ $list = array();
+ search($list,$conf['metadir'],array($this,'_search_count'),array('all'=>true));
+ $data['meta_count'] = $list['file_count'];
+ $data['meta_size'] = $list['file_size'];
+ $data['meta_biggest'] = $list['file_max'];
+ $data['meta_smallest'] = $list['file_min'];
+ if($list['file_count']) $data['meta_avg'] = $list['file_size'] / $list['file_count'];
+ unset($list);
+
+ // number and size of attic
+ $list = array();
+ search($list,$conf['olddir'],array($this,'_search_count'),array('all'=>true));
+ $data['attic_count'] = $list['file_count'];
+ $data['attic_size'] = $list['file_size'];
+ $data['attic_biggest'] = $list['file_max'];
+ $data['attic_smallest'] = $list['file_min'];
+ if($list['file_count']) $data['attic_avg'] = $list['file_size'] / $list['file_count'];
+ $data['attic_oldest'] = $list['file_oldest'];
+ unset($list);
+
+ // user count
+ if($auth && $auth->canDo('getUserCount')){
+ $data['user_count'] = $auth->getUserCount();
+ }
+
+ // calculate edits per day
+ $list = @file($conf['metadir'].'/_dokuwiki.changes');
+ $count = count($list);
+ if($count > 2){
+ $first = (int) substr(array_shift($list),0,10);
+ $last = (int) substr(array_pop($list),0,10);
+ $dur = ($last - $first)/(60*60*24); // number of days in the changelog
+ $data['edits_per_day'] = $count/$dur;
+ }
+ unset($list);
+
+ // plugins
+ $data['plugin'] = plugin_list();
+
+ // pcre info
+ if(defined('PCRE_VERSION')) $data['pcre_version'] = PCRE_VERSION;
+ $data['pcre_backtrack'] = ini_get('pcre.backtrack_limit');
+ $data['pcre_recursion'] = ini_get('pcre.recursion_limit');
+
+ // php info
+ $data['os'] = PHP_OS;
+ $data['webserver'] = $_SERVER['SERVER_SOFTWARE'];
+ $data['php_version'] = phpversion();
+ $data['php_sapi'] = php_sapi_name();
+ $data['php_memory'] = $this->_to_byte(ini_get('memory_limit'));
+ $data['php_exectime'] = $phptime;
+ $data['php_extension'] = get_loaded_extensions();
+
+ return $data;
+ }
+
+ function _search_count(&$data,$base,$file,$type,$lvl,$opts){
+ // traverse
+ if($type == 'd'){
+ if($data['dir_nest'] < $lvl) $data['dir_nest'] = $lvl;
+ $data['dir_count']++;
+ return true;
+ }
+
+ //only search txt files if 'all' option not set
+ if($opts['all'] || substr($file,-4) == '.txt'){
+ $size = filesize($base.'/'.$file);
+ $date = filemtime($base.'/'.$file);
+ $data['file_count']++;
+ $data['file_size'] += $size;
+ if(!isset($data['file_min']) || $data['file_min'] > $size) $data['file_min'] = $size;
+ if($data['file_max'] < $size) $data['file_max'] = $size;
+ if(!isset($data['file_oldest']) || $data['file_oldest'] > $date) $data['file_oldest'] = $date;
+ }
+
+ return false;
+ }
+
+ /**
+ * Convert php.ini shorthands to byte
+ *
+ * @author <gilthans dot NO dot SPAM at gmail dot com>
+ * @link http://de3.php.net/manual/en/ini.core.php#79564
+ */
+ function _to_byte($v){
+ $l = substr($v, -1);
+ $ret = substr($v, 0, -1);
+ switch(strtoupper($l)){
+ case 'P':
+ $ret *= 1024;
+ case 'T':
+ $ret *= 1024;
+ case 'G':
+ $ret *= 1024;
+ case 'M':
+ $ret *= 1024;
+ case 'K':
+ $ret *= 1024;
+ break;
+ }
+ return $ret;
+ }
+}
diff --git a/lib/plugins/popularity/lang/af/lang.php b/lib/plugins/popularity/lang/af/lang.php
new file mode 100644
index 000000000..ab5e4f609
--- /dev/null
+++ b/lib/plugins/popularity/lang/af/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Afrikaans language file
+ *
+ */
+$lang['submit'] = 'Stuir Data';
diff --git a/lib/plugins/popularity/lang/ar/intro.txt b/lib/plugins/popularity/lang/ar/intro.txt
new file mode 100644
index 000000000..a81fede51
--- /dev/null
+++ b/lib/plugins/popularity/lang/ar/intro.txt
@@ -0,0 +1,9 @@
+====== Popularity Feedback ======
+
+تجمع هذه الأداة بيانات مجهولة الاسم وتسمح لك بردها لمطوري دوكو ويكي. يساعدهم ذلك على معرفة كيفية استخدام دوكو ويكي من المستخدمين والتأكد من أن التطويرات المستقبلية مدعومة بتقارير استخدام حقيقية.
+
+نشجعك على تكرار هذه الخطوة من وقت لآخر لابقاء المطورين على علم بنمو الويكي خاصتك. بياناتك المرسلة مكررا ستحتفظ ب ID بلا اسماء يميزها.
+
+البيانات المرسلة تحتوي معلومات مثل اصدار دوكو ويكي، عدد وحجم صفحاتك وملفاتك، الاضافات المركبة و معلومات عن PHP عندك.
+
+البيانات التي سترسل معروضة صرفا أسفله. رجاء استخدم زر "أرسل البيانات" لنقل المعلومات. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ar/lang.php b/lib/plugins/popularity/lang/ar/lang.php
new file mode 100644
index 000000000..481668505
--- /dev/null
+++ b/lib/plugins/popularity/lang/ar/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Arabic language file
+ *
+ * @author Yaman Hokan <always.smile.yh@hotmail.com>
+ * @author Usama Akkad <uahello@gmail.com>
+ * @author uahello@gmail.com
+ */
+$lang['name'] = 'رد الشعبية (قد يأخذ بعض الوقت ليحمل)';
+$lang['submit'] = 'أرسل البيانات';
+$lang['autosubmit'] = 'ارسل البيانات آليا كل شهر';
+$lang['submissionFailed'] = 'تعذر إرسال البيانات بسبب الخطأ التالي:';
+$lang['submitDirectly'] = 'يمكنك إرسال البيانات يدويا بارسال النموذج التالي.';
+$lang['autosubmitError'] = 'فشلت آخر محاولة للإرسال، بسبب الخطأ التالي:';
+$lang['lastSent'] = 'أرسلت البيانات';
diff --git a/lib/plugins/popularity/lang/ar/submitted.txt b/lib/plugins/popularity/lang/ar/submitted.txt
new file mode 100644
index 000000000..085e3bd98
--- /dev/null
+++ b/lib/plugins/popularity/lang/ar/submitted.txt
@@ -0,0 +1,3 @@
+====== رد الشعبية ======
+
+أرسلت البيانات بنجاح. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/bg/intro.txt b/lib/plugins/popularity/lang/bg/intro.txt
new file mode 100644
index 000000000..35023b897
--- /dev/null
+++ b/lib/plugins/popularity/lang/bg/intro.txt
@@ -0,0 +1,9 @@
+====== Обратна връзка ======
+
+Инструментът събира данни за вашето Wiki и ви позволява да ги изпратите да разработчиците на DokuWiki. Информацията ще им помогне да разберат как DokuWiki се ползва от потребителите и че статистиката е в подкрепа на поетата насока за развитие.
+
+Моля, ползвайте функцията, от време на време, когато уебстраницата ви се разраства, за да информирате разработчиците. Изпратените данни ще бъдат идентифицирани с анонимен идентификатор.
+
+Събираните данни съдържат информация като версията на DokuWiki, броя и размера на вашите страници и файлове, инсталирани приставки и информация за локалната инсталация на PHP.
+
+Данните, които ще бъдат изпратени са изобразени отдолу. Моля, натиснете бутона "Изпращане на данните", за да бъдат изпратени. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/bg/lang.php b/lib/plugins/popularity/lang/bg/lang.php
new file mode 100644
index 000000000..ba731c0fc
--- /dev/null
+++ b/lib/plugins/popularity/lang/bg/lang.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Bulgarian language file
+ *
+ * @author Viktor Usunov <usun0v@mail.bg>
+ * @author Kiril <neohidra@gmail.com>
+ */
+$lang['name'] = 'Обратна връзка (зареждането изисква време)';
+$lang['submit'] = 'Изпращане на данните';
+$lang['autosubmit'] = 'Автоматично изпращане на данните веднъж в месеца';
+$lang['submissionFailed'] = 'Данните не могат да бъдат изпратени поради следната грешка:';
+$lang['submitDirectly'] = 'Можете да изпратите данните ръчно чрез следния формуляр.';
+$lang['autosubmitError'] = 'Последното автоматично изпращане се провали, поради следната грешка:';
+$lang['lastSent'] = 'Данните са изпратени';
diff --git a/lib/plugins/popularity/lang/bg/submitted.txt b/lib/plugins/popularity/lang/bg/submitted.txt
new file mode 100644
index 000000000..3ecd24f96
--- /dev/null
+++ b/lib/plugins/popularity/lang/bg/submitted.txt
@@ -0,0 +1,3 @@
+====== Обратна връзка ======
+
+Данните са изпратени успешно. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ca-valencia/intro.txt b/lib/plugins/popularity/lang/ca-valencia/intro.txt
new file mode 100644
index 000000000..cf14e0864
--- /dev/null
+++ b/lib/plugins/popularity/lang/ca-valencia/intro.txt
@@ -0,0 +1,9 @@
+====== Retroalimentació de popularitat ======
+
+Esta ferramenta arreplega senyes anònimes sobre el wiki i permet enviar-les als desenrolladors de DokuWiki. Açò els ajuda a comprendre cóm utilisen DokuWiki els usuaris i assegura que les decisions futures de desenroll estaran recolzades per estadístiques d'us real.
+
+L'animem a que repetixca este procés de tant en tant per a mantindre informats als desenrolladors quan el wiki creixca. Els seus conjunts reiteratius de senyes s'identificaran en un ID anònim.
+
+Les senyes arreplegades contenen informació com la versió del DokuWiki, el número i tamany de les pàgines i els archius, plúgins instalats i informació sobre l'instalació de PHP.
+
+Les senyes reals que s'enviaran es mostren ací avall. Per favor, utilise el botó "Enviar senyes" per a transferir l'informació.
diff --git a/lib/plugins/popularity/lang/ca-valencia/lang.php b/lib/plugins/popularity/lang/ca-valencia/lang.php
new file mode 100644
index 000000000..1bbe5e5f5
--- /dev/null
+++ b/lib/plugins/popularity/lang/ca-valencia/lang.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Valencian language file
+ *
+ * @author Bernat Arlandis <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@llenguaitecnologia.com>
+ */
+$lang['name'] = 'Retro-alimentació de popularitat (pot tardar un poc en carregar)';
+$lang['submit'] = 'Enviar senyes';
diff --git a/lib/plugins/popularity/lang/ca/intro.txt b/lib/plugins/popularity/lang/ca/intro.txt
new file mode 100644
index 000000000..f5ded3f1c
--- /dev/null
+++ b/lib/plugins/popularity/lang/ca/intro.txt
@@ -0,0 +1,9 @@
+====== Retroacció sobre popularitat ======
+
+Aquesta eina recull dades anònimes sobre el vostre wiki i us permet enviar-les als desenvolupadors de DokuWiki. Això els ajudarà a entendre com utilitzen DokuWiki els usuaris i farà que futures decisions de desenvolupament es prenguin sobre la base d'estadístiques d'ús reals.
+
+Els desenvolupadors de DokuWiki us preguen que repetiu aquest pas de tant en tant per tal de mantenir-los ben informats a mesura que creix el vostre wiki. Els conjunts de dades que envieu al llarg del temps quedaran identificats per un ID anònim.
+
+Les dades que es recullen contenen informació com ara la vostra versió de DokuWiki, el nombre i la mida de pàgines i fitxers, els connectors instal·lats i informació sobre la vostra instal·lació de PHP.
+
+Més avall es mostren les dades crues que s'enviaran. Feu servir el botó "Envia dades" per transferir aquesta informació. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ca/lang.php b/lib/plugins/popularity/lang/ca/lang.php
new file mode 100644
index 000000000..e6fdcd533
--- /dev/null
+++ b/lib/plugins/popularity/lang/ca/lang.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Catalan language file
+ *
+ * @author Carles Bellver <carles.bellver@cent.uji.es>
+ * @author Carles Bellver <carles.bellver@gmail.com>
+ * @author carles.bellver@cent.uji.es
+ */
+$lang['name'] = 'Retroacció sobre popularitat (pot trigar una mica a carregar)';
+$lang['submit'] = 'Envia dades';
diff --git a/lib/plugins/popularity/lang/cs/intro.txt b/lib/plugins/popularity/lang/cs/intro.txt
new file mode 100644
index 000000000..4b386568a
--- /dev/null
+++ b/lib/plugins/popularity/lang/cs/intro.txt
@@ -0,0 +1,9 @@
+===== Průzkum používání =====
+
+Tento nástroj jednorázově shromáždí anonymní data o vaší wiki a umožní vám odeslat je vývojářům DokuWiki. To jim pomůže lépe porozumět, jak uživatelé DokuWiki používají, a jejich rozhodnutí při dalším vývoji budou založena na statistikách z reálného používání DokuWiki.
+
+Chcete-li pomoci vývojářům, čas od času, jak vaše wiki poroste, použijte tento nástroj. Vaše data budou pokaždé označena stejným anonymním identifikátorem.
+
+Shromážděná data budou obsahovat informace, jako je instalovaná verze DokuWiki, počet a velikosti stránek a souborů, instalované pluginy a informace o nainstalovaném PHP.
+
+Čistá data, která se odešlou, budou vidět níže. K odeslání informací použijte prosím tlačítko "Odeslat data". \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/cs/lang.php b/lib/plugins/popularity/lang/cs/lang.php
new file mode 100644
index 000000000..287bcf3b0
--- /dev/null
+++ b/lib/plugins/popularity/lang/cs/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Czech language file
+ *
+ * @author Bohumir Zamecnik <bohumir@zamecnik.org>
+ * @author tomas@valenta.cz
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @author Lefty <lefty@multihost.cz>
+ * @author Vojta Beran <xmamut@email.cz>
+ * @author zbynek.krivka@seznam.cz
+ */
+$lang['name'] = 'Průzkum používání (může chviličku trvat, než se natáhne)';
+$lang['submit'] = 'Odeslat data';
+$lang['autosubmit'] = 'Automaticky odesílat data jednou měsíčně';
+$lang['submissionFailed'] = 'Data nemohla být odeslána kvůli následující chybě:';
+$lang['submitDirectly'] = 'Data můžete odeslat ručně zasláním následujícího formuláře.';
+$lang['autosubmitError'] = 'Poslední automatické odeslání selhalo kvůli následující chybě:';
+$lang['lastSent'] = 'Data byla odeslána.';
diff --git a/lib/plugins/popularity/lang/cs/submitted.txt b/lib/plugins/popularity/lang/cs/submitted.txt
new file mode 100644
index 000000000..ff1f41c9f
--- /dev/null
+++ b/lib/plugins/popularity/lang/cs/submitted.txt
@@ -0,0 +1,3 @@
+===== Průzkum používání =====
+
+Data byla úspěšně odeslána. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/da/intro.txt b/lib/plugins/popularity/lang/da/intro.txt
new file mode 100644
index 000000000..e2122c94d
--- /dev/null
+++ b/lib/plugins/popularity/lang/da/intro.txt
@@ -0,0 +1,9 @@
+====== Tilbagemelding om popularitet ======
+
+Dette værktøj samler anonyme oplysninge rom din wiki og giver dig mulighed for at sende det tilbage til DokuWiki-udviklerne. Dette hjælper dem til at sætte sig ind i, hvordan DokuWiki bruges af dets brugere og sikrer, at fremtidige beslutninger inden for udviklingen har grund i faktiske brugsstatistikker.
+
+Vi anbefaler dig til at gentage dette trin fra tid til anden for at holde udviklerne underrettede eftersom din wiki vokser. Dine anonyme datasamlinger vil blive tilkendegivet ved et anonymt navn.
+
+Opsamlede data indeholder oplysninger som eksempelvis din udgave af DokuWiki, antallet og størrelsen af dens sider, tilføjede udvidelse og oplysninger om din PHP-opsætning.
+
+De egentlige data, som vil blive sendt, er vist herunder. Brug venligst knappen 'Send Data' for at videresende oplysningerne. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/da/lang.php b/lib/plugins/popularity/lang/da/lang.php
new file mode 100644
index 000000000..325fd6568
--- /dev/null
+++ b/lib/plugins/popularity/lang/da/lang.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Danish language file
+ *
+ * @author Kalle Sommer Nielsen <kalle@php.net>
+ * @author Esben Laursen <hyber@hyber.dk>
+ * @author Harith <haj@berlingske.dk>
+ * @author Daniel Ejsing-Duun <dokuwiki@zilvador.dk>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author rasmus@kinnerup.com
+ * @author Michael Pedersen subben@gmail.com
+ */
+$lang['name'] = 'Tilbagemelding om popularitet (vil måske tage en del tid at indlæse)';
+$lang['submit'] = 'Send data';
diff --git a/lib/plugins/popularity/lang/de-informal/intro.txt b/lib/plugins/popularity/lang/de-informal/intro.txt
new file mode 100644
index 000000000..ddae9347d
--- /dev/null
+++ b/lib/plugins/popularity/lang/de-informal/intro.txt
@@ -0,0 +1,9 @@
+===== Rückmeldung zur Zufriedenheit =====
+
+Dieses Werkzeug sammelt anonym Daten über dein Wiki und erlaubt es dir diese an die Entwickler von DokuWiki zu senden. Dies hilft ihnen zu verstehen, wie DokuWiki von den Nutzern verwendet wird und stellt somit sicher, dass Entscheidungen für zukünftige Entwicklungen mit reellen Nutzungsstatistiken belegbar sind.
+
+Bitte wiederhole diesen Schritt von Zeit zu Zeit, um die Entwickler zu informieren wenn dein Wiki wächst. Deine aktuelleren Datensätze werden anhand einer anonymen Identifikationsnummer zugeordnet.
+
+Die gesammelten Daten enthalten Informationen über deine Version von DokuWiki, die Anzahl und Größe der Seiten und Dateien, installierte Erweiterungen und Informationen über deine PHP-Version.
+
+Die Rohdaten die gesendet werden, werden unten gezeigt. Bitte nutze den "Sende Daten" Knopf um die Informationen zu übermitteln. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/de-informal/lang.php b/lib/plugins/popularity/lang/de-informal/lang.php
new file mode 100644
index 000000000..40e6c4343
--- /dev/null
+++ b/lib/plugins/popularity/lang/de-informal/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * German (informal) language file
+ *
+ * @author Alexander Fischer <tbanus@os-forge.net>
+ * @author Juergen Schwarzer <jschwarzer@freenet.de>
+ * @author Marcel Metz <marcel_metz@gmx.de>
+ * @author Matthias Schulte <post@lupo49.de>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['name'] = 'Popularitätsrückmeldung (kann eine Weile dauern, bis es fertig geladen wurde)';
+$lang['submit'] = 'Sende Daten';
+$lang['autosubmit'] = 'Daten einmal im Monat automatisch senden';
+$lang['submissionFailed'] = 'Die Daten konnten aufgrund des folgenden Fehlers nicht gesendet werden: ';
+$lang['submitDirectly'] = 'Du kannst die Daten durch Betätigung des Buttons manuell versenden.';
+$lang['autosubmitError'] = 'Beim letzten automatischen Versuch die Daten zu senden, ist folgender Fehler aufgetreten: ';
+$lang['lastSent'] = 'Die Daten wurden gesendet';
diff --git a/lib/plugins/popularity/lang/de-informal/submitted.txt b/lib/plugins/popularity/lang/de-informal/submitted.txt
new file mode 100644
index 000000000..e7b45b5b7
--- /dev/null
+++ b/lib/plugins/popularity/lang/de-informal/submitted.txt
@@ -0,0 +1,3 @@
+====== Popularitäts-Feedback ======
+
+Die Daten wurden erfolgreich versandt. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/de/intro.txt b/lib/plugins/popularity/lang/de/intro.txt
new file mode 100644
index 000000000..dc014e029
--- /dev/null
+++ b/lib/plugins/popularity/lang/de/intro.txt
@@ -0,0 +1,11 @@
+====== Popularitäts-Feedback ======
+
+Dieses [[doku>popularity|Werkzeug]] sammelt verschiedene anonyme Daten über Ihr Wiki und erlaubt es Ihnen, diese an die DokuWiki-Entwickler zurückzusenden. Diese Daten helfen den Entwicklern besser zu verstehen, wie DokuWiki eingesetzt wird und stellt sicher, dass zukünftige, die Weiterentwicklung von DokuWiki betreffende, Entscheidungen auf Basis echter Nutzerdaten getroffen werden.
+
+Bitte wiederholen Sie das Versenden der Daten von Zeit zu Zeit, um die Entwickler über das Wachstum Ihres Wikis auf dem Laufenden zu halten. Ihre wiederholten Dateneinsendungen werden über eine anonyme ID identifiziert.
+
+Die gesammelten Daten enthalten Informationen wie Ihre DokuWiki-Version, die Anzahl und Größe Ihrer Seiten und Dateien, installierte Plugins und die eingesetzte PHP-Installation.
+
+Die zu übertragenen Roh-Daten werden in der untenstehenden Box angezeigt. Bitte drücken Sie die "Daten senden" Schaltfläche um die Information zu übertragen.
+
+
diff --git a/lib/plugins/popularity/lang/de/lang.php b/lib/plugins/popularity/lang/de/lang.php
new file mode 100644
index 000000000..42bdc14d5
--- /dev/null
+++ b/lib/plugins/popularity/lang/de/lang.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * German language file
+ *
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Dirk Einecke <dirk@dirkeinecke.de>
+ * @author Blitzi94@gmx.de
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Niels Lange <niels@boldencursief.nl>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Paul Lachewsky <kaeptn.haddock@gmail.com>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['name'] = 'Popularitäts-Feedback (Eventuell längere Ladezeit)';
+$lang['submit'] = 'Daten senden';
+$lang['autosubmit'] = 'Daten einmal im Monat automatisch senden';
+$lang['submissionFailed'] = 'Die Daten konnten aufgrund des folgenden Fehlers nicht gesendet werden: ';
+$lang['submitDirectly'] = 'Sie können die Daten durch Betätigung des Buttons manuell versenden.';
+$lang['autosubmitError'] = 'Beim letzten automatischen Versuch die Daten zu senden, ist folgender Fehler aufgetreten: ';
+$lang['lastSent'] = 'Die Daten wurden gesendet';
diff --git a/lib/plugins/popularity/lang/de/submitted.txt b/lib/plugins/popularity/lang/de/submitted.txt
new file mode 100644
index 000000000..e7b45b5b7
--- /dev/null
+++ b/lib/plugins/popularity/lang/de/submitted.txt
@@ -0,0 +1,3 @@
+====== Popularitäts-Feedback ======
+
+Die Daten wurden erfolgreich versandt. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/el/intro.txt b/lib/plugins/popularity/lang/el/intro.txt
new file mode 100644
index 000000000..22d54290a
--- /dev/null
+++ b/lib/plugins/popularity/lang/el/intro.txt
@@ -0,0 +1,9 @@
+====== Αναφορά Δημοτικότητας ======
+
+Το εργαλείο αυτό συλλέγει ανώνυμα δεδομένα για το wiki σας και σας επιτρέπει να τα στείλετε στους δημιουργούς της εφαρμογής DokuWiki. Αυτό τους βοηθά να καταλάβουν με ποιούς τρόπους χρησιμοποιείται η εφαρμογή DokuWiki από τους χρήστες της και εξασφαλίζει ότι οι μελλοντικές αποφάσεις σχεδίασης θα στηρίζονται σε πραγματικά δεδομένα χρήσης.
+
+Σας προτρέπουμε να επαναλαμβάνετε αυτή τη διαδικασία κατά διαστήματα ώστε οι δημιουργοί της εφαρμογής DokuWiki να μένουν ενήμεροι όταν το wiki σας μεγαλώνει. Τα διαδοχικά σύνολα δεδομένων που αποστέλλετε αναγνωρίζονται από έναν ανώνυμο κωδικό.
+
+Τα δεδομένα περιέχουν πληροφορίες όπως η έκδοση του DokuWiki σας, ο αριθμός και το μέγεθος των σελίδων και αρχείων σας, οι εγκατεστημένες επεκτάσεις και στοιχεία για την PHP που χρησιμοποιείτε.
+
+Τα ακριβή δεδομένα τα οποία θα αποσταλούν εμφανίζονται παρακάτω. Παρακαλούμε πατήστε στο κουμπί "Αποστολή Δεδομένων" για να τα αποστείλετε. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/el/lang.php b/lib/plugins/popularity/lang/el/lang.php
new file mode 100644
index 000000000..32558b060
--- /dev/null
+++ b/lib/plugins/popularity/lang/el/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Greek language file
+ *
+ * @author Konstantinos Koryllos <koryllos@gmail.com>
+ * @author George Petsagourakis <petsagouris@gmail.com>
+ * @author Petros Vidalis <pvidalis@gmail.com>
+ */
+$lang['name'] = 'Αναφορά Δημοτικότητας (ίσως αργήσει λίγο να εμφανιστεί)';
+$lang['submit'] = 'Αποστολή Δεδομένων';
+$lang['autosubmit'] = 'Να αποστέλονται τα δεδομένα αυτόματα μια φορά το μήνα.';
+$lang['submissionFailed'] = 'Τα δεδομένα δεν ήταν δυνατό να αποσταλλούν λόγω του παρακάτω σφάλματος:';
+$lang['submitDirectly'] = 'Μπορείτε να αποστείλλετε τα δεδομένα χειροκίνητα με την υποβολή της παρακάτω φόρμας.';
+$lang['autosubmitError'] = 'Η τελευταία αυτόματη υποβολή των δεδομένων απέτυχε με το παρακάτω μήνυμα σφάλματος:';
+$lang['lastSent'] = 'Τα δεδομένα έχουν σταλεί.';
diff --git a/lib/plugins/popularity/lang/el/submitted.txt b/lib/plugins/popularity/lang/el/submitted.txt
new file mode 100644
index 000000000..8004f9997
--- /dev/null
+++ b/lib/plugins/popularity/lang/el/submitted.txt
@@ -0,0 +1,3 @@
+====== Αποτέλεσμα Υποβολής Δημοσιότητας ======
+
+Τα δεδομένα στάλθηκαν επιτυχώς. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/en/intro.txt b/lib/plugins/popularity/lang/en/intro.txt
new file mode 100644
index 000000000..e1d6d940a
--- /dev/null
+++ b/lib/plugins/popularity/lang/en/intro.txt
@@ -0,0 +1,11 @@
+====== Popularity Feedback ======
+
+This [[doku>popularity|tool]] gathers anonymous data about your wiki and allows you to send it back to the DokuWiki developers. This helps them to understand them how DokuWiki is used by its users and makes sure future development decisions are backed up by real world usage statistics.
+
+You are encouraged to repeat this step from time to time to keep developers informed when your wiki grows. Your repeated data sets will be identified by an anonymous ID.
+
+Data collected contains information like your DokuWiki version, the number and size of your pages and files, installed plugins and information about your PHP install.
+
+The raw data that will be send is shown below. Please use the "Send Data" button to transfer the information.
+
+
diff --git a/lib/plugins/popularity/lang/en/lang.php b/lib/plugins/popularity/lang/en/lang.php
new file mode 100644
index 000000000..af6797cb2
--- /dev/null
+++ b/lib/plugins/popularity/lang/en/lang.php
@@ -0,0 +1,9 @@
+<?php
+
+$lang['name'] = 'Popularity Feedback (may take some time to load)';
+$lang['submit'] = 'Send Data';
+$lang['autosubmit'] = 'Automatically send data once a month';
+$lang['submissionFailed'] = 'The data couldn\'t be sent due to the following error:';
+$lang['submitDirectly'] = 'You can send the data manually by submitting the following form.';
+$lang['autosubmitError'] = 'The last autosubmit failed, because of the following error: ';
+$lang['lastSent'] = 'The data has been sent';
diff --git a/lib/plugins/popularity/lang/en/submitted.txt b/lib/plugins/popularity/lang/en/submitted.txt
new file mode 100644
index 000000000..30f2784aa
--- /dev/null
+++ b/lib/plugins/popularity/lang/en/submitted.txt
@@ -0,0 +1,3 @@
+====== Popularity Feedback ======
+
+The data has been sent succesfully.
diff --git a/lib/plugins/popularity/lang/eo/intro.txt b/lib/plugins/popularity/lang/eo/intro.txt
new file mode 100644
index 000000000..8d9b3dde8
--- /dev/null
+++ b/lib/plugins/popularity/lang/eo/intro.txt
@@ -0,0 +1,9 @@
+====== Populareca enketo ======
+
+Tiu ĉi ilo prenas anoniman datenaron pri via vikio kaj ebligas al vi sendi ĝin reen al la kodumantoj de DokuWiki. Tio helpas ke ili komprenu kiel DokuWiki estas uzata kaj certigas ke estontaj disvolviĝaj decidoj estos subtenataj de statistikoj pri reala aplikado.
+
+Ni instigas vin ripeti tiun agon iam kaj tiam por teni la disvolvigantojn informitaj, dum via vikio kreskas. Viaj resendotaj datenaroj estos identigitaj per anonima ID.
+
+La kolektita datenaro enhavas informon pri versio de la instalita DokuWiki, nombro kaj grandeco de la paĝoj kaj dosieroj, instalitaj kromaĵoj kaj informoj pri via PHP-sistemo.
+
+La kruda datenaro sendota estas montrita sube. Bonvole uzu la butonon &quot;Sendi datumaron&quot; por transŝuti tiun informaron. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/eo/lang.php b/lib/plugins/popularity/lang/eo/lang.php
new file mode 100644
index 000000000..e992e12ce
--- /dev/null
+++ b/lib/plugins/popularity/lang/eo/lang.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Esperanto language file
+ *
+ * @author Felipo Kastro <fefcas@gmail.com>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Erik Pedersen <erik pedersen@shaw.ca>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert BOGENSCHNEIDER <robog@gmx.de>
+ * @author Robert BOGENSCHNEIDER <bogi@UEA.org>
+ */
+$lang['name'] = 'Populareca enketo (eble la ŝargo prokrastos iomete)';
+$lang['submit'] = 'Sendi datumaron';
+$lang['autosubmit'] = 'Aŭtomate sendi datumaron monate';
+$lang['submissionFailed'] = 'La datumaro ne povis esti sendata pro la jena eraro:';
+$lang['submitDirectly'] = 'Vi povas sendi vi mem la datumaron per la sekva informilo.';
+$lang['autosubmitError'] = 'La lasta aŭtomata sendo malsukcesis, pro la jena eraro:';
+$lang['lastSent'] = 'La datumaro estas sendita';
diff --git a/lib/plugins/popularity/lang/eo/submitted.txt b/lib/plugins/popularity/lang/eo/submitted.txt
new file mode 100644
index 000000000..c2bce4e9f
--- /dev/null
+++ b/lib/plugins/popularity/lang/eo/submitted.txt
@@ -0,0 +1,3 @@
+====== Enketo pri Populareco ======
+
+La datumoj estis senditaj sukcese. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/es/intro.txt b/lib/plugins/popularity/lang/es/intro.txt
new file mode 100644
index 000000000..cc776a398
--- /dev/null
+++ b/lib/plugins/popularity/lang/es/intro.txt
@@ -0,0 +1,10 @@
+====== Retroalimentación (feedback) del plugin Popularity ======
+
+Esta herramienta recopila datos anónimos sobre tu wiki y te permite enviarlos a los desarrolladores de DokuWiki. Esto les ayuda a comprender cómo usan DokuWiki sus usuarios y asegura que las decisiones del desarrollo futuro del programa estén basadas en las estadísticas de uso del mundo real.
+
+Te animamos a repetir este paso de vez en cuando para mantener informados a los desarrolladores a medida que tu wiki crece. Tus paquetes repetidos de datos se identifican por un ID anónimo.
+
+Los datos recopilados contienen información como tu versión de DokuWiki, el número y tamaño de tus páginas y ficheros, plugins instalados e información sobre tu instalación de PHP.
+
+Los datos que se enviarán se muestran más abajo. Por favor, usa el botón "Enviar Datos" para transferir la información.
+
diff --git a/lib/plugins/popularity/lang/es/lang.php b/lib/plugins/popularity/lang/es/lang.php
new file mode 100644
index 000000000..752fb7da4
--- /dev/null
+++ b/lib/plugins/popularity/lang/es/lang.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Spanish language file
+ *
+ * @author oliver@samera.com.py
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Manuel Meco <manuel.meco@gmail.com>
+ * @author VictorCastelan <victorcastelan@gmail.com>
+ * @author Jordan Mero hack.jord@gmail.com
+ * @author Felipe Martinez <metalmartinez@gmail.com>
+ * @author Javier Aranda <internet@javierav.com>
+ * @author Zerial <fernando@zerial.org>
+ * @author Marvin Ortega <maty1206@maryanlinux.com>
+ * @author Daniel Castro Alvarado <dancas2@gmail.com>
+ * @author Fernando J. Gómez <fjgomez@gmail.com>
+ * @author Victor Castelan <victorcastelan@gmail.com>
+ * @author Mauro Javier Giamberardino <mgiamberardino@gmail.com>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ * @author emezeta <emezeta@infoprimo.com>
+ * @author Oscar Ciudad <oscar@jacho.net>
+ * @author Ruben Figols <ruben.figols@gmail.com>
+ */
+$lang['name'] = 'Retroinformación (Feedback) plugin Popularity';
+$lang['submit'] = 'Enviar datos';
+$lang['autosubmit'] = 'Enviar automáticamente datos una vez al mes';
+$lang['submissionFailed'] = 'Los datos no se pudo enviar debido al error siguiente:';
+$lang['submitDirectly'] = 'Puede enviar los datos de forma manual mediante la presentación de la siguiente forma.';
+$lang['autosubmitError'] = 'El último auto no pudo presentar, debido al error siguiente:';
+$lang['lastSent'] = 'Los datos se han enviado';
diff --git a/lib/plugins/popularity/lang/es/submitted.txt b/lib/plugins/popularity/lang/es/submitted.txt
new file mode 100644
index 000000000..bb1754cdd
--- /dev/null
+++ b/lib/plugins/popularity/lang/es/submitted.txt
@@ -0,0 +1,3 @@
+====== Retroinformación Popularity ======
+
+Los datos se han enviado con éxito. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/et/lang.php b/lib/plugins/popularity/lang/et/lang.php
new file mode 100644
index 000000000..ca1410ab0
--- /dev/null
+++ b/lib/plugins/popularity/lang/et/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Estonian language file
+ *
+ * @author kristian.kankainen@kuu.la
+ * @author Rivo Zängov <eraser@eraser.ee>
+ */
diff --git a/lib/plugins/popularity/lang/eu/intro.txt b/lib/plugins/popularity/lang/eu/intro.txt
new file mode 100644
index 000000000..2d2846f1b
--- /dev/null
+++ b/lib/plugins/popularity/lang/eu/intro.txt
@@ -0,0 +1,9 @@
+====== Popularitate Feedback-a ======
+
+Tresna honek datu anonimoak hartzen ditu zure wiki-ari buruz eta hauek DokuWiki garatzaileei bidaltzea ahalbidetzen dizu. Honek, DokuWiki erabiltzaileek nola erabiltzen duten ulertzen laguntzen die, etorkizuneko garapen erabakiak mundu errealeko erabilpen estatistikekin indartuz.
+
+Pauso hau denboran zehar errepikatzera animatzen zaitugu, modu horretan garatzaileak informatuz zure wiki-a handitzen den ahala. Zure datu bidalketak identifikatzaile anonimo batez identifikatuak izango dira.
+
+Jasotako datuek daramaten informazioa DokuWiki bertsioa, zure orri eta fitxategien kopuru eta tamaina, instalatutako plugin-ak, zure PHP instalazioari buruzko informazioa eta antzerako informazioa da.
+
+Bidaliko diren prozesatu gabeko datuak behean erakusten dira. Mesedez, erabili "Datuak Bidali" botoia informazioa bidaltzeko.
diff --git a/lib/plugins/popularity/lang/eu/lang.php b/lib/plugins/popularity/lang/eu/lang.php
new file mode 100644
index 000000000..05e4262de
--- /dev/null
+++ b/lib/plugins/popularity/lang/eu/lang.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Basque language file
+ *
+ * @author Inko Illarramendi <inko.i.a@gmail.com>
+ */
+$lang['name'] = 'Popularitate Feedback-a (denbora dezente iraun dezake kargatzen)';
+$lang['submit'] = 'Datuak Bidali';
+$lang['autosubmit'] = 'Automatikoki bidali informazioa hilabetean behin';
+$lang['submissionFailed'] = 'Informazioa ezin izan da bidali ondorengo errorea dela eta:';
+$lang['submitDirectly'] = 'Informazioa eskuz bidali dezakezu ondorengo formularioa bidaliz.';
+$lang['autosubmitError'] = 'Azken bidalketa automatikoak huts egin zuen ondorengo errorea dela eta:';
+$lang['lastSent'] = 'Informazioa bidalia izan da';
diff --git a/lib/plugins/popularity/lang/eu/submitted.txt b/lib/plugins/popularity/lang/eu/submitted.txt
new file mode 100644
index 000000000..94c81a528
--- /dev/null
+++ b/lib/plugins/popularity/lang/eu/submitted.txt
@@ -0,0 +1,3 @@
+====== Popularitate Feedback-a ======
+
+Informazioa arrakastaz bidalia izan da. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/fa/intro.txt b/lib/plugins/popularity/lang/fa/intro.txt
new file mode 100644
index 000000000..e8521af5f
--- /dev/null
+++ b/lib/plugins/popularity/lang/fa/intro.txt
@@ -0,0 +1,9 @@
+====== بازخورد محبوبیت ======
+
+این ابزار اطلاعات ناشناسی از ویکی شما را برای توسعه‌دهندگان DokuWiki ارسال می‌کند. این اطلاعات به توسعه‌دهندگان کمک می‌کند تا بفهمند کاربران DokuWiki از آن چگونه استفاده می‌کنند تا بتوانند در نسخه‌های آتی، تصمیمات بهتری اتخاذ کنند.
+
+ما امیدواریم شما این حرکت را در زمان‌های مختلف که ویکی‌تان بزرگ‌تر شد، انجام دهید و این اطلاعات ناشناس ارسال خواهد شد.
+
+اطلاعات جمع‌آوری شده حامل اطلاعاتی مثل نسخه‌ی DokuWiki، تعداد و حجم صفحات و فایل‌ها، افزونه‌های نصب شده و اطلاعات PHP سرور می‌باشد.
+
+اطلاعات خامی که ارسال می‌شود در زیر آمده است. خواهشمندیم از دکمه‌ی «ارسال اطلاعات» برای فرستاده شدن استفاده کنید. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/fa/lang.php b/lib/plugins/popularity/lang/fa/lang.php
new file mode 100644
index 000000000..70c65f1b3
--- /dev/null
+++ b/lib/plugins/popularity/lang/fa/lang.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Persian language file
+ *
+ * @author behrad eslamifar <behrad_es@yahoo.com)
+ * @author Mohsen Firoozmandan <info@mambolearn.com>
+ * @author omidmr@gmail.com
+ * @author Omid Mottaghi <omidmr@gmail.com>
+ * @author Mohammad Reza Shoaei <shoaei@gmail.com>
+ */
+$lang['name'] = 'بازخورد محبوبیت (ممکن است اندکی زمان ببرد)';
+$lang['submit'] = 'ارسال اطلاعات';
+$lang['autosubmit'] = 'ارسال خودکار اطلاعات به صورت ماهیانه';
+$lang['submissionFailed'] = 'اطلاعات به علت بروز خطای زیر قابل ارسال نیستند:';
+$lang['submitDirectly'] = 'شما میتوانید اطلاعات را با تکمیل این فرم به صورت دستی ارسال کنید.';
+$lang['autosubmitError'] = 'آخرین ارسال خودکار با خطای مواجه شد, به علت زیر:';
+$lang['lastSent'] = 'اطلاعات ارسال شد.';
diff --git a/lib/plugins/popularity/lang/fa/submitted.txt b/lib/plugins/popularity/lang/fa/submitted.txt
new file mode 100644
index 000000000..63eec47ba
--- /dev/null
+++ b/lib/plugins/popularity/lang/fa/submitted.txt
@@ -0,0 +1,2 @@
+====== بازخورد محبوبیت ======
+اطلاعات ارسال شد. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/fi/intro.txt b/lib/plugins/popularity/lang/fi/intro.txt
new file mode 100644
index 000000000..f68c2b8e1
--- /dev/null
+++ b/lib/plugins/popularity/lang/fi/intro.txt
@@ -0,0 +1,9 @@
+====== Suosion palaute ======
+
+Tämä työkalu kerää tietoja wikistäsi ilman tunnistetietoja, jotka voit lähettää DokuWikin kehittäjille. Tämä auttaa heitä ymmärtämään, kuinka DokuWikiä käytetään ja varmistaa, että tulevaisuuden kehityspäätökset tehdään tosielämän käyttökokemusten perusteella.
+
+Toivomme sinun toistavan tämän aiheen silloin tällöin, jotta kehittäjät pysyvät tietoisina, miten wikisi kehittyy. Uudelleenlähettämäsi tiedot identifioidaan tunnisteella, jota ei voida jäljittää takaisin sinuun.
+
+Kerätty tieto pitää sisällään tietoa esimerkiksi DokuWikisi versiosta, sivujen koosta ja lukumäärästä, asennetuista liitännäisistä, sekä PHP asennuksestasi.
+
+Raaka tieto, joka lähetetään näkyy alla. Lähetä tieto painamalla "Lähetä tiedot" nappia. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/fi/lang.php b/lib/plugins/popularity/lang/fi/lang.php
new file mode 100644
index 000000000..d7c230742
--- /dev/null
+++ b/lib/plugins/popularity/lang/fi/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Finnish language file
+ *
+ * @author Otto Vainio <otto@valjakko.net>
+ * @author Teemu Mattila <ghcsystems@gmail.com>
+ * @author Sami Olmari <sami@olmari.fi>
+ */
+$lang['name'] = 'Suosion palaute (voi kestää jonkun aikaa latautua)';
+$lang['submit'] = 'Lähetä tiedot';
+$lang['autosubmit'] = 'Lähetä tiedot automaattisesti kerran kuussa';
+$lang['submissionFailed'] = 'Tietoja ei voitu lähettää seuraavan virheen vuoksi:';
+$lang['submitDirectly'] = 'Voit lähettää tiedot käsin seuraavan kaavakkeen avulla';
+$lang['autosubmitError'] = 'Edellinen automaattilähetys epäonnistui seuraavan virheen vuoksi:';
+$lang['lastSent'] = 'Tiedot on lähetetty';
diff --git a/lib/plugins/popularity/lang/fi/submitted.txt b/lib/plugins/popularity/lang/fi/submitted.txt
new file mode 100644
index 000000000..31059c880
--- /dev/null
+++ b/lib/plugins/popularity/lang/fi/submitted.txt
@@ -0,0 +1,3 @@
+====== Suosion palaute ======
+
+Tiedot lähetettiin onnistuneesti. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/fr/intro.txt b/lib/plugins/popularity/lang/fr/intro.txt
new file mode 100644
index 000000000..041e65d69
--- /dev/null
+++ b/lib/plugins/popularity/lang/fr/intro.txt
@@ -0,0 +1,10 @@
+====== Enquête de popularité ======
+
+Cet [[doku>popularity|outil]] collecte des données anonymes concernant votre wiki et vous permet de les expédier aux développeurs de DokuWiki. Ceci leur permet de mieux comprendre comment DokuWiki est employé par ses utilisateurs et d'orienter les décisions sur les développements futurs en tenant compte des statistiques d'usage réel.
+
+Vous êtes encouragé à répéter l'opération de collecte et d'envoi des données anonymes de temps en temps afin d'informer les développeurs de la croissance de votre wiki.
+
+Les données collectées contiennent des informations telle que votre version de DokuWiki, le nombre et la taille de vos pages et fichiers, les modules installés ainsi que des informations sur la version de PHP installée.
+
+Les données brutes qui sont envoyées sont affichées ci dessous. Merci d'utiliser le bouton « Envoyer les données » pour expédier l'information.
+
diff --git a/lib/plugins/popularity/lang/fr/lang.php b/lib/plugins/popularity/lang/fr/lang.php
new file mode 100644
index 000000000..9ff7a7e8b
--- /dev/null
+++ b/lib/plugins/popularity/lang/fr/lang.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * French language file
+ *
+ * @author Guy Brand <gb@unistra.fr>
+ * @author stephane.gully@gmail.com
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author olivier duperray <duperray.olivier@laposte.net>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author Philippe Bajoit <philippe.bajoit@gmail.com>
+ * @author Florian Gaub <floriang@floriang.net>
+ * @author Samuel Dorsaz samuel.dorsaz@novelion.net
+ * @author Johan Guilbaud <guilbaud.johan@gmail.com>
+ * @author schplurtz@laposte.net
+ * @author skimpax@gmail.com
+ */
+$lang['name'] = 'Enquête de popularité (peut nécessiter un certain temps pour être chargée)';
+$lang['submit'] = 'Envoyer les données';
+$lang['autosubmit'] = 'Envoyer les données automatiquement chaque mois';
+$lang['submissionFailed'] = 'Les données ne peuvent pas être envoyées à cause des erreurs suivantes :';
+$lang['submitDirectly'] = 'Vous pouvez envoyer le données manuellement en soumettant ce formulaire.';
+$lang['autosubmitError'] = 'La dernière soumission automatique a échoué pour les raisons suivantes :';
+$lang['lastSent'] = 'Les données ont été envoyées ';
diff --git a/lib/plugins/popularity/lang/fr/submitted.txt b/lib/plugins/popularity/lang/fr/submitted.txt
new file mode 100644
index 000000000..0bc4cfe71
--- /dev/null
+++ b/lib/plugins/popularity/lang/fr/submitted.txt
@@ -0,0 +1,2 @@
+====== Enquête de popularité ======
+Les données ont été envoyées avec succès. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/gl/intro.txt b/lib/plugins/popularity/lang/gl/intro.txt
new file mode 100644
index 000000000..72f03e012
--- /dev/null
+++ b/lib/plugins/popularity/lang/gl/intro.txt
@@ -0,0 +1,10 @@
+====== Resposta de Popularidade ======
+
+Esta ferramenta recolle datos anónimos verbo do teu wiki e permíteche enviarllos aos desenvolvedores do DokuWiki. Isto axudaralles a ter unha idea do xeito en que se emprega o DokuWiki por parte dos seus usuarios, e asegura que as decisións de desenvolvemento futuro coincidan coas estatísticas de uso no mundo real.
+
+Animámoste a levar a cabo este proceso de cando en vez para manteres informados aos desenvolvedores a medida que o teu wiki vaia medrando. Os teus xogos de datos repetidos seran identificados por un ID anónimo.
+
+Os datos recompilados conteñen información como a versión do teu Dokuwiki, o número e tamaño das túas páxinas e arquivos, as extensións instaladas e información verbo da túa instalación do PHP.
+
+Os datos en bruto que serán enviados amósanse embaixo. Por favor, emprega o botón "Enviar Datos" para transferires a información.
+
diff --git a/lib/plugins/popularity/lang/gl/lang.php b/lib/plugins/popularity/lang/gl/lang.php
new file mode 100644
index 000000000..34bd3935f
--- /dev/null
+++ b/lib/plugins/popularity/lang/gl/lang.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Galician language file
+ *
+ * @author Medúlio <medulio@ciberirmandade.org>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ */
+$lang['name'] = 'Resposta de Popularidade (pode demorar un tempo a cargar)';
+$lang['submit'] = 'Enviar Datos';
+$lang['autosubmit'] = 'Enviar datos automáticamente unha vez por mes';
+$lang['submissionFailed'] = 'Os datos non se poden enviar debido ao seguinte erro:';
+$lang['submitDirectly'] = 'Podes enviar os datos de forma manual co seguinte formulario.';
+$lang['autosubmitError'] = 'O último envío automático fallou debido ao seguinte erro:';
+$lang['lastSent'] = 'Os datos foron enviados';
diff --git a/lib/plugins/popularity/lang/gl/submitted.txt b/lib/plugins/popularity/lang/gl/submitted.txt
new file mode 100644
index 000000000..0dec55eef
--- /dev/null
+++ b/lib/plugins/popularity/lang/gl/submitted.txt
@@ -0,0 +1,3 @@
+====== Resposta de Popularidade ======
+
+Os datos foron enviados satisfactoriamente. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/he/intro.txt b/lib/plugins/popularity/lang/he/intro.txt
new file mode 100644
index 000000000..1f2e318f7
--- /dev/null
+++ b/lib/plugins/popularity/lang/he/intro.txt
@@ -0,0 +1,9 @@
+====== משוב פופלריות ======
+
+כלי זה אוסף מידע אנונימי אודות הויקי שלך ומאפשר לך לשלוח אותו חזרה למפתחי דוקוויקי. מידע זה יסיע להם להבין את השימוש שעושים משתמשי דוקוויקי במערכת ויבטיח שהחלטות עתידיות לגבי הפיתוח יתבססו על סטטיסטיקות שימוש אמיתי.
+
+נודה אם תחזור על הפעולה מהעת לעת כדי לודא המפתחים מיודעים כשהויקי שלך גדל. המידע שישלח יזוהה על ידי תג אנונימי.
+
+המידע שנאסף כולל פרטים כמו גרסת הדוקוויקי, מספר וגודל הדפים והקבצים שלך, הרחבות מותקנות ומידע אודות התקנת ה-PHP שלך.
+
+המידע הגולמי שישלח מופיע מטה. נא השתמש בכפתור "שלח מידע" כדי להעבירו. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/he/lang.php b/lib/plugins/popularity/lang/he/lang.php
new file mode 100644
index 000000000..f619127cd
--- /dev/null
+++ b/lib/plugins/popularity/lang/he/lang.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Hebrew language file
+ *
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ * @author Moshe Kaplan <mokplan@gmail.com>
+ * @author Yaron Yogev <yaronyogev@gmail.com>
+ * @author Yaron Shahrabani <sh.yaron@gmail.com>
+ */
+$lang['name'] = 'משוב פופולריות (יתכן זמן טעינה ארוך)';
+$lang['submit'] = 'שלח מידע';
diff --git a/lib/plugins/popularity/lang/hi/lang.php b/lib/plugins/popularity/lang/hi/lang.php
new file mode 100644
index 000000000..c0085d72a
--- /dev/null
+++ b/lib/plugins/popularity/lang/hi/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Hindi language file
+ *
+ * @author Abhinav Tyagi <abhinavtyagi11@gmail.com>
+ * @author yndesai@gmail.com
+ */
+$lang['submit'] = 'डेटा भेजे';
diff --git a/lib/plugins/popularity/lang/hr/lang.php b/lib/plugins/popularity/lang/hr/lang.php
new file mode 100644
index 000000000..96f1d6afe
--- /dev/null
+++ b/lib/plugins/popularity/lang/hr/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Croatian language file
+ *
+ * @author Branko Rihtman <theney@gmail.com>
+ * @author Dražen Odobašić <dodobasic@gmail.com>
+ * @author Dejan Igrec dejan.igrec@gmail.com
+ */
diff --git a/lib/plugins/popularity/lang/hu/intro.txt b/lib/plugins/popularity/lang/hu/intro.txt
new file mode 100644
index 000000000..17bb6fc6f
--- /dev/null
+++ b/lib/plugins/popularity/lang/hu/intro.txt
@@ -0,0 +1,9 @@
+====== Visszajelzés a DokuWiki használatáról ======
+
+Ez az eszköz anonimizált adatokat gyűjt a wikidről, és lehetővé teszi, hogy elküldd a DokuWiki fejlesztőinek. Ez segít meglátni, hogy a felhasználók hogyan használják a DokuWikijüket, ezáltal biztosítja, hogy a későbbi fejlesztési döntések hátterében valós használati statisztikák álljanak.
+
+Szeretnénk megkérni, hogy időről időre ismételd meg ezt a műveletet, hogy a fejlesztők értesülhessenek, hogyan nő a wikid mérete. Az ismételt adatküldéseid egy anoním ID-vel lesznek azonosítva.
+
+Ilyen és hasonló információkat gyűjtünk: DokuWiki verziószáma, a lapok, fájlok mérete és darabszáma, feltelepített bővítmények, PHP installáció adatai.
+
+Az elküldendő nyers adat lent látható. Kérjük, az "Adatok elküldése" gombbal juttasd el hozzánk!
diff --git a/lib/plugins/popularity/lang/hu/lang.php b/lib/plugins/popularity/lang/hu/lang.php
new file mode 100644
index 000000000..5dcd1adf0
--- /dev/null
+++ b/lib/plugins/popularity/lang/hu/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Hungarian language file
+ *
+ * @author Sandor TIHANYI <stihanyi+dw@gmail.com>
+ * @author Siaynoq Mage <siaynoqmage@gmail.com>
+ * @author schilling.janos@gmail.com
+ * @author Szabó Dávid <szabo.david@gyumolcstarhely.hu>
+ * @author Sándor TIHANYI <stihanyi+dw@gmail.com>
+ * @author David Szabo <szabo.david@gyumolcstarhely.hu>
+ */
+$lang['name'] = 'Visszajelzés a DokuWiki használatáról (sok időt vehet igénybe a betöltése)';
+$lang['submit'] = 'Adatok elküldése';
+$lang['autosubmit'] = 'Adatok havonkénti automatikus elküldése.';
+$lang['submissionFailed'] = 'Az adatok a következő hiba miatt nem kerültek elküldésre:';
+$lang['submitDirectly'] = 'Az adatokat a következő űrlap segítségével lehet elküldeni.';
+$lang['autosubmitError'] = 'Az adatok a következő hiba miatt nem kerültek automatikusan elküldésre:';
+$lang['lastSent'] = 'Az adatokat elküldtük.';
diff --git a/lib/plugins/popularity/lang/hu/submitted.txt b/lib/plugins/popularity/lang/hu/submitted.txt
new file mode 100644
index 000000000..30ab8bd8e
--- /dev/null
+++ b/lib/plugins/popularity/lang/hu/submitted.txt
@@ -0,0 +1,3 @@
+====== Visszajelzés a DokuWiki használatáról ======
+
+Az adatokat sikeresen elküldtük. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ia/intro.txt b/lib/plugins/popularity/lang/ia/intro.txt
new file mode 100644
index 000000000..d31c3653f
--- /dev/null
+++ b/lib/plugins/popularity/lang/ia/intro.txt
@@ -0,0 +1,9 @@
+====== Datos de popularitate ======
+
+Iste instrumento collige datos anonyme super tu wiki e te permitte inviar los retro al disveloppatores de DokuWiki. Isto les adjuta de comprender como DokuWiki es usate per su usatores e assecura que le decisiones super le disveloppamento futur si basate super statisticas de uso ex le mundo real.
+
+Tu es incoragiate a repeter iste procedura de tempore a tempore pro continuar a informar le disveloppatores quando tu wiki cresce. Tu collectiones repetite de datos essera identificate per un ID anonyme.
+
+Le datos colligite contine informationes como tu version de DokuWiki, le numero e dimension de tu paginas e files, plug-ins installate e information super tu installation de PHP.
+
+Le datos crude que essera inviate es monstrate hic infra. Per favor usa le button "Inviar datos" pro transferer le informationes. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ia/lang.php b/lib/plugins/popularity/lang/ia/lang.php
new file mode 100644
index 000000000..4a45f04f3
--- /dev/null
+++ b/lib/plugins/popularity/lang/ia/lang.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Interlingua language file
+ *
+ * @author robocap <robocap1@gmail.com>
+ * @author Martijn Dekker <martijn@inlv.org>
+ */
+$lang['name'] = 'Datos de popularitate (pote prender alcun tempore pro cargar)';
+$lang['submit'] = 'Inviar datos';
diff --git a/lib/plugins/popularity/lang/id-ni/intro.txt b/lib/plugins/popularity/lang/id-ni/intro.txt
new file mode 100644
index 000000000..fb2370935
--- /dev/null
+++ b/lib/plugins/popularity/lang/id-ni/intro.txt
@@ -0,0 +1,7 @@
+====== Popularitas-Fangombakha ======
+
+Fakake anonyme da'e i'owuloi ngawalö data moroi ba Wiki khöu awö wanehegöu wama'ohe'ö DokuWiki ba zangahaogö. Data da'e aoha wangehaogö ba wombohouni mangawuli ba DokuWiki ba biziso miföna abölö aoha wangirö'ö ya'ia bakha ba nahia wamake statistik.
+
+Tola öfa'ohe'ö mangawuli data ero-ero soginötö ba wangehaogö ba bawamohouni Wiki khöndra samazökhi. Data nifa'ohe'öu ifareso dania anonyme ID.
+
+...
diff --git a/lib/plugins/popularity/lang/id-ni/lang.php b/lib/plugins/popularity/lang/id-ni/lang.php
new file mode 100644
index 000000000..d9a36f203
--- /dev/null
+++ b/lib/plugins/popularity/lang/id-ni/lang.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * idni language file
+ *
+ * @author Harefa <fidelis@harefa.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
+$lang['name'] = 'Sabölö teturia (sito\'ölönia ara ginötö wamokai)';
+$lang['submit'] = 'Fa\'ohe\'ö data';
diff --git a/lib/plugins/popularity/lang/id/lang.php b/lib/plugins/popularity/lang/id/lang.php
new file mode 100644
index 000000000..1867f0f69
--- /dev/null
+++ b/lib/plugins/popularity/lang/id/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Indonesian language file
+ *
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/popularity/lang/is/lang.php b/lib/plugins/popularity/lang/is/lang.php
new file mode 100644
index 000000000..9add4cae4
--- /dev/null
+++ b/lib/plugins/popularity/lang/is/lang.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Icelandic language file
+ *
+ * @author Hrannar Baldursson <hrannar.baldursson@gmail.com>
+ * @author Ólafur Gunnlaugsson <oli@audiotools.com>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ */
+$lang['submit'] = 'Senda gögn';
diff --git a/lib/plugins/popularity/lang/it/intro.txt b/lib/plugins/popularity/lang/it/intro.txt
new file mode 100644
index 000000000..f65310a5a
--- /dev/null
+++ b/lib/plugins/popularity/lang/it/intro.txt
@@ -0,0 +1,9 @@
+====== Raccolta dati sul wiki ======
+
+Questo strumento raccoglie dati anonimi sul tuo wiki e ti permette di inviarli agli sviluppatori di Dokuwiki. Questo aiuta loro a capire come Dokuwiki viene utilizzato dagli utenti e prendere decisioni future sullo sviluppo in base a quelle che sono le reali statistiche di utilizzo da parte degli utenti.
+
+Ti incoraggiamo a ripetere ogni tanto questa operazione per mantenere informati gli sviluppatori sulla crescita del tuo wiki. L'insieme dei dati raccolti saranno identificati tramite un ID anonimo.
+
+I dati raccolti contengono informazioni come la versione di DokuWiki, il numero e le dimensioni delle pagine e dei file, i plugin installati e informazioni sulla versione di PHP presente nel sistema.
+
+A continuazione puoi vedere un'anteprima dei dati che saranno inviati. Utilizza il pulsante "Invia dati" per trasferire le informazioni. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/it/lang.php b/lib/plugins/popularity/lang/it/lang.php
new file mode 100644
index 000000000..a7852f22c
--- /dev/null
+++ b/lib/plugins/popularity/lang/it/lang.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Italian language file
+ *
+ * @author Diego Pierotto ita.translations@tiscali.it
+ * @author ita.translations@tiscali.it
+ * @author Lorenzo Breda <lbreda@gmail.com>
+ * @author snarchio@alice.it
+ * @author robocap <robocap1@gmail.com>
+ * @author Osman Tekin osman.tekin93@hotmail.it
+ * @author Jacopo Corbetta <jacopo.corbetta@gmail.com>
+ */
+$lang['name'] = 'Raccolta dati sul wiki (può impiegare del tempo per caricarsi)';
+$lang['submit'] = 'Invia dati';
+$lang['autosubmit'] = 'Invia automaticamente i dati una volta al mese';
+$lang['submissionFailed'] = 'È stato impossibile inviare i dati a causa del seguente errore:';
+$lang['submitDirectly'] = 'È possibile inviare i dati manualmente utilizzando il pulsante sottostante.';
+$lang['autosubmitError'] = 'L\'ultimo invio automatico non è andato a buon fine a causa del seguente errore:';
+$lang['lastSent'] = 'I dati sono stati inviati';
diff --git a/lib/plugins/popularity/lang/it/submitted.txt b/lib/plugins/popularity/lang/it/submitted.txt
new file mode 100644
index 000000000..78247154e
--- /dev/null
+++ b/lib/plugins/popularity/lang/it/submitted.txt
@@ -0,0 +1,3 @@
+====== Raccolta dati sul wiki ======
+
+I dati sono stati inviati correttamente. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ja/intro.txt b/lib/plugins/popularity/lang/ja/intro.txt
new file mode 100644
index 000000000..09886f418
--- /dev/null
+++ b/lib/plugins/popularity/lang/ja/intro.txt
@@ -0,0 +1,9 @@
+====== 利用状況調査 ======
+
+このツールは、ご利用中のwikiの情報を収集し、それをDokuWikiの開発者へ匿名で送信するものです。開発者はこのツールにより、DokuWikiが実際にどの様に利用されているかを理解し、そして実際の利用状況に基づいて今後の開発方針の決定することができます。
+
+お使いのwikiの規模が大きくなってきたときは、このステップを定期的に繰り返すことを推奨しています。また、送信されたデータは匿名のIDで識別されます。
+
+DokuWikiのバージョン、ページとファイルの数とサイズ、インストール済みプラグイン、そしてお使いのPHPに関する情報が、送信されるデータに含まれます。
+
+以下に表示されているデータが実際に送信されるデータとなります。"データ送信"ボタンを押して情報を送信してください。 \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ja/lang.php b/lib/plugins/popularity/lang/ja/lang.php
new file mode 100644
index 000000000..736924bb1
--- /dev/null
+++ b/lib/plugins/popularity/lang/ja/lang.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Japanese language file
+ *
+ * @author Ikuo Obataya <i.obataya@gmail.com>
+ * @author Daniel Dupriest <kououken@gmail.com>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ * @author Yuji Takenaka <webmaster@davilin.com>
+ */
+$lang['name'] = '利用状況調査(ロードに少し時間が掛かります)';
+$lang['submit'] = 'データ送信';
+$lang['autosubmit'] = '月に一度は自動的にデータを送付';
+$lang['submissionFailed'] = '次のエラーによりデータが送信できませんでした:';
+$lang['submitDirectly'] = '次のフォームを使ってデータを手動で送信することができます。';
+$lang['autosubmitError'] = '以下のエラーにより最後の自動送信に失敗しました:';
+$lang['lastSent'] = 'データを送信しました。';
diff --git a/lib/plugins/popularity/lang/ja/submitted.txt b/lib/plugins/popularity/lang/ja/submitted.txt
new file mode 100644
index 000000000..604f8e55f
--- /dev/null
+++ b/lib/plugins/popularity/lang/ja/submitted.txt
@@ -0,0 +1,3 @@
+====== 利用状況調査 ======
+
+データの送信に成功しました。 \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/kk/lang.php b/lib/plugins/popularity/lang/kk/lang.php
new file mode 100644
index 000000000..dde5b9577
--- /dev/null
+++ b/lib/plugins/popularity/lang/kk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * kazakh language file
+ *
+ * @author Nurgozha Kaliaskarov astana08@gmail.com
+ */
diff --git a/lib/plugins/popularity/lang/ko/intro.txt b/lib/plugins/popularity/lang/ko/intro.txt
new file mode 100644
index 000000000..e979b71d5
--- /dev/null
+++ b/lib/plugins/popularity/lang/ko/intro.txt
@@ -0,0 +1,9 @@
+====== 인기도 조사 ======
+
+설치된 위키의 익명 정보를 DokuWiki 개발자들에게 보냅니다. 이 기능은 DokuWiki가 실제 사용자들에게 어떻게 사용되는지 DokuWiki 개발자들에게 알려줌으로써 이 후 개발 시 참고가 됩니다.
+
+설치된 위키가 커짐에 따라서 이 과정을 반복할 필요가 있습니다. 반복된 데이타는 익명 ID로 구별되어집니다.
+
+전송 데이타는 설치 DokuWiki 버전, 페이지와 파일 수, 크기, 설치 플러그인, 설치 PHP 정보등을 포함하고 있습니다.
+
+실제 보내질 자료는 아래와 같습니다. 정보를 보내려면 "자료 보내기" 버튼을 클릭합니다.
diff --git a/lib/plugins/popularity/lang/ko/lang.php b/lib/plugins/popularity/lang/ko/lang.php
new file mode 100644
index 000000000..0f1442d53
--- /dev/null
+++ b/lib/plugins/popularity/lang/ko/lang.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Korean language file
+ *
+ * @author jk lee
+ * @author dongnak@gmail.com
+ * @author Song Younghwan <purluno@gmail.com>
+ * @author SONG Younghwan <purluno@gmail.com>
+ * @author Seung-Chul Yoo <dryoo@live.com>
+ */
+$lang['name'] = '인기도 조사 (불러오는데 시간이 걸릴 수 있습니다.)';
+$lang['submit'] = '자료 보내기';
+$lang['autosubmit'] = '자료를 자동으로 매달 한번씩 보내기';
+$lang['submissionFailed'] = '다음과 같은 이유로 자료 전송에 실패했습니다 :';
+$lang['submitDirectly'] = '아래의 양식에 맞춰 수동으로 작성된 자료를 보낼 수 있습니다';
+$lang['autosubmitError'] = '다음과 같은 이유로 자동 자료 전송에 실패했습니다 :';
+$lang['lastSent'] = '자료가 전송되었습니다';
diff --git a/lib/plugins/popularity/lang/ko/submitted.txt b/lib/plugins/popularity/lang/ko/submitted.txt
new file mode 100644
index 000000000..e8b434dc5
--- /dev/null
+++ b/lib/plugins/popularity/lang/ko/submitted.txt
@@ -0,0 +1,3 @@
+====== 인기도 조사 ======
+
+자료 전송이 성공적으로 완료되었습니다 \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/la/intro.txt b/lib/plugins/popularity/lang/la/intro.txt
new file mode 100644
index 000000000..c3029caf4
--- /dev/null
+++ b/lib/plugins/popularity/lang/la/intro.txt
@@ -0,0 +1,10 @@
+====== Index Fauoris Popularis ======
+
+Haoc instrumentum fauorem popularem mittis sic ut creatores uicis meliorem illum facere possint.
+
+Rursum te fauorem mittere experamus sic ut si mutationes meliores uel peiores esse uidere possimus.
+
+Res mittendae tua forma in usu, numerus et pondus paginarum et aliarum rerum, addenda in usu et de PHP.
+
+Res rudes mittendae subter ostenduntur. "Res mittere" premas ut eas transferas.
+
diff --git a/lib/plugins/popularity/lang/la/lang.php b/lib/plugins/popularity/lang/la/lang.php
new file mode 100644
index 000000000..c7f307c29
--- /dev/null
+++ b/lib/plugins/popularity/lang/la/lang.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Latin language file
+ *
+ * @author Massimiliano Vassalli <vassalli.max@gmail.com>
+ */
+$lang['name'] = 'Index fauoris popularis (multum tempus quaerere potest)';
+$lang['submit'] = 'Missum die';
+$lang['autosubmit'] = 'Constanter res omni mense mittuntur';
+$lang['submissionFailed'] = 'Res non mittuntur ea causa:';
+$lang['submitDirectly'] = 'Res tu mittere potes cum hoc exemplar compleas.';
+$lang['autosubmitError'] = 'Extrema missio lapsa est ea causa:';
+$lang['lastSent'] = 'Res missae sunt';
diff --git a/lib/plugins/popularity/lang/la/submitted.txt b/lib/plugins/popularity/lang/la/submitted.txt
new file mode 100644
index 000000000..2b2faf439
--- /dev/null
+++ b/lib/plugins/popularity/lang/la/submitted.txt
@@ -0,0 +1,3 @@
+====== Index fauoris popularis ======
+
+Res feliciter missae sunt. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/lb/lang.php b/lib/plugins/popularity/lang/lb/lang.php
new file mode 100644
index 000000000..59acdf7a8
--- /dev/null
+++ b/lib/plugins/popularity/lang/lb/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * lb language file
+ *
+ * @author joel@schintgen.net
+ */
diff --git a/lib/plugins/popularity/lang/lt/lang.php b/lib/plugins/popularity/lang/lt/lang.php
new file mode 100644
index 000000000..88df29c50
--- /dev/null
+++ b/lib/plugins/popularity/lang/lt/lang.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Lithuanian language file
+ *
+ * @author audrius.klevas@gmail.com
+ * @author Arunas Vaitekunas <aras@fan.lt>
+ */
+$lang['name'] = 'Populiarumo apklausa (gali užtrukti pakrovimas)';
+$lang['submit'] = 'Pateikti';
diff --git a/lib/plugins/popularity/lang/lv/intro.txt b/lib/plugins/popularity/lang/lv/intro.txt
new file mode 100644
index 000000000..dd43f96a5
--- /dev/null
+++ b/lib/plugins/popularity/lang/lv/intro.txt
@@ -0,0 +1,9 @@
+====== Popularitātes atsauksme ======
+
+Šis rīks savāc anonīmus datus par tavu wiki sistēmu un piedāvā tos nodot DokuWiki izstrādātājiem. Tas ļauj zināt kā izmanto DokuWiki un palīdz tālāko attīstību balstīt patiesas izmantošanas statistikā .
+
+Ierosinām laiku pa laikam atkārtoti nosūtīt datus, lai izstrādātāji zinātu, ka tavs wiki aug. Atkārtotos sūtījumus identificēs pēc anonīmā ID.
+
+Savāktie dati satur ziņas par DokuWiki versiju, lapu skaitu un apjomu, instalētajiem spraudņiem un par PHP instalāciju.
+
+Nosūtāmie dati redzami zemāk. Nospied pogu "Nosūtīt datus", lai nodotu ziņas. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/lv/lang.php b/lib/plugins/popularity/lang/lv/lang.php
new file mode 100644
index 000000000..f0c940b6f
--- /dev/null
+++ b/lib/plugins/popularity/lang/lv/lang.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Latvian, Lettish language file
+ *
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['name'] = 'Popularitātes atsauksmes (ielāde var aizņemt kādu laiku)';
+$lang['submit'] = 'Nosūtīt datus';
+$lang['autosubmit'] = 'Automātiski reizi mēnesī nosūtīt datus';
+$lang['submissionFailed'] = 'Datus nevar nosūtīt kļūdas dēļ:';
+$lang['submitDirectly'] = 'Jūs pats varat pats nosūtīt datus no šīs veidlapas.';
+$lang['autosubmitError'] = 'Pēdējā automātiskā nosūtīšana kļūdas dēļ:';
+$lang['lastSent'] = 'Dati nosūtīti';
diff --git a/lib/plugins/popularity/lang/lv/submitted.txt b/lib/plugins/popularity/lang/lv/submitted.txt
new file mode 100644
index 000000000..c31338abf
--- /dev/null
+++ b/lib/plugins/popularity/lang/lv/submitted.txt
@@ -0,0 +1,3 @@
+====== Popularitātes atsauksmes ======
+
+Dati veiksmīgi nosūtīti \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/mk/lang.php b/lib/plugins/popularity/lang/mk/lang.php
new file mode 100644
index 000000000..6d4530f79
--- /dev/null
+++ b/lib/plugins/popularity/lang/mk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Macedonian language file
+ *
+ * @author Dimitar Talevski <dimi3.14@gmail.com>
+ */
diff --git a/lib/plugins/popularity/lang/mr/intro.txt b/lib/plugins/popularity/lang/mr/intro.txt
new file mode 100644
index 000000000..df912e483
--- /dev/null
+++ b/lib/plugins/popularity/lang/mr/intro.txt
@@ -0,0 +1,8 @@
+====== लोकप्रियता फीडबॅक ======
+हे टूल तुमच्या विकी संबंधी माहिती गुप्तपणे गोळा करते आणि डॉक्युविकीच्या निर्मात्याना पाठवते. याद्वारे त्यांना डॉक्युविकी प्रत्यक्ष कशी वापरली जाते व त्यानुसार प्रत्यक्ष माहितीवर आधारित पुढील सुधारणा करण्यास मदत होते.
+
+तुम्ही हे टूल ठराविक अंतराने परत वापरत राहिल्यास अधिक चांगले ,कारण तुमची विकी जसजशी वाढेल तसे डेवलपर लोकाना त्याबद्दल माहिती कळण्यास मदत होइल. तुमचा डेटा गुप्त निर्देशकाद्वारे ओळखला जाइल.
+
+या डेटा मधे पुढील प्रकारची माहिती असेल : तुमच्या डॉक्युविकीची आवृत्ति, त्यातील पानांची संख्या व साइज़, इन्स्टॉल केलेले प्लगइन आणि तुमच्या PHP ची आवृत्ति.
+
+जो डेटा प्रत्यक्ष पाठवला जाइल तो खाली दाखवला आहे. "Send Data" बटन वर क्लिक करून हा डेटा पाठवा. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/mr/lang.php b/lib/plugins/popularity/lang/mr/lang.php
new file mode 100644
index 000000000..abf7dd5ed
--- /dev/null
+++ b/lib/plugins/popularity/lang/mr/lang.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Marathi language file
+ *
+ * @author ghatothkach@hotmail.com
+ * @author Padmanabh Kulkarni <kulkarnipadmanabh@gmail.com>
+ * @author Padmanabh Kulkarni<kulkarnipadmanabh@gmail.com>
+ * @author shantanoo@gmail.com
+ */
+$lang['name'] = 'लोकप्रियता फीडबॅक ( लोड होण्यास थोडा वेळ लागेल )';
+$lang['submit'] = 'माहीती पाठवा';
diff --git a/lib/plugins/popularity/lang/ms/lang.php b/lib/plugins/popularity/lang/ms/lang.php
new file mode 100644
index 000000000..77ad2a1c1
--- /dev/null
+++ b/lib/plugins/popularity/lang/ms/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Malay language file
+ *
+ * @author Markos
+ */
diff --git a/lib/plugins/popularity/lang/ne/lang.php b/lib/plugins/popularity/lang/ne/lang.php
new file mode 100644
index 000000000..d6aa56eb7
--- /dev/null
+++ b/lib/plugins/popularity/lang/ne/lang.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Nepali language file
+ *
+ * @author Saroj Kumar Dhakal <lotusnagarkot@gmail.com>
+ * @author SarojKumar Dhakal <lotusnagarkot@yahoo.com>
+ * @author Saroj Dhakal<lotusnagarkot@yahoo.com>
+ */
+$lang['submit'] = 'सामग्री पठाउनुहोस् ';
diff --git a/lib/plugins/popularity/lang/nl/intro.txt b/lib/plugins/popularity/lang/nl/intro.txt
new file mode 100644
index 000000000..3c045c427
--- /dev/null
+++ b/lib/plugins/popularity/lang/nl/intro.txt
@@ -0,0 +1,9 @@
+====== Populariteitsfeedback ======
+
+Dit onderdeel verzamelt anonieme gegevens over uw wiki en stelt u in staat deze te versturen naar de ontwikkelaars van DokuWiki. Dit helpt hen te begrijpen hoe DokuWiki wordt gebruikt door de gebruikers en zorgt er ook voor dat toekomstige ontwikkelkeuzes kunnen worden gestaafd door echte gebruikersstatistieken.
+
+U wordt verzocht deze stap van tijd tot tijd te herhalen om ontwikkelaars op de hoogte te houden terwijl uw wiki groeit. De herhaalde data zal worden geïdentificeerd door een uniek, anoniem ID.
+
+De verzamelde gegevens bevat onder andere gegevens over uw versie van DokuWiki, het aantal- en de grootte van de pagina's en bestanden, geïnstalleerde plugins en informatie over PHP.
+
+De ruwe data die verzonden worden staan hieronder. Gebruik de knop "Verstuur" om de informatie te verzenden.
diff --git a/lib/plugins/popularity/lang/nl/lang.php b/lib/plugins/popularity/lang/nl/lang.php
new file mode 100644
index 000000000..e5e94aab4
--- /dev/null
+++ b/lib/plugins/popularity/lang/nl/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Dutch language file
+ *
+ * @author Wouter Schoot <wouter@schoot.org>
+ * @author Niels Schoot <niels.schoot@quintiq.com>
+ * @author Dion Nicolaas <dion@nicolaas.net>
+ * @author Danny Rotsaert <danny.rotsaert@edpnet.be>
+ * @author Marijn Hofstra hofstra.m@gmail.com
+ * @author Matthias Carchon webmaster@c-mattic.be
+ * @author Marijn Hofstra <hofstra.m@gmail.com>
+ * @author Timon Van Overveldt <timonvo@gmail.com>
+ * @author Jeroen
+ * @author Ricardo Guijt <ricardoguijt@gmail.com>
+ */
+$lang['name'] = 'Populariteitsfeedback (kan even duren om in te laden)';
+$lang['submit'] = 'Verstuur';
+$lang['autosubmit'] = 'Gegevens automatisch maandelijks verzenden';
+$lang['submissionFailed'] = 'De gegevens konden niet verstuurd worden vanwege de volgende fouten:';
+$lang['submitDirectly'] = 'Je kan de gegevens handmatig sturen door het onderstaande formulier te verzenden.';
+$lang['autosubmitError'] = 'De laatste automatische verzending is mislukt vanwege de volgende fout:';
+$lang['lastSent'] = 'De gegevens zijn verstuurd.';
diff --git a/lib/plugins/popularity/lang/nl/submitted.txt b/lib/plugins/popularity/lang/nl/submitted.txt
new file mode 100644
index 000000000..219d80fb6
--- /dev/null
+++ b/lib/plugins/popularity/lang/nl/submitted.txt
@@ -0,0 +1,3 @@
+===== Populariteitsfeedback =====
+
+Het versturen van de gegevens is gelukt. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/no/intro.txt b/lib/plugins/popularity/lang/no/intro.txt
new file mode 100644
index 000000000..a0f360157
--- /dev/null
+++ b/lib/plugins/popularity/lang/no/intro.txt
@@ -0,0 +1,9 @@
+====== Popularitetsfeedback ======
+
+Dette verktøyet samler anonyme data om din wiki og lar deg sende det tilbake til DokuWikis utviklere. Dette hjelper utviklerne å forstå hvordan DokuWiki blir brukt av brukerne, og gjør at fremtidig beslutninger om videre utvikling kan baseres på statistikk fra virkelig bruk.
+
+Du oppfordres herved til å gjenta dette skrittet fra tid til annen for å holde utviklerne informert når din wiki vokser. Ditt gjentatte datasett blir identifisert vha en anonym ID.
+
+De data som samles inn inneholder informasjon som din DokuWiki-versjon, antallet og størrelsen på sider og filer, installerte plugins og informasjon om din installerte PHP.
+
+Rådata som blir sendt vises nedenfor. Bruk knappen "Send data" for å overføre informasjonen. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/no/lang.php b/lib/plugins/popularity/lang/no/lang.php
new file mode 100644
index 000000000..df38f6e0e
--- /dev/null
+++ b/lib/plugins/popularity/lang/no/lang.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Norwegian language file
+ *
+ * @author Rune M. Andersen <rune.andersen@gmail.com>
+ * @author Jakob Vad Nielsen (me@jakobnielsen.net)
+ * @author Kjell Tore Næsgaard <kjell.t.nasgaard@ntnu.no>
+ * @author Knut Staring <knutst@gmail.com>
+ * @author Lisa Ditlefsen <lisa@vervesearch.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author Rune Rasmussen syntaxerror.no@gmail.com
+ * @author Thomas Nygreen <nygreen@gmail.com>
+ * @author Jon Bøe <jonmagneboe@hotmail.com>
+ * @author Egil Hansen <egil@rosetta.no>
+ */
+$lang['name'] = 'Popularitetsfeedback (kan ta litt tid å laste)';
+$lang['submit'] = 'Send data';
+$lang['autosubmit'] = 'Send data automatisk en gang i måneden';
+$lang['submissionFailed'] = 'Kunne ikke sende dataene på grunn av følgende feil:';
+$lang['submitDirectly'] = 'Du kan sende dataene manuelt ved å sende inn dette skjemaet.';
+$lang['autosubmitError'] = 'Den siste automatiske innsendingen feilet på grunn av følgende feil:';
+$lang['lastSent'] = 'Dataene er sendt';
diff --git a/lib/plugins/popularity/lang/no/submitted.txt b/lib/plugins/popularity/lang/no/submitted.txt
new file mode 100644
index 000000000..ccec7674e
--- /dev/null
+++ b/lib/plugins/popularity/lang/no/submitted.txt
@@ -0,0 +1,3 @@
+====== Tilbakemelding om popularitet ======
+
+Innsending av dataene var vellykket. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/pl/intro.txt b/lib/plugins/popularity/lang/pl/intro.txt
new file mode 100644
index 000000000..d95e7f79c
--- /dev/null
+++ b/lib/plugins/popularity/lang/pl/intro.txt
@@ -0,0 +1,9 @@
+====== Informacja o popularności ======
+
+To narzędzie zbiera anonimowe dane o Twoim wiki i wysyła je do twórców DokuWiki. Zbieranie tych informacji pozwala na lepsze zrozumienie sposobów korzystania z DokuWiki i ułatwia podejmowanie przyszłych decyzji projektowych w oparciu o rzeczywiste dane statystyczne.
+
+Zachęcamy do uruchamiania tej funkcji co pewien czas, by poinformować programistów DokuWiki o rozwoju Twojego wiki. Informacje przesyłane przez Ciebie będą oznaczone anonimowym identyfikatorem.
+
+Zbierane dane zawierają informacje o wersji DokuWiki, ilości i rozmiarze stron i plików, zainstalowanych wtyczkach oraz informację o oprogramowaniu PHP.
+
+Wysyłane dane przedstawione są poniżej. Naciśnij przycisk "Wyślij dane" w celu przesłania informacji. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/pl/lang.php b/lib/plugins/popularity/lang/pl/lang.php
new file mode 100644
index 000000000..64d772d54
--- /dev/null
+++ b/lib/plugins/popularity/lang/pl/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Polish language file
+ *
+ * @author Grzegorz Żur <grzegorz.zur@gmail.com>
+ * @author Mariusz Kujawski <marinespl@gmail.com>
+ * @author Maciej Kurczewski <pipijajko@gmail.com>
+ * @author Sławomir Boczek <slawkens@gmail.com>
+ * @author sleshek@wp.pl
+ * @author Leszek Stachowski <shazarre@gmail.com>
+ * @author maros <dobrimaros@yahoo.pl>
+ * @author Grzegorz Widła <dzesdzes@gmail.com>
+ * @author Łukasz Chmaj <teachmeter@gmail.com>
+ * @author Begina Felicysym <begina.felicysym@wp.eu>
+ */
+$lang['name'] = 'Informacja o popularności (ładowanie może zająć dłuższą chwilę)';
+$lang['submit'] = 'Wyślij dane';
+$lang['autosubmit'] = 'Automatycznie wysyłaj dane raz na miesiąc';
+$lang['submissionFailed'] = 'Dane nie mogły być przesłane ze względu na następujące błędy:';
+$lang['submitDirectly'] = 'Możesz wysłać dane ręcznie poprzez następujący formularz:';
+$lang['autosubmitError'] = 'Ostatnie wysyłanie automatyczne nie powiodło się ze względu na następujące błędy:';
+$lang['lastSent'] = 'Dane zostały wysłane:';
diff --git a/lib/plugins/popularity/lang/pl/submitted.txt b/lib/plugins/popularity/lang/pl/submitted.txt
new file mode 100644
index 000000000..195e81388
--- /dev/null
+++ b/lib/plugins/popularity/lang/pl/submitted.txt
@@ -0,0 +1,3 @@
+====== Informacje o popularności ======
+
+Wysyłanie danych powiodło się. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/pt-br/intro.txt b/lib/plugins/popularity/lang/pt-br/intro.txt
new file mode 100644
index 000000000..306cb2820
--- /dev/null
+++ b/lib/plugins/popularity/lang/pt-br/intro.txt
@@ -0,0 +1,9 @@
+====== Retorno de Popularidade ======
+
+Essa ferramenta coleta dados anônimos sobre o seu wiki e permite que você os envie para os desenvolvedores do DokuWiki. Isso ajuda-os a compreender como o DokuWiki é utilizado pelos seus usuários e garante que decisões para futuros desenvolvimentos sejam respaldadas por estatísticas de uso real.
+
+Você é encorajado a repetir esse procedimento de tempos em tempos, para manter os desenvolvedores informados quando o seu wiki for alterado. Seus pacotes de dados repetidos serão categorizados por uma identificação anônima.
+
+Os dados coletados contém informações do tipo: a versão do seu DokuWiki, o número e tamanho das suas páginas e arquivos, plug-ins instalados e informações sobre a sua instalação do PHP.
+
+Os dados brutos que serão enviados é mostrado abaixo. Por favor, utilize o botão "Enviar dados" para transferir a informação.
diff --git a/lib/plugins/popularity/lang/pt-br/lang.php b/lib/plugins/popularity/lang/pt-br/lang.php
new file mode 100644
index 000000000..44d811d81
--- /dev/null
+++ b/lib/plugins/popularity/lang/pt-br/lang.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
+ * @author Lucien Raven <lucienraven@yahoo.com.br>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Flávio Veras <flaviove@gmail.com>
+ * @author Jeferson Propheta <jeferson.propheta@gmail.com>
+ * @author jair.henrique@gmail.com
+ * @author Luis Dantas <luis@dantas.com>
+ * @author Frederico Guimarães <frederico@teia.bio.br>
+ * @author Jair Henrique <jair.henrique@gmail.com>
+ * @author Luis Dantas <luisdantas@gmail.com>
+ * @author Sergio Motta sergio@cisne.com.br
+ * @author Isaias Masiero Filho <masiero@masiero.org>
+ * @author Balaco Baco <balacobaco@imap.cc>
+ */
+$lang['name'] = 'Retorno de popularidade (pode demorar um pouco para carregar)';
+$lang['submit'] = 'Enviar dados';
+$lang['autosubmit'] = 'Enviar os dados automaticamente uma vez por mês';
+$lang['submissionFailed'] = 'Os dados não puderam ser enviados devido ao seguinte erro:';
+$lang['submitDirectly'] = 'Você pode enviar os dados manualmente, submetendo o formulário baixo.';
+$lang['autosubmitError'] = 'Ocorreu uma falha na última submissão automática, devido ao seguinte erro:';
+$lang['lastSent'] = 'Os dados foram enviados';
diff --git a/lib/plugins/popularity/lang/pt-br/submitted.txt b/lib/plugins/popularity/lang/pt-br/submitted.txt
new file mode 100644
index 000000000..7c0cea8c1
--- /dev/null
+++ b/lib/plugins/popularity/lang/pt-br/submitted.txt
@@ -0,0 +1,3 @@
+====== Retorno de popularidade ======
+
+Os dados foram enviados com sucesso. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/pt/intro.txt b/lib/plugins/popularity/lang/pt/intro.txt
new file mode 100644
index 000000000..9ec37e208
--- /dev/null
+++ b/lib/plugins/popularity/lang/pt/intro.txt
@@ -0,0 +1,9 @@
+====== Retorno de Popularidade ======
+
+Esta ferramenta junta dados anónimos sobre o seu wiki e permite estes sejam enviados para a equipa de desenvolvimento do DokuWiki. Isto ajuda-os a compreender como o DokuWiki é usado pelos seus utilizadores de forma a permitir que desenvolvimentos futuros sejam baseadas em estatísticas de uso real.
+
+Você é encorajado a repetir este passo regularmente para manter a equipa informada quando o seu wiki crescer. Os seus dados permanecerão sempre anónimos.
+
+Os dados colectados contêm informação como a versão do DokuWiki que você utiliza, o número e tamanho das suas páginas e ficheiros, os plugins instalados e informação sobre a sua instalação do PHP.
+
+Os dados que serão enviados são mostrados abaixo. Use o botão "Enviar Dados" para transferir a informação. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/pt/lang.php b/lib/plugins/popularity/lang/pt/lang.php
new file mode 100644
index 000000000..ac27dc8c0
--- /dev/null
+++ b/lib/plugins/popularity/lang/pt/lang.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Fil <fil@meteopt.com>
+ * @author André Neves <drakferion@gmail.com>
+ * @author José Campos zecarlosdecampos@gmail.com
+ */
+$lang['name'] = 'Retorno (feedback) de Popularidade (pode levar algum tempo a carregar)';
+$lang['submit'] = 'Enviar Dados';
+$lang['autosubmit'] = 'Enviar dados automáticamente uma vez por mês';
+$lang['submissionFailed'] = 'Os dados não foram enviados devido ao seguinte erro:';
+$lang['submitDirectly'] = 'Pode enviar os dados manualmente, submetendo o seguinte formulário.';
+$lang['autosubmitError'] = 'A última auto-submissão falhou, por causa do seguinte erro:';
+$lang['lastSent'] = 'Os dados foram enviados';
diff --git a/lib/plugins/popularity/lang/pt/submitted.txt b/lib/plugins/popularity/lang/pt/submitted.txt
new file mode 100644
index 000000000..d2bb2b7ae
--- /dev/null
+++ b/lib/plugins/popularity/lang/pt/submitted.txt
@@ -0,0 +1,3 @@
+====== Retorno de Popularidade ======
+
+Os dados foram enviados com sucesso. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ro/intro.txt b/lib/plugins/popularity/lang/ro/intro.txt
new file mode 100644
index 000000000..b2dfcbaf1
--- /dev/null
+++ b/lib/plugins/popularity/lang/ro/intro.txt
@@ -0,0 +1,9 @@
+====== Feedback de popularitate ======
+
+Această unealtă colectează date anonime despre wiki-ul dvs. şi vă permite să le trimiteţi înapoi către dezvoltatorii DokuWiki. Aceasta îi ajută să înţeleagă cum este folosit DokuWiki de către utilizatori şi asigură faptul că viitoarele decizii privind dezvoltarea sunt bazate pe statistici ale utilizării în condiţii reale.
+
+Sunteţi încurajat să repetaţi acest pas din când în când pentru a ţine dezvoltatorii la curent cu dezvoltarea wiki-ului dvs. Seturile de date trimise in mod repetat vor fi identificate printr-un ID anonim.
+
+Datele colectate conţin informaţii precum versiunea DokuWiki, numărul şi mărimea paginilor şi a fişierelor dvs., plugin-urile instalate şi informaţii despre versiunea PHP instalată.
+
+Datele brute ce vor fi trimise sunt afişate mai jos. Vă rugăm utilizaţi butonul "Trimite datele" pentru a transfera informaţiile. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ro/lang.php b/lib/plugins/popularity/lang/ro/lang.php
new file mode 100644
index 000000000..f3ca8d37e
--- /dev/null
+++ b/lib/plugins/popularity/lang/ro/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Romanian language file
+ *
+ * @author Emanuel-Emeric Andrasi <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrași <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andraşi <em.andrasi@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrasi <em.andrasi@mandrivausers.ro>
+ * @author Marius OLAR <olarmariusalex@gmail.com>
+ * @author Emanuel-Emeric Andrași <em.andrasi@mandrivausers.ro>
+ */
+$lang['name'] = 'Feedback de popularitate (încărcarea poate dura mai mult)';
+$lang['submit'] = 'Trimite datele';
+$lang['autosubmit'] = 'Trimite datele automat o dată pe lună';
+$lang['submissionFailed'] = 'Datele nu au fost trimise din cauza următoarei erori:';
+$lang['submitDirectly'] = 'Puteți trimite datele manual prin completarea următorului formular.';
+$lang['autosubmitError'] = 'Ultima trimitere automată a eșuat din cauza următoarei erori:';
+$lang['lastSent'] = 'Datele au fost trimise';
diff --git a/lib/plugins/popularity/lang/ro/submitted.txt b/lib/plugins/popularity/lang/ro/submitted.txt
new file mode 100644
index 000000000..214ffb71f
--- /dev/null
+++ b/lib/plugins/popularity/lang/ro/submitted.txt
@@ -0,0 +1,3 @@
+====== Feedback de popularitate ======
+
+Datele au fost trimise cu succes. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ru/intro.txt b/lib/plugins/popularity/lang/ru/intro.txt
new file mode 100644
index 000000000..e8118e4eb
--- /dev/null
+++ b/lib/plugins/popularity/lang/ru/intro.txt
@@ -0,0 +1,10 @@
+====== Сбор информации о популярности ======
+
+Этот инструмент собирает анонимные данные о вашей вики и позволяет вам отправить их разработчикам «ДокуВики». Эти данные помогут им понять, как именно используется «ДокуВики», и удостовериться, что принимаемые проектные решения соответствуют жизненным реалиям.
+
+Отправляйте данные время от времени для того, чтобы сообщать разработчикам о том, что ваша вики «подросла». Отправленные вами данные будут идентифицированы по анонимному ID.
+
+Собранные данные содержат такую информацию, как: версия «ДокуВики», количество и размер ваших страниц и файлов, установленные плагины, информацию об установленном PHP.
+
+Данные, которые будут отосланы, представлены ниже. Пожалуйста, используйте кнопку «Отправить данные», чтобы передать информацию.
+
diff --git a/lib/plugins/popularity/lang/ru/lang.php b/lib/plugins/popularity/lang/ru/lang.php
new file mode 100644
index 000000000..79b3e224d
--- /dev/null
+++ b/lib/plugins/popularity/lang/ru/lang.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Russian language file
+ *
+ * @author Змей Этерийский evil_snake@eternion.ru
+ * @author Hikaru Nakajima <jisatsu@mail.ru>
+ * @author Alexei Tereschenko <alexeitlex@yahoo.com>
+ * @author Irina Ponomareva irinaponomareva@webperfectionist.com
+ * @author Alexander Sorkin <kibizoid@gmail.com>
+ * @author Kirill Krasnov <krasnovforum@gmail.com>
+ * @author Vlad Tsybenko <vlad.development@gmail.com>
+ * @author Aleksey Osadchiy <rfc@nm.ru>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Ladyko Andrey <fylh@succexy.spb.ru>
+ * @author Eugene <windy.wanderer@gmail.com>
+ */
+$lang['name'] = 'Сбор информации о популярности (для загрузки может потребоваться некоторое время)';
+$lang['submit'] = 'Отправить данные';
+$lang['autosubmit'] = 'Автоматически отправлять данные один раз в месяц';
+$lang['submissionFailed'] = 'Данные не могут быть отправлены из-за ошибки:';
+$lang['submitDirectly'] = 'Вы можете отправлять данные вручную, заполнив форму:';
+$lang['autosubmitError'] = 'Последнее автоотправление данных не удалось из-за ошибки:';
+$lang['lastSent'] = 'Данные отправлены';
diff --git a/lib/plugins/popularity/lang/ru/submitted.txt b/lib/plugins/popularity/lang/ru/submitted.txt
new file mode 100644
index 000000000..a239943a4
--- /dev/null
+++ b/lib/plugins/popularity/lang/ru/submitted.txt
@@ -0,0 +1,2 @@
+====== Общественная обратная связь ======
+Данные были успешно отправлены. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/sk/intro.txt b/lib/plugins/popularity/lang/sk/intro.txt
new file mode 100644
index 000000000..7f580d979
--- /dev/null
+++ b/lib/plugins/popularity/lang/sk/intro.txt
@@ -0,0 +1,9 @@
+====== Prieskum používania ======
+
+Tento nástroj získa anonymné dáta o Vašej wiki a ponúkne Vám možnosť odoslať ich späť k vývojárom DokuWiki. Týmto spôsobom im umožníte lepšie porozumieť, ako je používaná DokuWiki, a podporiť ich budúce rozhodnutia o ďalšom vývoji informáciami z reálneho používania DokuWiki.
+
+Doporučujeme Vám opakovať tento krok z času na čas pri napredovaní Vašej wiki a tak pomôcť vývojárom DokuWiki. Vaše dáta budú označené anonymným ID.
+
+Zozbierané dáta obsahujú informácie ako verziu DokuWiki, počet a veľkosť Vašich stránok a súborov, inštalované pluginy a informácie o inštalovanom PHP.
+
+Dáta, ktoré budú poslané sú zobrazené nižšie. Prosím použite tlačidlo "Poslať dáta" na odoslanie týchto informácií. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/sk/lang.php b/lib/plugins/popularity/lang/sk/lang.php
new file mode 100644
index 000000000..bc46b03c5
--- /dev/null
+++ b/lib/plugins/popularity/lang/sk/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Slovak language file
+ *
+ * @author Michal Mesko <michal.mesko@gmail.com>
+ * @author exusik@gmail.com
+ * @author Martin Michalek <michalek.dev@gmail.com>
+ */
+$lang['name'] = 'Prieskum používania (môže chvíľu trvať)';
+$lang['submit'] = 'Poslať dáta';
+$lang['autosubmit'] = 'Automaticky zaslať dáta raz mesačne';
+$lang['submissionFailed'] = 'Dáta nemohli byť odoslané z nasledujúceho dôdovu:';
+$lang['submitDirectly'] = 'Dáta môžu byť zaslané manuálne nasledujúcim formulárom:';
+$lang['autosubmitError'] = 'Posledné automatické odoslanie dát zlyhalo z nasledujúceho dôvodu:';
+$lang['lastSent'] = 'Dáta boli odoslané.';
diff --git a/lib/plugins/popularity/lang/sk/submitted.txt b/lib/plugins/popularity/lang/sk/submitted.txt
new file mode 100644
index 000000000..f99fb9fa9
--- /dev/null
+++ b/lib/plugins/popularity/lang/sk/submitted.txt
@@ -0,0 +1,3 @@
+====== Prieskum používania ======
+
+Dáta boli úspešne odoslané. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/sl/intro.txt b/lib/plugins/popularity/lang/sl/intro.txt
new file mode 100644
index 000000000..2c029db63
--- /dev/null
+++ b/lib/plugins/popularity/lang/sl/intro.txt
@@ -0,0 +1,9 @@
+====== Poročilo o uporabi ======
+
+To orodje je namenjeno zbiranju brezimnih podatkov o postavljeni DokuWiki strani in omogoča pošiljanje nekaterih podatkov neposredno razvijalcem sistema. S temi podatki lahko razvijalci razumejo načine uporabe sistema, zahteve uporabnikov in pogostost uporabe, kar s statističnimi podatki vpliva tudi na nadaljnji razvoj sistema.
+
+Priporočeno je, da poročilo o uporabi pošljete vsake toliko časa, saj lahko le tako razvijalci dobijo podatke o hitrosti rasti spletišča in pogostosti uporabe. Vsi podatki so poslani označeni s posebno vpisno številko, ki omogoča brezimno sledenje.
+
+Zbrani podatki vsebujejo podrobnosti o različici uporabljenega sistema DokuWiki, število in velikost wiki strani, datotekah, ki so naložene na sistem in podatke o vstavkih ter PHP namestitvi in različici.
+
+Surovi podatki, ki bodo poslani so prikazani spodaj. S pritiskom na gumb "Pošlji podatke", bodo ti poslani na strežnik razvijalcev.
diff --git a/lib/plugins/popularity/lang/sl/lang.php b/lib/plugins/popularity/lang/sl/lang.php
new file mode 100644
index 000000000..5c92dd7c4
--- /dev/null
+++ b/lib/plugins/popularity/lang/sl/lang.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Slovenian language file
+ *
+ * @author Matej Urbančič (mateju@svn.gnome.org)
+ */
+$lang['name'] = 'Poročilo o uporabi (nalaganje strani je lahko dolgotrajno)';
+$lang['submit'] = 'Pošlji podatke';
+$lang['autosubmit'] = 'Samodejno pošlji podatke enkrat mesečno';
+$lang['submissionFailed'] = 'Podatkov zaradi napake ni mogoče poslati:';
+$lang['submitDirectly'] = 'Podatke je mogoče poslati ročno s pošiljanjem preko obrazca.';
+$lang['autosubmitError'] = 'Zadnji poskus samodejnega pošiljanja je spodletel zaradi napake:';
+$lang['lastSent'] = 'Podatki so bili uspešno poslani.';
diff --git a/lib/plugins/popularity/lang/sl/submitted.txt b/lib/plugins/popularity/lang/sl/submitted.txt
new file mode 100644
index 000000000..11ae052f7
--- /dev/null
+++ b/lib/plugins/popularity/lang/sl/submitted.txt
@@ -0,0 +1,3 @@
+====== Poročilo o uporabi ======
+
+Podatki so bili uspešno poslani.
diff --git a/lib/plugins/popularity/lang/sq/intro.txt b/lib/plugins/popularity/lang/sq/intro.txt
new file mode 100644
index 000000000..eb37e5f36
--- /dev/null
+++ b/lib/plugins/popularity/lang/sq/intro.txt
@@ -0,0 +1,9 @@
+====== Informacioni mbi Popullaritetin ======
+
+Ky mjet mbledh të dhëna anonime rreth wiki-t tuaj dhe ju lejon t'ia dërgoni ato zhvilluesve të DokuWiki-t. Kjo i ndihmon ata të kuptojnë sesi DokuWiki përdoret nga përdoruesit e tij dhe siguron që vendimet për zhvillime të ardhshme të jenë të mbështetura mbi statistika të nxjera nga bota e vërtetë.
+
+Ju jeni të inkurajuar ta përsërisni këtë hap shpesh herë për t'i mbajtur zhvilluesit të informuar kur wiki juaj rritet. Bashkësia e të dhënave tuaja të përsëritura do të identifikohen nga një ID anonime.
+
+Të dhënat e mbledhura përmbajnë informacione si versioni i DokuWiki-t tuaj, numri dhe madhësia e faqeve dhe skedarëve, plugin-et e instaluar dhe informacione rreth instalimit të PHP-së.
+
+Të dhënat e papërpunuara që do të dërgohen janë treguar më poshtë. Ju lutem përdorni buttonin "Dërgo Të Dhëna" për të transferuar informacionin. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/sq/lang.php b/lib/plugins/popularity/lang/sq/lang.php
new file mode 100644
index 000000000..1954ce04c
--- /dev/null
+++ b/lib/plugins/popularity/lang/sq/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Albanian language file
+ *
+ * @author Leonard Elezi leonard.elezi@depinfo.info
+ */
+$lang['name'] = 'Informacioni mbi Popullaritetin (mund të marë ca kohë derisa të ngarkohet)';
+$lang['submit'] = 'Dërgo Të Dhënat';
diff --git a/lib/plugins/popularity/lang/sr/intro.txt b/lib/plugins/popularity/lang/sr/intro.txt
new file mode 100644
index 000000000..cbbb46adf
--- /dev/null
+++ b/lib/plugins/popularity/lang/sr/intro.txt
@@ -0,0 +1,9 @@
+====== Мерење популарности ======
+
+Ова алатка анонимно скупља податке о вашем викију и шаље их програмерима DokuWiki-ја. Овим помажете да разумеју како корисници користе DokuWiki и обезбеђујете да се одлуке имају потпору у статистици о коришћењу у реалним условима.
+
+Охрабрујемо вас да поновите овај корак с времена на време да би програмери имали информацију о развоју вашег викија. Ваши поновљени подаци ће бити идентификовани са анонимним ЛИБом.
+
+Сакупљени подаци садрже информације: верзија вашег DokuWiki-ја, број и величина страница и датотека, инсталирани додаци и информације о ПХПу.
+
+Сирова верзија података који се шаљу се налази испод. Користите дугме Пошаљи податке за пренос информација. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/sr/lang.php b/lib/plugins/popularity/lang/sr/lang.php
new file mode 100644
index 000000000..f560b52a8
--- /dev/null
+++ b/lib/plugins/popularity/lang/sr/lang.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Serbian language file
+ *
+ * @author Иван Петровић petrovicivan@ubuntusrbija.org
+ * @author Ivan Petrovic <petrovicivan@ubuntusrbija.org>
+ * @author Miroslav Šolti <solti.miroslav@gmail.com>
+ */
+$lang['name'] = 'Мерење популарности (може потрајати док се не учита)';
+$lang['submit'] = 'Пошаљи податке';
diff --git a/lib/plugins/popularity/lang/sv/intro.txt b/lib/plugins/popularity/lang/sv/intro.txt
new file mode 100644
index 000000000..2f00c01d7
--- /dev/null
+++ b/lib/plugins/popularity/lang/sv/intro.txt
@@ -0,0 +1,11 @@
+====== Popularitetsfeedback ======
+
+Detta verktyg samlar anonyma data om din wiki och låter dig skicka dessa till DokuWikis utvecklare. Det hjälper utvecklarna att förstå hur DokuWiki används och gör att framtida beslut om DokuWikis utveckling kan grundas på statistik från verkligt bruk.
+
+Upprepa gärna detta steg då och då allteftersom din Wiki växer. Dina rapporter kommer att bli identifierade med hjälp av ett anonymt id.
+
+Data som samlas in innehåller information om bland annat din DokuWiki-version, antalet och storleken på sidorna, installerade plugins samt information om din PHP-installation.
+
+Rådata som kommer att sändas visas här nedanför. Vänligen använd knappen "Sänd data" för att överföra informationen.
+
+
diff --git a/lib/plugins/popularity/lang/sv/lang.php b/lib/plugins/popularity/lang/sv/lang.php
new file mode 100644
index 000000000..8be542e7f
--- /dev/null
+++ b/lib/plugins/popularity/lang/sv/lang.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Swedish language file
+ *
+ * @author Håkan Sandell <hakan.sandell[at]mydata.se>
+ * @author Dennis Karlsson
+ * @author Tormod Otter Johansson <tormod@latast.se>
+ * @author emil@sys.nu
+ * @author Pontus Bergendahl <pontus.bergendahl@gmail.com>
+ * @author Tormod Johansson tormod.otter.johansson@gmail.com
+ * @author Emil Lind <emil@sys.nu>
+ * @author Bogge Bogge <bogge@bogge.com>
+ * @author Peter Åström <eaustreum@gmail.com>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ * @author mikael@mallander.net
+ */
+$lang['name'] = 'Popularitets-feedback (det kan ta en stund att ladda sidan)';
+$lang['submit'] = 'Sänd data';
+$lang['autosubmit'] = 'Skicka data automatiskt varje månad';
+$lang['submissionFailed'] = 'Datan kunde inte skickas för att:';
+$lang['submitDirectly'] = 'Du kan skicka datan manuellt genom att fylla i följande formulär.';
+$lang['autosubmitError'] = 'Senaste automatiska sändning av datan misslyckades för att:';
+$lang['lastSent'] = 'Datan har skickats';
diff --git a/lib/plugins/popularity/lang/sv/submitted.txt b/lib/plugins/popularity/lang/sv/submitted.txt
new file mode 100644
index 000000000..fb8eab773
--- /dev/null
+++ b/lib/plugins/popularity/lang/sv/submitted.txt
@@ -0,0 +1,3 @@
+====== Popularitetsfeedback ======
+
+Datan har skickats utan problem. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/th/lang.php b/lib/plugins/popularity/lang/th/lang.php
new file mode 100644
index 000000000..3ae8a7890
--- /dev/null
+++ b/lib/plugins/popularity/lang/th/lang.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Thai language file
+ *
+ * @author Komgrit Niyomrath <n.komgrit@gmail.com>
+ * @author Kittithat Arnontavilas mrtomyum@gmail.com
+ * @author Kittithat Arnontavilas <mrtomyum@gmail.com>
+ * @author Thanasak Sompaisansin <jombthep@gmail.com>
+ */
+$lang['name'] = 'ส่งข้อมูลความนิยมกลับ (อาจใช้เวลาในการโหลด)';
+$lang['submit'] = 'ส่งข้อมูล';
diff --git a/lib/plugins/popularity/lang/tr/intro.txt b/lib/plugins/popularity/lang/tr/intro.txt
new file mode 100644
index 000000000..a855ff327
--- /dev/null
+++ b/lib/plugins/popularity/lang/tr/intro.txt
@@ -0,0 +1,9 @@
+====== Popülerlik Geribeslemesi ======
+
+Bu araç wiki'niz hakkında genel bilgileri toplayarak bunları DokuWiki geliştiricilerine geri göndermenizi sağlar. Böylece geliştiriciler DokuWiki'nin kullanıcılar tarafından nasıl kullanıldığını anlamalarını sağlar ve ileride gerçek kullanım istatistiklerine göre geliştirme kararları verebilirler.
+
+Wiki'nizin büyümesiyle beraber bu bölümü zaman zaman çalıştırmanız geliştiricileri bilgilendirecektir. Tekrar gönderilen veriler anonim olarak gönderilecektir.
+
+Bu veriler DokuWiki sürümünü, sayısını, sayfaların ve dosyalarım büyüklüklerini, yüklü eklentileri ve PHP sürümünü içermektedir.
+
+Gönderilecek işlenmemiş veriler aşağıda gösterilmektedir. Lütfen "Verileri Gönder" butonuna tıklayarak bilgileri gönderin. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/tr/lang.php b/lib/plugins/popularity/lang/tr/lang.php
new file mode 100644
index 000000000..fe87d1548
--- /dev/null
+++ b/lib/plugins/popularity/lang/tr/lang.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Turkish language file
+ *
+ * @author Aydın Coşkuner <aydinweb@gmail.com>
+ * @author Cihan Kahveci <kahvecicihan@gmail.com>
+ * @author Yavuz Selim <yavuzselim@gmail.com>
+ * @author Caleb Maclennan <caleb@alerque.com>
+ */
+$lang['name'] = 'Popülerlik Geribeslemesi (yüklemesi uzun sürebilir)';
+$lang['submit'] = 'Verileri Gönder';
diff --git a/lib/plugins/popularity/lang/uk/intro.txt b/lib/plugins/popularity/lang/uk/intro.txt
new file mode 100644
index 000000000..3ceb8826e
--- /dev/null
+++ b/lib/plugins/popularity/lang/uk/intro.txt
@@ -0,0 +1,9 @@
+====== Відгук популярності ======
+
+Цей інструмент збирає анонімні дані про вашу вікі і відсилає її розробникам системи. Це допоможе їм зрозуміти, як саме користувачі використовують ДокуВікі і дозволяє врахувати потреби користувачів при подальшому удосконаленні системи.
+
+Ви можете повторно відсилати відгуки час від часу, щоб повідомляти розробників про розвиток вашої ДокуВікі. Повторні відгуки будуть ідентифіковані по анонімному ID.
+
+У зібраних даних є інформація про версію ДокуВікі, кількість і розмір сторінок в ній, встановлені додатки і інформація про налаштування вашого PHP.
+
+Дані, які буде надіслано показано нижче. Для передачі інформації натисніть будь-ласка кнопку "Передати дані" \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/uk/lang.php b/lib/plugins/popularity/lang/uk/lang.php
new file mode 100644
index 000000000..584641482
--- /dev/null
+++ b/lib/plugins/popularity/lang/uk/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Ukrainian language file
+ *
+ * @author serg_stetsuk@ukr.net
+ * @author okunia@gmail.com
+ * @author Oleksandr Kunytsia <okunia@gmail.com>
+ * @author Uko uko@uar.net
+ * @author Ulrikhe Lukoie <lukoie@gmail>.com
+ * @author Kate Arzamastseva pshns@ukr.net
+ */
+$lang['name'] = 'Відгук популярності (може зайняти деякий час)';
+$lang['submit'] = 'Передати дані';
+$lang['autosubmit'] = 'Автоматично надсилати дані один раз на місяць';
+$lang['submissionFailed'] = 'Дані не можуть бути відправлені через таку помилку:';
+$lang['submitDirectly'] = 'Ви можете надіслати дані вручну, відправивши наступну форму.';
+$lang['autosubmitError'] = 'Останнє автоматичне відправлення не вдалося через таку помилку:';
+$lang['lastSent'] = 'Дані були відправлені';
diff --git a/lib/plugins/popularity/lang/uk/submitted.txt b/lib/plugins/popularity/lang/uk/submitted.txt
new file mode 100644
index 000000000..90213858d
--- /dev/null
+++ b/lib/plugins/popularity/lang/uk/submitted.txt
@@ -0,0 +1,2 @@
+====== Відгук популярності ======
+Дані були успішно відправлені. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/zh-tw/intro.txt b/lib/plugins/popularity/lang/zh-tw/intro.txt
new file mode 100644
index 000000000..37c63dced
--- /dev/null
+++ b/lib/plugins/popularity/lang/zh-tw/intro.txt
@@ -0,0 +1,10 @@
+====== 人氣回饋 ======
+
+本工具會從您的維基站台收集訊息,並以匿名的方式發送給 DokuWiki 的開發者。這有助於他們了解使用者們如何使用 DokuWiki ,並能基於實際統計資料對未來開發做出更準確的決策。
+
+我們鼓勵您經常重複這個步驟,讓開發者了解您的維基站台的成長情形。您的資料集將會被標識為一個匿名的識別碼 (ID)。
+
+收集的資料包括 DokuWiki 版本、頁面數量、檔案大小、安裝的插件、伺服器的 PHP 資訊。
+
+將被發送的原始資料顯示如下。請點擊「發送資料」按鈕進行傳輸。
+
diff --git a/lib/plugins/popularity/lang/zh-tw/lang.php b/lib/plugins/popularity/lang/zh-tw/lang.php
new file mode 100644
index 000000000..3ced0ee5a
--- /dev/null
+++ b/lib/plugins/popularity/lang/zh-tw/lang.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Chinese Traditional language file
+ *
+ * @author Li-Jiun Huang <ljhuang.tw@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-simptrad.html
+ * @author Wayne San <waynesan@zerozone.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmai.com>
+ * @author Cheng-Wei Chien <e.cwchien@gmail.com>
+ * @author Danny Lin
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['name'] = '人氣回饋(載入可能需要一些時間)';
+$lang['submit'] = '發送資料';
+$lang['autosubmit'] = '每月自動發送';
+$lang['submissionFailed'] = '由於以下原因,資料無法發送:';
+$lang['submitDirectly'] = '你可以利用以下的表單來發手動發送資料.';
+$lang['autosubmitError'] = '由於以下原因,上次自動發送失敗:';
+$lang['lastSent'] = '資料已發送';
diff --git a/lib/plugins/popularity/lang/zh-tw/submitted.txt b/lib/plugins/popularity/lang/zh-tw/submitted.txt
new file mode 100644
index 000000000..6febcd5b8
--- /dev/null
+++ b/lib/plugins/popularity/lang/zh-tw/submitted.txt
@@ -0,0 +1,3 @@
+====== 人氣回饋 ======
+
+資料已發送成功 \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/zh/intro.txt b/lib/plugins/popularity/lang/zh/intro.txt
new file mode 100644
index 000000000..40e93dcb0
--- /dev/null
+++ b/lib/plugins/popularity/lang/zh/intro.txt
@@ -0,0 +1,9 @@
+====== 人气反馈 ======
+
+本工具收集关于您维基站点的匿名信息,并允许您将其发送给 DokuWiki 的开发者。这样做有助于我们了解用户是如何使用 DokuWiki 的,并能使我们未来的开发决策建立在现实使用数据上。
+
+我们鼓励您不时重复该步骤,以便我们能了解您的维基站点发展进度。您的数据集将被匿名 ID 标识。
+
+收集的数据包括 DokuWiki 版本、您的页面数量以及文件大小、已安装的插件、服务器上的 PHP 相关信息。
+
+将被发送的原始数据如下所示。请点击“发送数据”按扭进行传输。 \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/zh/lang.php b/lib/plugins/popularity/lang/zh/lang.php
new file mode 100644
index 000000000..9c916c2a5
--- /dev/null
+++ b/lib/plugins/popularity/lang/zh/lang.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Chinese language file
+ *
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-tradsimp.html
+ * @author George Sheraton guxd@163.com
+ * @author Simon zhan <simonzhan@21cn.com>
+ * @author mr.jinyi@gmail.com
+ * @author ben <ben@livetom.com>
+ * @author lainme <lainme993@gmail.com>
+ * @author caii <zhoucaiqi@gmail.com>
+ * @author Hiphen Lee <jacob.b.leung@gmail.com>
+ * @author caii, patent agent in China <zhoucaiqi@gmail.com>
+ * @author lainme993@gmail.com
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['name'] = '人气反馈(载入可能需要一些时间)';
+$lang['submit'] = '发送数据';
+$lang['autosubmit'] = '每月自动发送';
+$lang['submissionFailed'] = '数据由于以下原因不恩你给发送:';
+$lang['submitDirectly'] = '你可以手动提交下面的表单来发送数据。';
+$lang['autosubmitError'] = '印以下原因,上一次自动提交失败:';
+$lang['lastSent'] = '数据已发送';
diff --git a/lib/plugins/popularity/lang/zh/submitted.txt b/lib/plugins/popularity/lang/zh/submitted.txt
new file mode 100644
index 000000000..6039b70e1
--- /dev/null
+++ b/lib/plugins/popularity/lang/zh/submitted.txt
@@ -0,0 +1,3 @@
+====== 人气反馈 ======
+
+数据发送成功。 \ No newline at end of file
diff --git a/lib/plugins/popularity/plugin.info.txt b/lib/plugins/popularity/plugin.info.txt
new file mode 100644
index 000000000..16b148f41
--- /dev/null
+++ b/lib/plugins/popularity/plugin.info.txt
@@ -0,0 +1,7 @@
+base popularity
+author Andreas Gohr
+email andi@splitbrain.org
+date 2011-08-18
+name Popularity Feedback Plugin
+desc Send anonymous data about your wiki to the developers.
+url http://www.dokuwiki.org/plugin:popularity
diff --git a/lib/plugins/revert/admin.php b/lib/plugins/revert/admin.php
new file mode 100644
index 000000000..2aaf1395f
--- /dev/null
+++ b/lib/plugins/revert/admin.php
@@ -0,0 +1,185 @@
+<?php
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_revert extends DokuWiki_Admin_Plugin {
+ var $cmd;
+ // some vars which might need tuning later
+ var $max_lines = 800; // lines to read from changelog
+ var $max_revs = 20; // numer of old revisions to check
+
+
+ /**
+ * Constructor
+ */
+ function admin_plugin_revert(){
+ $this->setupLocale();
+ }
+
+ /**
+ * access for managers
+ */
+ function forAdminOnly(){
+ return false;
+ }
+
+ /**
+ * return sort order for position in admin menu
+ */
+ function getMenuSort() {
+ return 40;
+ }
+
+ /**
+ * handle user request
+ */
+ function handle() {
+ }
+
+ /**
+ * output appropriate html
+ */
+ function html() {
+
+ echo $this->plugin_locale_xhtml('intro');
+
+ $this->_searchform();
+
+ if(is_array($_REQUEST['revert']) && checkSecurityToken()){
+ $this->_revert($_REQUEST['revert'],$_REQUEST['filter']);
+ }elseif(isset($_REQUEST['filter'])){
+ $this->_list($_REQUEST['filter']);
+ }
+ }
+
+ /**
+ * Display the form for searching spam pages
+ */
+ function _searchform(){
+ global $lang;
+ echo '<form action="" method="post"><div class="no">';
+ echo '<label>'.$this->getLang('filter').': </label>';
+ echo '<input type="text" name="filter" class="edit" value="'.hsc($_REQUEST['filter']).'" />';
+ echo '<input type="submit" class="button" value="'.$lang['btn_search'].'" />';
+ echo ' <span>'.$this->getLang('note1').'</span>';
+ echo '</div></form><br /><br />';
+ }
+
+ /**
+ * Start the reversion process
+ */
+ function _revert($revert,$filter){
+ global $conf;
+
+ echo '<hr /><br />';
+ echo '<p>'.$this->getLang('revstart').'</p>';
+
+ echo '<ul>';
+ foreach($revert as $id){
+ global $REV;
+
+ // find the last non-spammy revision
+ $data = '';
+ $old = getRevisions($id, 0, $this->max_revs);
+ if(count($old)){
+ foreach($old as $REV){
+ $data = rawWiki($id,$REV);
+ if(strpos($data,$filter) === false) break;
+ }
+ }
+
+ if($data){
+ saveWikiText($id,$data,'old revision restored',false);
+ printf('<li><div class="li">'.$this->getLang('reverted').'</div></li>',$id,$REV);
+ }else{
+ saveWikiText($id,'','',false);
+ printf('<li><div class="li">'.$this->getLang('removed').'</div></li>',$id);
+ }
+ @set_time_limit(10);
+ flush();
+ }
+ echo '</ul>';
+
+ echo '<p>'.$this->getLang('revstop').'</p>';
+ }
+
+ /**
+ * List recent edits matching the given filter
+ */
+ function _list($filter){
+ global $conf;
+ global $lang;
+ echo '<hr /><br />';
+ echo '<form action="" method="post"><div class="no">';
+ echo '<input type="hidden" name="filter" value="'.hsc($filter).'" />';
+ formSecurityToken();
+
+ $recents = getRecents(0,$this->max_lines);
+ echo '<ul>';
+
+
+ $cnt = 0;
+ foreach($recents as $recent){
+ if($filter){
+ if(strpos(rawWiki($recent['id']),$filter) === false) continue;
+ }
+
+ $cnt++;
+ $date = strftime($conf['dformat'],$recent['date']);
+
+ echo ($recent['type']===DOKU_CHANGE_TYPE_MINOR_EDIT) ? '<li class="minor">' : '<li>';
+ echo '<div class="li">';
+ echo '<input type="checkbox" name="revert[]" value="'.hsc($recent['id']).'" checked="checked" id="revert__'.$cnt.'" />';
+ echo '<label for="revert__'.$cnt.'">'.$date.'</label> ';
+
+ echo '<a href="'.wl($recent['id'],"do=diff").'">';
+ $p = array();
+ $p['src'] = DOKU_BASE.'lib/images/diff.png';
+ $p['width'] = 15;
+ $p['height'] = 11;
+ $p['title'] = $lang['diff'];
+ $p['alt'] = $lang['diff'];
+ $att = buildAttributes($p);
+ echo "<img $att />";
+ echo '</a> ';
+
+ echo '<a href="'.wl($recent['id'],"do=revisions").'">';
+ $p = array();
+ $p['src'] = DOKU_BASE.'lib/images/history.png';
+ $p['width'] = 12;
+ $p['height'] = 14;
+ $p['title'] = $lang['btn_revs'];
+ $p['alt'] = $lang['btn_revs'];
+ $att = buildAttributes($p);
+ echo "<img $att />";
+ echo '</a> ';
+
+ echo html_wikilink(':'.$recent['id'],(useHeading('navigation'))?NULL:$recent['id']);
+ echo ' &ndash; '.htmlspecialchars($recent['sum']);
+
+ echo ' <span class="user">';
+ echo $recent['user'].' '.$recent['ip'];
+ echo '</span>';
+
+ echo '</div>';
+ echo '</li>';
+
+ @set_time_limit(10);
+ flush();
+ }
+ echo '</ul>';
+
+ echo '<p>';
+ echo '<input type="submit" class="button" value="'.$this->getLang('revert').'" /> ';
+ printf($this->getLang('note2'),hsc($filter));
+ echo '</p>';
+
+ echo '</div></form>';
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/plugins/revert/lang/af/lang.php b/lib/plugins/revert/lang/af/lang.php
new file mode 100644
index 000000000..1fff08db3
--- /dev/null
+++ b/lib/plugins/revert/lang/af/lang.php
@@ -0,0 +1,5 @@
+<?php
+/**
+ * Afrikaans language file
+ *
+ */
diff --git a/lib/plugins/revert/lang/ar/intro.txt b/lib/plugins/revert/lang/ar/intro.txt
new file mode 100644
index 000000000..5839ee0c8
--- /dev/null
+++ b/lib/plugins/revert/lang/ar/intro.txt
@@ -0,0 +1,3 @@
+====== مدير الاسترجاع ======
+
+تساعدك هذه الصفحة في الاستعادة الآلية لهجوم غثاء. للحصول على قائمة بالصفحات المغثاة أولا أدخل نص البحث (مثل. عنوان غثاء), ثم أكد أن الصفحات الموجودة هي غثاء فعلا و استرجع التعديلات. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/ar/lang.php b/lib/plugins/revert/lang/ar/lang.php
new file mode 100644
index 000000000..a073c336d
--- /dev/null
+++ b/lib/plugins/revert/lang/ar/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Arabic language file
+ *
+ * @author Yaman Hokan <always.smile.yh@hotmail.com>
+ * @author Usama Akkad <uahello@gmail.com>
+ * @author uahello@gmail.com
+ */
+$lang['menu'] = 'مدير الاسترجاع';
+$lang['filter'] = 'ابحث في الصفحات المتأذاة';
+$lang['revert'] = 'استرجع الصفحات المحددة';
+$lang['reverted'] = '%s استرجعت للاصدار %s';
+$lang['removed'] = 'حُذفت %s ';
+$lang['revstart'] = 'بدأت عملية الاستعادة. قد يستغرق ذلك وقتا طويلا. إذا كان وقت النص البرمجي ينفذ قبل النهاية، عليك استرجاع أجزاء أصغر.
+';
+$lang['revstop'] = 'عملية الاستعادة انتهت بنجاح.';
+$lang['note1'] = 'لاحظ: البحث حساس لحالة الأحرف';
+$lang['note2'] = 'لاحظ: ستسترجع الصفحة إلى آخر اصدار لا يحوي شروط الغثاء <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/bg/intro.txt b/lib/plugins/revert/lang/bg/intro.txt
new file mode 100644
index 000000000..44d5a0938
--- /dev/null
+++ b/lib/plugins/revert/lang/bg/intro.txt
@@ -0,0 +1,4 @@
+====== Възстановяване ======
+
+Страницата помага за автоматично възстановяване след SPAM атака. За да намерите спамнатите страници, въведете текст за търсене (напр. линк от SPAM съобщението), след това потвърдете, че намерените страници са наистина SPAM и възстановете старите им версии.
+
diff --git a/lib/plugins/revert/lang/bg/lang.php b/lib/plugins/revert/lang/bg/lang.php
new file mode 100644
index 000000000..0819de01a
--- /dev/null
+++ b/lib/plugins/revert/lang/bg/lang.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * bulgarian language file
+ * @author Nikolay Vladimirov <nikolay@vladimiroff.com>
+ * @author Viktor Usunov <usun0v@mail.bg>
+ * @author Kiril <neohidra@gmail.com>
+ */
+$lang['menu'] = 'Възстановяване';
+$lang['filter'] = 'Търсене на спамнати страници';
+$lang['revert'] = 'Възстанови избраните страници';
+$lang['reverted'] = '%s върната до версия %s';
+$lang['removed'] = '%s премахната';
+$lang['revstart'] = 'Процесът на възстановяване започна. Това може да отнеме много време. Ако скриптът се просрочи преди да завърши, трябва да възстановявате на по-малки парчета.';
+$lang['revstop'] = 'Процесът на възстановяване завърши успешно.';
+$lang['note1'] = 'Бележка: при търсенето се различават малки от големи букви';
+$lang['note2'] = 'Бележка: страницата ще бъде върната към стара версия без SPAM терминa <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/ca-valencia/intro.txt b/lib/plugins/revert/lang/ca-valencia/intro.txt
new file mode 100644
index 000000000..fed2cb9cc
--- /dev/null
+++ b/lib/plugins/revert/lang/ca-valencia/intro.txt
@@ -0,0 +1,4 @@
+====== Gestor de reversions ======
+
+Esta pàgina ajuda en la reversió automàtica d'atacs de spam. Per a
+trobar una llista de pàgines que tinguen spam introduïxca una cadena de busca (p. e. una URL de spam), confirme que les pàgines trobades tenen realment spam i revertixca les edicions.
diff --git a/lib/plugins/revert/lang/ca-valencia/lang.php b/lib/plugins/revert/lang/ca-valencia/lang.php
new file mode 100644
index 000000000..77dd5808e
--- /dev/null
+++ b/lib/plugins/revert/lang/ca-valencia/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * valencian language file
+ * @author Bernat Arlandis <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@llenguaitecnologia.com>
+ */
+$lang['menu'] = 'Gestor de reversions';
+$lang['filter'] = 'Buscar pàgines en spam';
+$lang['revert'] = 'Revertir pàgines seleccionades';
+$lang['reverted'] = '%s revertides a la versió %s';
+$lang['removed'] = '%s llevades';
+$lang['revstart'] = 'El procés de reversió ha començat. Açò pot dur prou de temps. Si es talla abans d\'acabar, haurà de revertir per parts.';
+$lang['revstop'] = 'El procés de reversió ha finalisat correctament.';
+$lang['note1'] = 'Nota: esta busca és sensible a mayúscules';
+$lang['note2'] = 'Nota: esta pàgina es revertirà a l\'última versió que no continga el spam definit pel terme <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/ca/intro.txt b/lib/plugins/revert/lang/ca/intro.txt
new file mode 100644
index 000000000..0af2e8e6d
--- /dev/null
+++ b/lib/plugins/revert/lang/ca/intro.txt
@@ -0,0 +1,3 @@
+====== Gestió de reversions ======
+
+Aquesta pàgina us ajuda a revertir automàticament els canvis que siguin producte d'un atac amb brossa. Per trobar la llista de pàgines atacades, cerqueu una cadena adequada (p. ex. un URL de propaganda), confirmeu que les pàgines trobades contenen realment brossa i llavors revertiu-les a revisions anteriors. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/ca/lang.php b/lib/plugins/revert/lang/ca/lang.php
new file mode 100644
index 000000000..b8800911f
--- /dev/null
+++ b/lib/plugins/revert/lang/ca/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Catalan language file
+ *
+ * @author Carles Bellver <carles.bellver@gmail.com>
+ * @author carles.bellver@gmail.com
+ * @author carles.bellver@cent.uji.es
+ * @author Carles Bellver <carles.bellver@cent.uji.es>
+ */
+$lang['menu'] = 'Gestió de reversions';
+$lang['filter'] = 'Cerca pàgines brossa';
+$lang['revert'] = 'Reverteix les pàgines seleccionades';
+$lang['reverted'] = 'S\'ha revertit %s a la revisió %s';
+$lang['removed'] = 'S\'ha suprimit %s';
+$lang['revstart'] = 'S\'ha iniciat el procés de reversió. Això pot trigar una bona estona. Si s\'excedeix el temps d\'espera màxim del servidor, haureu de tornar a intentar-ho per parts.';
+$lang['revstop'] = 'El procés de reversió ha acabat amb èxit.';
+$lang['note1'] = 'Nota: aquesta cerca distingeix entre majúscules i minúscules.';
+$lang['note2'] = 'Nota: la pàgina es revertirà a la darrera versió que no contingui el terme brossa especificat <em>%s</em>.';
diff --git a/lib/plugins/revert/lang/cs/intro.txt b/lib/plugins/revert/lang/cs/intro.txt
new file mode 100644
index 000000000..1e1cd0fd8
--- /dev/null
+++ b/lib/plugins/revert/lang/cs/intro.txt
@@ -0,0 +1,3 @@
+====== Obnova zaspamovaných stránek ======
+
+Tato stránka pomůže při automatické obnově po spamovém útoku. Pro nalezení seznamu zaspamovaných stránek nejdříve zadejte hledaný výraz (např. spamové URL) a pak potvrďte, že nalezené stránky opravdu obsahují spam a mohou být obnoveny.
diff --git a/lib/plugins/revert/lang/cs/lang.php b/lib/plugins/revert/lang/cs/lang.php
new file mode 100644
index 000000000..cf19381c8
--- /dev/null
+++ b/lib/plugins/revert/lang/cs/lang.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Czech language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Bohumir Zamecnik <bohumir@zamecnik.org>
+ * @author Zbynek Krivka <zbynek.krivka@seznam.cz>
+ * @author tomas@valenta.cz
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @author Lefty <lefty@multihost.cz>
+ * @author Vojta Beran <xmamut@email.cz>
+ * @author zbynek.krivka@seznam.cz
+ */
+$lang['menu'] = 'Obnova zaspamovaných stránek';
+$lang['filter'] = 'Hledat zaspamované stránky';
+$lang['revert'] = 'Obnovit vybrané stránky';
+$lang['reverted'] = '%s vrácena do verze %s';
+$lang['removed'] = '%s odstraněna';
+$lang['revstart'] = 'Obnova stránek začala. Tento proces může trvat dlouho. Pokud
+skriptu vyprší čas, budete muset obnovovat po menších blocích
+stránek.';
+$lang['revstop'] = 'Proces obnovy stránek byl úspěšně dokončen.';
+$lang['note1'] = 'Poznámka: toto vyhledávání je citlivé na velikost písmen';
+$lang['note2'] = 'Poznámka: tato stránka bude obnovena na poslední verzi, která
+neobsahovala dané spamové slovo <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/da/intro.txt b/lib/plugins/revert/lang/da/intro.txt
new file mode 100644
index 000000000..fdb0c5f32
--- /dev/null
+++ b/lib/plugins/revert/lang/da/intro.txt
@@ -0,0 +1,3 @@
+===== Gendannelsesstyring =====
+
+Denne side hjælper dig med at gendanne sider efter et angreb af uønskede indlæg. For at finde en liste af sider, der muligvis er blevet ændret, så skriv en søgestreng (for eksempel. en uønsket netadresse) og bekræft, at de fundne sider virkeligt er uønskede og gendan ændringerne. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/da/lang.php b/lib/plugins/revert/lang/da/lang.php
new file mode 100644
index 000000000..c94366638
--- /dev/null
+++ b/lib/plugins/revert/lang/da/lang.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Danish language file
+ *
+ * @author Kalle Sommer Nielsen <kalle@php.net>
+ * @author Esben Laursen <hyber@hyber.dk>
+ * @author Harith <haj@berlingske.dk>
+ * @author Daniel Ejsing-Duun <dokuwiki@zilvador.dk>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author rasmus@kinnerup.com
+ * @author Michael Pedersen subben@gmail.com
+ */
+$lang['menu'] = 'Gendannelsesstyring';
+$lang['filter'] = 'Søg efter uønskede sider';
+$lang['revert'] = 'Gendan valgte sider';
+$lang['reverted'] = '%s gendannet til ændring %s';
+$lang['removed'] = '%s fjernet';
+$lang['revstart'] = 'Gendannelsesforløbet er startet. Dette kan tage et stykke tid. Hvis kodefilen giver "time out" før processen færdiggøres, skal du gendanne i mindre dele.';
+$lang['revstop'] = 'Gendannelsesforløbet fuldført uden fejl';
+$lang['note1'] = 'Bemærk: Der er forskel på store og små bogstaver i søgningen';
+$lang['note2'] = 'Bemærk: Denne side vil blive gendannet til den seneste udgave, der ikke indeholder det givne uønskede udtryk <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/de-informal/intro.txt b/lib/plugins/revert/lang/de-informal/intro.txt
new file mode 100644
index 000000000..d5a092155
--- /dev/null
+++ b/lib/plugins/revert/lang/de-informal/intro.txt
@@ -0,0 +1,3 @@
+====== Seiten wieder herstellen ======
+
+Dieses Plugin dient der automatischen Wiederherstellung von Seiten nach einem Spam-Angriff. Geben Sie zunächst einen Suchbegriff (z.B. eine Spam URL) ein um eine Liste betroffener Seiten zu erhalten. Nachdem Sie sich vergewissert haben, dass die gefundenen Seiten wirklich Spam enthalten, können Sie die Seiten wieder herstellen.
diff --git a/lib/plugins/revert/lang/de-informal/lang.php b/lib/plugins/revert/lang/de-informal/lang.php
new file mode 100644
index 000000000..c199bb55b
--- /dev/null
+++ b/lib/plugins/revert/lang/de-informal/lang.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * German (informal) language file
+ *
+ * @author Alexander Fischer <tbanus@os-forge.net>
+ * @author Juergen Schwarzer <jschwarzer@freenet.de>
+ * @author Marcel Metz <marcel_metz@gmx.de>
+ * @author Matthias Schulte <post@lupo49.de>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Zurückstellungsmanager';
+$lang['filter'] = 'Durchsuche als Spam markierte Seiten';
+$lang['revert'] = 'Setze ausgewählte Seiten zurück.';
+$lang['reverted'] = '%s zu Revision %s zurückgesetzt';
+$lang['removed'] = '%s entfernt';
+$lang['revstart'] = 'Zurückstellungsprozess gestartet. Dies kann eine längere Zeit dauern. Wenn das Skript vor Fertigstellung stoppt, solltest du es in kleineren Stücken versuchen.';
+$lang['revstop'] = 'Zurückstellungsprozess erfolgreich beendet.';
+$lang['note1'] = 'Beachte: Diese Suche berücksichtigt Gross- und Kleinschreibung';
+$lang['note2'] = 'Beachte: Diese Seite wid zurückgestellt auf die letzte Version, die nicht den Spam-Ausdruck <i>%s</i> enthält.';
diff --git a/lib/plugins/revert/lang/de/intro.txt b/lib/plugins/revert/lang/de/intro.txt
new file mode 100644
index 000000000..d5a092155
--- /dev/null
+++ b/lib/plugins/revert/lang/de/intro.txt
@@ -0,0 +1,3 @@
+====== Seiten wieder herstellen ======
+
+Dieses Plugin dient der automatischen Wiederherstellung von Seiten nach einem Spam-Angriff. Geben Sie zunächst einen Suchbegriff (z.B. eine Spam URL) ein um eine Liste betroffener Seiten zu erhalten. Nachdem Sie sich vergewissert haben, dass die gefundenen Seiten wirklich Spam enthalten, können Sie die Seiten wieder herstellen.
diff --git a/lib/plugins/revert/lang/de/lang.php b/lib/plugins/revert/lang/de/lang.php
new file mode 100644
index 000000000..b430ce876
--- /dev/null
+++ b/lib/plugins/revert/lang/de/lang.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Germanlanguage file
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Dirk Einecke <dirk@dirkeinecke.de>
+ * @author Blitzi94@gmx.de
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Niels Lange <niels@boldencursief.nl>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Paul Lachewsky <kaeptn.haddock@gmail.com>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Seiten wieder herstellen';
+$lang['filter'] = 'Nach betroffenen Seiten suchen';
+$lang['revert'] = 'Ausgewählte Seiten wieder herstellen';
+$lang['reverted'] = '%s wieder hergestellt zu Version %s';
+$lang['removed'] = '%s entfernt';
+$lang['revstart'] = 'Wiederherstellung gestartet. Dies kann einige Zeit dauern. Wenn das Script abbricht, bevor alle Seiten wieder hergestellt wurden, reduzieren Sie die Anzahl der Seiten und wiederholen Sie den Vorgang.';
+$lang['revstop'] = 'Wiederherstellung erfolgreich abgeschlossen.';
+$lang['note1'] = 'Anmerkung: diese Suche unterscheidet Groß- und Kleinschreibung';
+$lang['note2'] = 'Anmerkung: die Seite wird zur letzten Version, die nicht den angegebenen Spam Begriff <i>%s</i> enthält, wieder hergestellt.';
diff --git a/lib/plugins/revert/lang/el/intro.txt b/lib/plugins/revert/lang/el/intro.txt
new file mode 100644
index 000000000..9b583bc6b
--- /dev/null
+++ b/lib/plugins/revert/lang/el/intro.txt
@@ -0,0 +1,3 @@
+====== Αποκατάσταση κακόβουλων αλλαγών σελίδων ======
+
+Αυτή η σελίδα σας βοηθά να αποκαταστήσετε αυτόματα τις κακόβουλες αλλαγές σελίδων που προκαλούν οι επιθέσεις spam. Για να βρείτε τις σελίδες που πρέπει να τροποποιηθούν, πρώτα δώστε έναν όρο αναζήτησης (π.χ. έναν σύνδεσμο spam) και έπειτα επιβεβαιώστε ότι οι σελίδες που θα βρεθούν όντως περιέχουν spam και προχωρήστε στην αποκατάστασή τους.
diff --git a/lib/plugins/revert/lang/el/lang.php b/lib/plugins/revert/lang/el/lang.php
new file mode 100644
index 000000000..63454e4e9
--- /dev/null
+++ b/lib/plugins/revert/lang/el/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Greek language file
+ *
+ * Based on DokuWiki Version rc2007-05-24 english language file
+ * Original english language file contents included for reference
+ *
+ * @author Thanos Massias <tm@thriasio.gr>
+ * @author Αθανάσιος Νταής <homunculus@wana.gr>
+ * @author Konstantinos Koryllos <koryllos@gmail.com>
+ * @author George Petsagourakis <petsagouris@gmail.com>
+ * @author Petros Vidalis <pvidalis@gmail.com>
+ */
+$lang['menu'] = 'Αποκατάσταση κακόβουλων αλλαγών σελίδων';
+$lang['filter'] = 'Αναζήτηση σελίδων που περιέχουν spam';
+$lang['revert'] = 'Επαναφορά παλαιότερων εκδόσεων των επιλεγμένων σελίδων';
+$lang['reverted'] = 'Η σελίδα %s επεναφέρθηκε στην έκδοση %s';
+$lang['removed'] = 'Η σελίδα %s διαγράφηκε';
+$lang['revstart'] = 'Η διαδικασία αποκατάστασης άρχισε. Αυτό ίσως πάρει αρκετό χρόνο. Εάν η εφαρμογή υπερβεί το διαθέσιμο χρονικό όριο και τερματιστεί πριν τελειώσει, θα χρειαστεί να επαναλάβετε αυτή τη διαδικασία για μικρότερα τμήματα.';
+$lang['revstop'] = 'Η διαδικασία αποκατάστασης ολοκληρώθηκε με επιτυχία.';
+$lang['note1'] = '<br />Σημείωση: η αναζήτηση επηρεάζεται από το εάν οι χαρακτήρες είναι πεζοί ή κεφαλαίοι';
+$lang['note2'] = '<br />Σημείωση: η σελίδα θα επαναφερθεί στην πλέον πρόσφατη έκδοση που δεν περιέχει τον όρο <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/en/intro.txt b/lib/plugins/revert/lang/en/intro.txt
new file mode 100644
index 000000000..b8f355854
--- /dev/null
+++ b/lib/plugins/revert/lang/en/intro.txt
@@ -0,0 +1,3 @@
+====== Revert Manager ======
+
+This page helps you with the automatic reversion of a spam attack. To find a list of spammy pages first enter a search string (eg. a spam URL), then confirm that the found pages are really spam and revert the edits.
diff --git a/lib/plugins/revert/lang/en/lang.php b/lib/plugins/revert/lang/en/lang.php
new file mode 100644
index 000000000..6bf867ded
--- /dev/null
+++ b/lib/plugins/revert/lang/en/lang.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * english language file
+ */
+
+// for admin plugins, the menu prompt to be displayed in the admin menu
+// if set here, the plugin doesn't need to override the getMenuText() method
+$lang['menu'] = 'Revert Manager';
+
+// custom language strings for the plugin
+
+$lang['filter'] = 'Search spammy pages';
+$lang['revert'] = 'Revert selected pages';
+$lang['reverted'] = '%s reverted to revision %s';
+$lang['removed'] = '%s removed';
+$lang['revstart'] = 'Reversion process started. This can take a long time. If the
+ script times out before finishing, you need to revert in smaller
+ chunks.';
+$lang['revstop'] = 'Reversion process finished successfully.';
+$lang['note1'] = 'Note: this search is case sensitive';
+$lang['note2'] = 'Note: the page will be reverted to the last version not containing the given spam term <i>%s</i>.';
+
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/plugins/revert/lang/eo/intro.txt b/lib/plugins/revert/lang/eo/intro.txt
new file mode 100644
index 000000000..14e831467
--- /dev/null
+++ b/lib/plugins/revert/lang/eo/intro.txt
@@ -0,0 +1,3 @@
+====== Administro de Restarigo ======
+
+Tiu ĉi paĝo helpas vin pri aŭtomata restarigo el spama atako. Por trovi liston de spamecaj paĝoj, unue mendu serĉan liter-ĉenon (ekz. spama URL), do konfirmu, ke la trovitaj paĝoj fakte estas spamaj kaj restarigu la antaŭajn versiojn bonajn.
diff --git a/lib/plugins/revert/lang/eo/lang.php b/lib/plugins/revert/lang/eo/lang.php
new file mode 100644
index 000000000..a893fb145
--- /dev/null
+++ b/lib/plugins/revert/lang/eo/lang.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Esperantolanguage file
+ *
+ * @author Felipe Castro <fefcas@uol.com.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Felipe Castro <fefcas (cxe) gmail (punkto) com>
+ * @author Felipo Kastro <fefcas@gmail.com>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Erik Pedersen <erik pedersen@shaw.ca>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert BOGENSCHNEIDER <robog@gmx.de>
+ * @author Robert BOGENSCHNEIDER <bogi@UEA.org>
+ */
+$lang['menu'] = 'Administrado de restarigo';
+$lang['filter'] = 'Serĉi spamecajn paĝojn';
+$lang['revert'] = 'Restarigi la elektitajn paĝojn';
+$lang['reverted'] = '%s estas restarigita al revizio %s';
+$lang['removed'] = '%s estas forigita';
+$lang['revstart'] = 'Restariga procezo estas ekigita. Tio povas daŭri longan tempon. Se la skripto tro prokrastos antaŭ plenumo, vi bezonos restarigi po pli etaj blokoj.';
+$lang['revstop'] = 'Restariga procezo plenumiĝis sukcese.';
+$lang['note1'] = 'Rimarko: tiu ĉi serĉo distingas usklecon';
+$lang['note2'] = 'Rimarko: la paĝo restariĝos al la lasta versio ne enhavanta la menditan spaman terminon &lt;i&gt;%s&lt;/i&gt;.';
diff --git a/lib/plugins/revert/lang/es/intro.txt b/lib/plugins/revert/lang/es/intro.txt
new file mode 100644
index 000000000..39c5b047d
--- /dev/null
+++ b/lib/plugins/revert/lang/es/intro.txt
@@ -0,0 +1,3 @@
+====== Restaurador ======
+
+Esta página te ayuda con la restauración de ataques spam. Para encontrar una lista de páginas con spam introduce una cadena , luego confirma que las páginas encontradas son realmente un spam y restaura la edición. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/es/lang.php b/lib/plugins/revert/lang/es/lang.php
new file mode 100644
index 000000000..e235015d4
--- /dev/null
+++ b/lib/plugins/revert/lang/es/lang.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Spanish language file
+ *
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ * @author Gabriel Castillo <gch@pumas.ii.unam.mx>
+ * @author oliver@samera.com.py
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Manuel Meco <manuel.meco@gmail.com>
+ * @author VictorCastelan <victorcastelan@gmail.com>
+ * @author Jordan Mero hack.jord@gmail.com
+ * @author Felipe Martinez <metalmartinez@gmail.com>
+ * @author Javier Aranda <internet@javierav.com>
+ * @author Zerial <fernando@zerial.org>
+ * @author Marvin Ortega <maty1206@maryanlinux.com>
+ * @author Daniel Castro Alvarado <dancas2@gmail.com>
+ * @author Fernando J. Gómez <fjgomez@gmail.com>
+ * @author Victor Castelan <victorcastelan@gmail.com>
+ * @author Mauro Javier Giamberardino <mgiamberardino@gmail.com>
+ * @author emezeta <emezeta@infoprimo.com>
+ * @author Oscar Ciudad <oscar@jacho.net>
+ * @author Ruben Figols <ruben.figols@gmail.com>
+ */
+$lang['menu'] = 'Restaurador';
+$lang['filter'] = 'Buscar páginas con spam';
+$lang['revert'] = 'Restaurar las páginas seleccionadas';
+$lang['reverted'] = '%s ha restaurado la revisión %s';
+$lang['removed'] = '%s borrado';
+$lang['revstart'] = 'El proceso de restaurado ha comenzado. Puede llevar bastante tiempo. Si el script se para antes de acabar, deberías restaurar cadenas más pequeñas.';
+$lang['revstop'] = 'El proceso de restaurado ha finalizado satisfactoriamente.';
+$lang['note1'] = 'Nota: la búsqueda diferencia entre mayúsculas y minúsculas.';
+$lang['note2'] = 'Nota: la página será restaurada a la última versión que no tenga el término de spam dado <em>%s</em>.';
diff --git a/lib/plugins/revert/lang/et/lang.php b/lib/plugins/revert/lang/et/lang.php
new file mode 100644
index 000000000..ca1410ab0
--- /dev/null
+++ b/lib/plugins/revert/lang/et/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Estonian language file
+ *
+ * @author kristian.kankainen@kuu.la
+ * @author Rivo Zängov <eraser@eraser.ee>
+ */
diff --git a/lib/plugins/revert/lang/eu/intro.txt b/lib/plugins/revert/lang/eu/intro.txt
new file mode 100644
index 000000000..c5a5a5afa
--- /dev/null
+++ b/lib/plugins/revert/lang/eu/intro.txt
@@ -0,0 +1,3 @@
+====== Berrezartze Kudeatzailea ======
+
+Orri honek spam eraso baten berrezartze automatikoarekin laguntzen dizu. Spam-a duten orriak bilatzeko, lehenik sartu bilaketa katea (adb. spam URL bat), eta ondoren baieztatu bilatutako orriak benetan spam-a dutela, gero aldaketak berrezartzeko.
diff --git a/lib/plugins/revert/lang/eu/lang.php b/lib/plugins/revert/lang/eu/lang.php
new file mode 100644
index 000000000..e94f07b2a
--- /dev/null
+++ b/lib/plugins/revert/lang/eu/lang.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Basque language file
+ *
+ * @author Inko Illarramendi <inko.i.a@gmail.com>
+ */
+$lang['menu'] = 'Berrezartze Kudeatzailea';
+$lang['filter'] = 'Bilatu spam duten orriak';
+$lang['revert'] = 'Berrezarri aukeratutako orriak';
+$lang['reverted'] = '%s berrezarria %s berrikuspenera';
+$lang['removed'] = '%s ezabatua';
+$lang['revstart'] = 'Berrezartze prozesua hasi da. Honek denbora luzea eraman dezake.
+Script-a denbora mugara iristen bada, zati txikiagotan berrezarri
+beharko duzu. ';
+$lang['revstop'] = 'Berrezartze prozesua arrakastaz bukatu da.';
+$lang['note1'] = 'Oharra: bilaketa honek maiuskulak eta minuskulak bereizten ditu';
+$lang['note2'] = 'Oharra: orria azken bertsiora berrezarriko da, emandako <i>%s</i> spam terminorik ez duelarik.';
diff --git a/lib/plugins/revert/lang/fa/intro.txt b/lib/plugins/revert/lang/fa/intro.txt
new file mode 100644
index 000000000..0ccdb089a
--- /dev/null
+++ b/lib/plugins/revert/lang/fa/intro.txt
@@ -0,0 +1,3 @@
+====== مدیریت برگشت‌ها ======
+
+این صفحه، در بازیابی صفحاتی که به آن‌ها اسپم ارسال شده است کمک می‌رساند. برای مشاهده‌ی صفحات اسپم شده، ابتدا جستجو کنید، سپس از اسپم شدن صفحه‌ی مورد نظر اطمینان حاصل کنید و تغییرات اعمال شده را برگردانید. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/fa/lang.php b/lib/plugins/revert/lang/fa/lang.php
new file mode 100644
index 000000000..02d2aabd2
--- /dev/null
+++ b/lib/plugins/revert/lang/fa/lang.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Persian language file
+ *
+ * @author behrad eslamifar <behrad_es@yahoo.com)
+ * @author Mohsen Firoozmandan <info@mambolearn.com>
+ * @author omidmr@gmail.com
+ * @author Omid Mottaghi <omidmr@gmail.com>
+ * @author Mohammad Reza Shoaei <shoaei@gmail.com>
+ */
+$lang['menu'] = 'مدیریت برگشت‌ها';
+$lang['filter'] = 'جستجوی صفحات اسپم شده';
+$lang['revert'] = 'بازگردانی صفحات انتخاب شده';
+$lang['reverted'] = '%s به نگارش %s بازگردانده شد';
+$lang['removed'] = '%s حذف شد';
+$lang['revstart'] = 'در حال بازگرداندن. ممکن است مدتی زمان ببرد. اگر اجرای برنامه، پیش از اتمام به پایان رسید، باید در بخش‌های کوچک‌تری بازگردانی را انجام دهید.';
+$lang['revstop'] = 'بازگرداندن با موفقیت به پایان رسید.';
+$lang['note1'] = 'توجه: جستجو حساس به حروف کوچک و بزرگ است';
+$lang['note2'] = 'توجه: صفحه به آخرین نسخه‌ای که حاوی اسپم <i>%s</i> نیست بازگردانده خواهد شد.';
diff --git a/lib/plugins/revert/lang/fi/intro.txt b/lib/plugins/revert/lang/fi/intro.txt
new file mode 100644
index 000000000..3b3ce5daa
--- /dev/null
+++ b/lib/plugins/revert/lang/fi/intro.txt
@@ -0,0 +1,3 @@
+====== Palautuksenhallinta ======
+
+Tämä sivu auttaa sinua automaattisen palautuksenhallinnan kanssa spam hyökkäyksen jälkeen. Löytääksesi listan spammatyistä sivuista anna ensin hakusana (esim. spm URL), sen jälkeen varmista, että löytyneet sivut todella ovat spammia ja palauta sitten sivut.
diff --git a/lib/plugins/revert/lang/fi/lang.php b/lib/plugins/revert/lang/fi/lang.php
new file mode 100644
index 000000000..fdf9bb81c
--- /dev/null
+++ b/lib/plugins/revert/lang/fi/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Finnish language file
+ *
+ * @author otto@valjakko.net
+ * @author Otto Vainio <otto@valjakko.net>
+ * @author Teemu Mattila <ghcsystems@gmail.com>
+ * @author Sami Olmari <sami@olmari.fi>
+ */
+$lang['menu'] = 'Palautuksenhallinta';
+$lang['filter'] = 'Etsi spammattyjä sivuja';
+$lang['revert'] = 'Palauta valitut sivut';
+$lang['reverted'] = '%s palautettu versioon %s';
+$lang['removed'] = '%s poistettu';
+$lang['revstart'] = 'Palautusprosessi käynnistetty. Tämä voi viedä pidemmän aikaa. Jos ajo katkeaa aikakatkaisuun ennen loppua, niin sinun pitää palauttaa pienemmissä osissa.';
+$lang['revstop'] = 'Palautusprosessi lopetti onnistuneesti.';
+$lang['note1'] = 'Huomioi: tämä haku on kirjainkoosta riippuva';
+$lang['note2'] = 'Huomioi: tämä sivu palautetaan viimeiseen versioon, jossa ei ole annettua spamtermiä <i>%s</i>';
diff --git a/lib/plugins/revert/lang/fr/intro.txt b/lib/plugins/revert/lang/fr/intro.txt
new file mode 100644
index 000000000..6dcbe74b9
--- /dev/null
+++ b/lib/plugins/revert/lang/fr/intro.txt
@@ -0,0 +1,3 @@
+====== Gestionnaire de réversions ======
+
+Cette page peut vous aider à restaurer des pages après une attaque de spam. Pour trouver la liste des pages vandalisées, entrez un motif de recherche (p. ex. une URL de spam), puis confirmez que les pages trouvées contiennent du spam et annulez leurs éditions.
diff --git a/lib/plugins/revert/lang/fr/lang.php b/lib/plugins/revert/lang/fr/lang.php
new file mode 100644
index 000000000..9c5194b31
--- /dev/null
+++ b/lib/plugins/revert/lang/fr/lang.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * french language file
+ * @author Delassaux Julien <julien@delassaux.fr>
+ * @author Maurice A. LeBlanc <leblancma@cooptel.qc.ca>
+ * @author Guy Brand <gb@unistra.fr>
+ * @author stephane.gully@gmail.com
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author olivier duperray <duperray.olivier@laposte.net>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author Philippe Bajoit <philippe.bajoit@gmail.com>
+ * @author Florian Gaub <floriang@floriang.net>
+ * @author Samuel Dorsaz samuel.dorsaz@novelion.net
+ * @author Johan Guilbaud <guilbaud.johan@gmail.com>
+ * @author schplurtz@laposte.net
+ * @author skimpax@gmail.com
+ */
+$lang['menu'] = 'Gestionnaire de réversions';
+$lang['filter'] = 'Trouver les pages spammées ';
+$lang['revert'] = 'Annuler les modifications sélectionnées';
+$lang['reverted'] = '%s restauré à la révision %s';
+$lang['removed'] = '%s supprimé';
+$lang['revstart'] = 'Processus de réversion démarré. Ceci peut prendre longtemps. Si le script dépasse le délai avant de terminer, vous devrez restaurer de plus petits groupes de pages.';
+$lang['revstop'] = 'Processus de réversion terminé avec succès.';
+$lang['note1'] = 'Note : cette recherche est insensible à la casse';
+$lang['note2'] = 'Note : cette page sera révisée à la version précédente ne contenant pas le terme spammeur <em>%s</em>.';
diff --git a/lib/plugins/revert/lang/gl/intro.txt b/lib/plugins/revert/lang/gl/intro.txt
new file mode 100644
index 000000000..6327249fc
--- /dev/null
+++ b/lib/plugins/revert/lang/gl/intro.txt
@@ -0,0 +1,3 @@
+====== Xestor de Reversión ======
+
+Esta páxina axudarache a revertir automaticamente un ataque de correo-lixo. Para atopares unha listaxe de páxinas que conteñan correo-lixo, primeiro debes inserir unha cadea de procura (p.e. un URL do correo-lixo), e logo confirmares que as páxinas atopadas conteñen realmente o tal correo-lixo e reverter as edicións. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/gl/lang.php b/lib/plugins/revert/lang/gl/lang.php
new file mode 100644
index 000000000..a0c5a9785
--- /dev/null
+++ b/lib/plugins/revert/lang/gl/lang.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Galicianlanguage file
+ *
+ * @author Medúlio <medulio@ciberirmandade.org>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ */
+$lang['menu'] = 'Xestor de Reversión';
+$lang['filter'] = 'Procurar páxinas con correo-lixo';
+$lang['revert'] = 'Revertir as páxinas seleccionadas';
+$lang['reverted'] = '%s revertido á revisión %s';
+$lang['removed'] = '%s eliminado';
+$lang['revstart'] = 'Proceso de reversión iniciado. Isto podería demorar un anaco longo. Se o script fallar por superar o seu límite de tempo denantes de rematar, terás que facer a reversión en anacos máis pequenos.';
+$lang['revstop'] = 'O proceso de reversión rematou correctamente.';
+$lang['note1'] = 'Nota: esta procura distingue entre maiúsculas e minúsculas';
+$lang['note2'] = 'Nota: a páxina revertirase á última versión que non conteña o termo de correo-lixo <i>%s</i> indicado.';
diff --git a/lib/plugins/revert/lang/he/intro.txt b/lib/plugins/revert/lang/he/intro.txt
new file mode 100644
index 000000000..44b78dfea
--- /dev/null
+++ b/lib/plugins/revert/lang/he/intro.txt
@@ -0,0 +1,3 @@
+====== מנהל השחזור ======
+
+דף זה יסיע בידך לשחזר באופן אוטומטי אחרי התקפת ספאם. כדי לקבל את רשימת הדפים עם הספאם עליך ראשית מחרוזת לחיפוש (לדוגמה כתובת ספאם) אחר כך עליך לאשר שהדפים שנמצאו באמת מכילים ספאם ולשחזר את העריכות.
diff --git a/lib/plugins/revert/lang/he/lang.php b/lib/plugins/revert/lang/he/lang.php
new file mode 100644
index 000000000..ac3c3412e
--- /dev/null
+++ b/lib/plugins/revert/lang/he/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Hebrew language file
+ *
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ * @author Moshe Kaplan <mokplan@gmail.com>
+ * @author Yaron Yogev <yaronyogev@gmail.com>
+ * @author Yaron Shahrabani <sh.yaron@gmail.com>
+ */
+$lang['menu'] = 'מנהל שחזור';
+$lang['filter'] = 'חפש דפים עם ספאם';
+$lang['revert'] = 'שחזר את הדפים הנבחרים';
+$lang['reverted'] = '%s שוחזרו לגרסה %s';
+$lang['removed'] = '%s הוסרו';
+$lang['revstart'] = 'תהליך השחזור החל. התהליך עלול להיות ממושך. אם תסריט מגיע למגבלת פסק הזמן לפני שהסתיים התהליך יהיה צורך לבצע את השחזור במקטעים קטנים יותר.';
+$lang['revstop'] = 'תהליך השחזור הושלם בהצלחה.';
+$lang['note1'] = 'לתשומת לבך: החיפוש ער לגודל האותיות הלועזיות.';
+$lang['note2'] = 'לתשות לבך: הדף ישוחזר לגרסה האחרונה שאינה מכילה את מונח הספאם <i>%s</i>';
diff --git a/lib/plugins/revert/lang/hi/lang.php b/lib/plugins/revert/lang/hi/lang.php
new file mode 100644
index 000000000..d6f78ffd6
--- /dev/null
+++ b/lib/plugins/revert/lang/hi/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Hindi language file
+ *
+ * @author Abhinav Tyagi <abhinavtyagi11@gmail.com>
+ * @author yndesai@gmail.com
+ */
diff --git a/lib/plugins/revert/lang/hr/lang.php b/lib/plugins/revert/lang/hr/lang.php
new file mode 100644
index 000000000..96f1d6afe
--- /dev/null
+++ b/lib/plugins/revert/lang/hr/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Croatian language file
+ *
+ * @author Branko Rihtman <theney@gmail.com>
+ * @author Dražen Odobašić <dodobasic@gmail.com>
+ * @author Dejan Igrec dejan.igrec@gmail.com
+ */
diff --git a/lib/plugins/revert/lang/hu/intro.txt b/lib/plugins/revert/lang/hu/intro.txt
new file mode 100644
index 000000000..e2c2dadd9
--- /dev/null
+++ b/lib/plugins/revert/lang/hu/intro.txt
@@ -0,0 +1,3 @@
+====== Visszaállítás kezelő ======
+
+Segítséget nyújtunk SPAM támadások utáni automatikus visszaállításhoz. A fertőzött oldalak kereséséhez meg kell adni egy karaktersorozatot (pl. egy SPAM URL-t). A találatok közül kiválasztva a valóban SPAM-et tartalmazó oldakat, visszaállítjuk őket a lehetséges utolsó SPAM mentes állapotra. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/hu/lang.php b/lib/plugins/revert/lang/hu/lang.php
new file mode 100644
index 000000000..058a63196
--- /dev/null
+++ b/lib/plugins/revert/lang/hu/lang.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Hungarian language file
+ *
+ * @author Sandor TIHANYI <stihanyi+dw@gmail.com>
+ * @author Siaynoq Mage <siaynoqmage@gmail.com>
+ * @author schilling.janos@gmail.com
+ * @author Szabó Dávid <szabo.david@gyumolcstarhely.hu>
+ * @author Sándor TIHANYI <stihanyi+dw@gmail.com>
+ * @author David Szabo <szabo.david@gyumolcstarhely.hu>
+ */
+$lang['menu'] = 'Visszaállítás kezelő (anti-SPAM)';
+$lang['filter'] = 'SPAM tartalmú oldalak keresése';
+$lang['revert'] = 'Kiválasztott oldalak visszaállítása';
+$lang['reverted'] = '%s a következő változatra lett visszaállítva: %s';
+$lang['removed'] = '%s törölve';
+$lang['revstart'] = 'A visszaállítási folyamat elindult. Ez hosszú ideig eltarthat. Ha időtúllépés miatt nem tud lefutni, kisebb darabbal kell próbálkozni.';
+$lang['revstop'] = 'A visszaállítási folyamat sikeresen befejeződött.';
+$lang['note1'] = 'Megjegyzés: a keresés kisbetű-nagybetűre érzékeny';
+$lang['note2'] = 'Megjegyzés: Az oldalt az utolsó olyan változatra állítjuk vissza, ami nem tartalmazza a megadott spam kifejezést: <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/ia/intro.txt b/lib/plugins/revert/lang/ia/intro.txt
new file mode 100644
index 000000000..ae548e9df
--- /dev/null
+++ b/lib/plugins/revert/lang/ia/intro.txt
@@ -0,0 +1,3 @@
+====== Gestion de reversiones ======
+
+Iste pagina te adjuta con le reversion automatic de un attacco de spam. Pro cercar un lista de paginas spammose, primo entra un texto a cercar (p.ex. un URL de spam), postea confirma que le paginas trovate es realmente spam e reverte le modificationes. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/ia/lang.php b/lib/plugins/revert/lang/ia/lang.php
new file mode 100644
index 000000000..bec2eca7b
--- /dev/null
+++ b/lib/plugins/revert/lang/ia/lang.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Interlingua language file
+ *
+ * @author robocap <robocap1@gmail.com>
+ * @author Martijn Dekker <martijn@inlv.org>
+ */
+$lang['menu'] = 'Gestion de reversiones';
+$lang['filter'] = 'Cercar paginas spammose';
+$lang['revert'] = 'Reverter le paginas seligite';
+$lang['reverted'] = '%s revertite al version %s';
+$lang['removed'] = '%s removite';
+$lang['revstart'] = 'Le processo de reversion ha comenciate. Isto pote durar multo. Si le script expira ante de finir, tu debe divider le reversiones in blocos minor.';
+$lang['revstop'] = 'Le processo de reversion ha succedite.';
+$lang['note1'] = 'Nota: iste recerca distingue inter majusculas e minusculas.';
+$lang['note2'] = 'Nota: le pagina essera revertite al ultime version que non contine le termino de spam specificate, <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/id-ni/lang.php b/lib/plugins/revert/lang/id-ni/lang.php
new file mode 100644
index 000000000..d367340b7
--- /dev/null
+++ b/lib/plugins/revert/lang/id-ni/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * idni language file
+ *
+ * @author Harefa <fidelis@harefa.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/revert/lang/id/lang.php b/lib/plugins/revert/lang/id/lang.php
new file mode 100644
index 000000000..c3d485930
--- /dev/null
+++ b/lib/plugins/revert/lang/id/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Indonesian language file
+ *
+ * @author Irwan Butar Butar <irwansah.putra@gmail.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/revert/lang/is/lang.php b/lib/plugins/revert/lang/is/lang.php
new file mode 100644
index 000000000..9de404992
--- /dev/null
+++ b/lib/plugins/revert/lang/is/lang.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Icelandic language file
+ *
+ * @author Hrannar Baldursson <hrannar.baldursson@gmail.com>
+ * @author Ólafur Gunnlaugsson <oli@audiotools.com>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ */
+$lang['removed'] = '%s eytt';
+$lang['note1'] = 'Athugaðu að þegar leitað er þá skiftir stafsetur máli, það að segja leitarvélin gerir mun á hástöfum og lágstöfum';
diff --git a/lib/plugins/revert/lang/it/intro.txt b/lib/plugins/revert/lang/it/intro.txt
new file mode 100644
index 000000000..a5ef14680
--- /dev/null
+++ b/lib/plugins/revert/lang/it/intro.txt
@@ -0,0 +1,3 @@
+====== Gestore di ripristini ======
+
+Questa pagina aiuta il controllo automatico degli attacchi spam. Per cercare una lista delle pagine con spam, inserisci innanzitutto una stringa di ricerca (ad esempio l'URL di un sito di spam), quindi Verifica che le pagine trovate contengano realmente spam e ripristinale ad una versione precedente.
diff --git a/lib/plugins/revert/lang/it/lang.php b/lib/plugins/revert/lang/it/lang.php
new file mode 100644
index 000000000..79565655b
--- /dev/null
+++ b/lib/plugins/revert/lang/it/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Italian language file
+ *
+ * @author Pietro Battiston toobaz@email.it
+ * @author Diego Pierotto ita.translations@tiscali.it
+ * @author ita.translations@tiscali.it
+ * @author Lorenzo Breda <lbreda@gmail.com>
+ * @author snarchio@alice.it
+ * @author robocap <robocap1@gmail.com>
+ * @author Osman Tekin osman.tekin93@hotmail.it
+ * @author Jacopo Corbetta <jacopo.corbetta@gmail.com>
+ */
+$lang['menu'] = 'Gestore di ripristini';
+$lang['filter'] = 'Cerca pagine con spam';
+$lang['revert'] = 'Ripristina le pagine selezionate';
+$lang['reverted'] = '%s ripristinata alla versione %s';
+$lang['removed'] = '%s rimossa';
+$lang['revstart'] = 'Processo di ripristino avviato. Può essere necessario molto tempo. Se lo script non fa in tempo a finire, sarà necessario ripristinare in blocchi più piccoli.';
+$lang['revstop'] = 'Processo di ripristino finito con successo.';
+$lang['note1'] = 'Nota: questa ricerca distingue le maiuscole';
+$lang['note2'] = 'Nota: la pagina verrà ripristinata all\'ultima versione non contenente la parola di spam data <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/ja/intro.txt b/lib/plugins/revert/lang/ja/intro.txt
new file mode 100644
index 000000000..995a57fd7
--- /dev/null
+++ b/lib/plugins/revert/lang/ja/intro.txt
@@ -0,0 +1,3 @@
+====== 復元管理 ======
+
+このページは、スパムにより編集されたページを自動的に復元するための機能を管理します。 スパムを受けたページを検索するため、スパムURLなどのキーワードを入力してください。 その後、検索結果に含まれているページがスパムされていることを確認してから復元を行います。
diff --git a/lib/plugins/revert/lang/ja/lang.php b/lib/plugins/revert/lang/ja/lang.php
new file mode 100644
index 000000000..0cd8c6f9b
--- /dev/null
+++ b/lib/plugins/revert/lang/ja/lang.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * japanese language file
+ * @author Yuji Takenaka <webmaster@davilin.com>
+ * @author Ikuo Obataya <i.obataya@gmail.com>
+ * @author Daniel Dupriest <kououken@gmail.com>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ */
+$lang['menu'] = '復元管理';
+$lang['filter'] = 'スパムを受けたページを検索';
+$lang['revert'] = '選択したページを検索';
+$lang['reverted'] = '%s はリビジョン %s へ復元されました';
+$lang['removed'] = '%s は削除されました';
+$lang['revstart'] = '復元処理中です。時間が掛かる可能性がありますが、もしタイムアウトした場合は、復元を複数回に分けて行ってください。';
+$lang['revstop'] = '復元処理が正しく完了しました。';
+$lang['note1'] = '注意:検索語句は大文字・小文字を区別します';
+$lang['note2'] = '注意:最新の内容に検索したスパムキーワード <i>%s</i> が含まれていないページが復元されます。';
diff --git a/lib/plugins/revert/lang/kk/lang.php b/lib/plugins/revert/lang/kk/lang.php
new file mode 100644
index 000000000..dde5b9577
--- /dev/null
+++ b/lib/plugins/revert/lang/kk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * kazakh language file
+ *
+ * @author Nurgozha Kaliaskarov astana08@gmail.com
+ */
diff --git a/lib/plugins/revert/lang/ko/intro.txt b/lib/plugins/revert/lang/ko/intro.txt
new file mode 100644
index 000000000..a0164dc4f
--- /dev/null
+++ b/lib/plugins/revert/lang/ko/intro.txt
@@ -0,0 +1,3 @@
+====== 복구 관리자 ======
+
+스팸 공격으로 부터 자동으로 복구하는데 이페이지는 도움이 될 수 있습니다. 스팸 공격받은 페이지 목록을 찾으려면 문자열을 입력하기 바랍니다(예. 스팸 URL), 그 후 검색된 페이지들이 스팸 공격받았는지 확인하고 복구합니다.
diff --git a/lib/plugins/revert/lang/ko/lang.php b/lib/plugins/revert/lang/ko/lang.php
new file mode 100644
index 000000000..0163d2754
--- /dev/null
+++ b/lib/plugins/revert/lang/ko/lang.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Korean language file
+ *
+ * @author jk lee
+ * @author dongnak@gmail.com
+ * @author Song Younghwan <purluno@gmail.com>
+ * @author SONG Younghwan <purluno@gmail.com>
+ * @author Seung-Chul Yoo <dryoo@live.com>
+ */
+$lang['menu'] = '복구 관리자';
+$lang['filter'] = '스팸 페이지 검색 ';
+$lang['revert'] = '선택 페이지들 복구';
+$lang['reverted'] = '%s를 이전 버전 %s 으로 복구';
+$lang['removed'] = '%s 삭제';
+$lang['revstart'] = '복구 작업을 시작합니다. 오랜 시간이 걸릴 수 있습니다. 완료되기 전에 스크립트 time out이 발생한다면 더 작은 작업들로 나누어서 복구하기 바랍니다. ';
+$lang['revstop'] = '복구 작업이 성공적으로 끝났습니다.';
+$lang['note1'] = '주의: 대소문자 구별하여 검색합니다.';
+$lang['note2'] = '주의: 이 페이지는 스팸 단어 <i>%s</i>를 포함하지 않은 가장 최근 과거 문서 버전으로 복구됩니다. ';
diff --git a/lib/plugins/revert/lang/la/intro.txt b/lib/plugins/revert/lang/la/intro.txt
new file mode 100644
index 000000000..99a206f63
--- /dev/null
+++ b/lib/plugins/revert/lang/la/intro.txt
@@ -0,0 +1,3 @@
+====== Restituendi Administrator ======
+
+Haec pagina contra mala interretialia paginas restituta. Vt paginas aegras quaeras, malum VRL scribe, deinde paginas malas eligas. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/la/lang.php b/lib/plugins/revert/lang/la/lang.php
new file mode 100644
index 000000000..af4203437
--- /dev/null
+++ b/lib/plugins/revert/lang/la/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Latin language file
+ *
+ * @author Massimiliano Vassalli <vassalli.max@gmail.com>
+ */
+$lang['menu'] = 'Restituendi administrator';
+$lang['filter'] = 'Malas paginas quaerere';
+$lang['revert'] = 'Electas paginas restituere';
+$lang['reverted'] = '%s restitutur ut %s recenseas';
+$lang['removed'] = '%s deletur';
+$lang['revstart'] = 'Restitutio agens. Hic multo tempore agere potest. Si nimium tempus transit, manu restituis.';
+$lang['revstop'] = 'Restitutio feliciter perfecta.';
+$lang['note1'] = 'Caue: litteras maiores et minores discernit';
+$lang['note2'] = 'Caue: pagina in recentiori forma sine malis uerbis "<i>%s</i>" restituetur';
diff --git a/lib/plugins/revert/lang/lb/intro.txt b/lib/plugins/revert/lang/lb/intro.txt
new file mode 100644
index 000000000..59c5dfc14
--- /dev/null
+++ b/lib/plugins/revert/lang/lb/intro.txt
@@ -0,0 +1,3 @@
+====== Revert Manager ======
+
+Dës Säit hëlleft bei der automatescher zerécksetzung no enger Spamattack. Fir eng Lëscht vun zougespamte Säiten ze fannen, gëff fir d'éischt e Sichbegrëff an (z.B. eng Spamadress). Konfirméier dann dass déi Säite wierklech zougespamt goufen a setz se dann zréck. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/lb/lang.php b/lib/plugins/revert/lang/lb/lang.php
new file mode 100644
index 000000000..59acdf7a8
--- /dev/null
+++ b/lib/plugins/revert/lang/lb/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * lb language file
+ *
+ * @author joel@schintgen.net
+ */
diff --git a/lib/plugins/revert/lang/lt/lang.php b/lib/plugins/revert/lang/lt/lang.php
new file mode 100644
index 000000000..103485864
--- /dev/null
+++ b/lib/plugins/revert/lang/lt/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Lithuanian language file
+ *
+ * @author audrius.klevas@gmail.com
+ * @author Arunas Vaitekunas <aras@fan.lt>
+ */
diff --git a/lib/plugins/revert/lang/lv/intro.txt b/lib/plugins/revert/lang/lv/intro.txt
new file mode 100644
index 000000000..edcdab2cd
--- /dev/null
+++ b/lib/plugins/revert/lang/lv/intro.txt
@@ -0,0 +1,3 @@
+====== Piemēsloto lapu atjaunotājs ======
+
+Šī lapa palīdzēs automātiski atjaunot saturu pēc huligānisma . Lai atrastu piedrazotās lapas ieraksti meklējamo izteiksmi (piem. smaperu URL), tad apstiprini, ka atrastās ir "mēslapas" un atcel izdarītās izmaiņas .
diff --git a/lib/plugins/revert/lang/lv/lang.php b/lib/plugins/revert/lang/lv/lang.php
new file mode 100644
index 000000000..012d6cc4c
--- /dev/null
+++ b/lib/plugins/revert/lang/lv/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Latvian, Lettish language file
+ *
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['menu'] = 'Piemēsloto lapu atjaunotājs';
+$lang['filter'] = 'Meklēt piemēslotās lapas';
+$lang['revert'] = 'Atjaunot norādītās lapas ';
+$lang['reverted'] = '%s atjaunots uz %s stāvokli';
+$lang['removed'] = '%s dzēsts';
+$lang['revstart'] = 'Atjaunošana uzsākta. Tas var aizņemt ilgāku laiku. Ja darbība pārtrūkst noilguma dēļ, atjaunošana jāveic pa mazākām porcijām.';
+$lang['revstop'] = 'Atjaunošana veiksmīgi pabeigta. ';
+$lang['note1'] = 'Ievēro: Meklēšana atšķir lielos un mazos burtus.';
+$lang['note2'] = 'Ievēro: Lapu atjaunos ar pēdējo versiju, kas nesatur uzdoto spama vārdu <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/mk/lang.php b/lib/plugins/revert/lang/mk/lang.php
new file mode 100644
index 000000000..6d4530f79
--- /dev/null
+++ b/lib/plugins/revert/lang/mk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Macedonian language file
+ *
+ * @author Dimitar Talevski <dimi3.14@gmail.com>
+ */
diff --git a/lib/plugins/revert/lang/mr/intro.txt b/lib/plugins/revert/lang/mr/intro.txt
new file mode 100644
index 000000000..efca2430d
--- /dev/null
+++ b/lib/plugins/revert/lang/mr/intro.txt
@@ -0,0 +1,5 @@
+====== फेरबदल व्यवस्थापक ======
+
+ह्या पानाद्वारे तुम्ही भंकस हल्ल्याद्वारे झालेले बदल आपोआप फेरबदल करू शकता.
+भंकस पानांची यादी बनवण्यासाठी प्रथम एखादा शब्दसमूह टाका ( उदा. एखादं भंकस URL ),
+मग जी पाने सापडतील टी भंकस असल्याचे नक्की करा आणि त्यातील बदल रद्द करा. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/mr/lang.php b/lib/plugins/revert/lang/mr/lang.php
new file mode 100644
index 000000000..3912bb967
--- /dev/null
+++ b/lib/plugins/revert/lang/mr/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Marathi language file
+ *
+ * @author ghatothkach@hotmail.com
+ * @author Padmanabh Kulkarni <kulkarnipadmanabh@gmail.com>
+ * @author Padmanabh Kulkarni<kulkarnipadmanabh@gmail.com>
+ * @author shantanoo@gmail.com
+ */
+$lang['menu'] = 'फेर बदल व्यवस्थापक';
+$lang['filter'] = 'भंकस पाने शोधा';
+$lang['revert'] = 'निवडलेली पानातील बदल रद्द करा';
+$lang['reverted'] = '%s फेरबदलून %s आवृत्तिमधे आणला आहे';
+$lang['removed'] = '%s काढला आहे.';
+$lang['revstart'] = 'फेरबदलाची प्रक्रिया चालु झाली आहे.याला बराच वेळ लागू शकतो. जर स्क्रिप्ट सम्पण्याआधि त्याची कालमर्यादा उलटून गेली तर छोट्या-छोट्या तुकड्यांमधे फेरबदल करा.';
+$lang['revstop'] = 'फेरबदलाची प्रक्रिया यशस्वीरीत्या पूर्ण झाली.';
+$lang['note1'] = 'टीप : हा शोध केस-सेंसिटिव आहे ( फ़क्त इंग्रजीसाठी लागू )';
+$lang['note2'] = 'टीप : हे पान फेरबदल करून ज्या शेवटच्या आवृत्तिमधे <i>%s</i> हा दिलेला भंकस शब्द नाही त्यात बदलले जाईल.';
diff --git a/lib/plugins/revert/lang/ms/lang.php b/lib/plugins/revert/lang/ms/lang.php
new file mode 100644
index 000000000..77ad2a1c1
--- /dev/null
+++ b/lib/plugins/revert/lang/ms/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Malay language file
+ *
+ * @author Markos
+ */
diff --git a/lib/plugins/revert/lang/ne/lang.php b/lib/plugins/revert/lang/ne/lang.php
new file mode 100644
index 000000000..4fd337532
--- /dev/null
+++ b/lib/plugins/revert/lang/ne/lang.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Nepali language file
+ *
+ * @author Saroj Kumar Dhakal <lotusnagarkot@gmail.com>
+ * @author SarojKumar Dhakal <lotusnagarkot@yahoo.com>
+ * @author Saroj Dhakal<lotusnagarkot@yahoo.com>
+ */
+$lang['menu'] = 'पूर्वस्थिती व्यवस्थापक';
+$lang['filter'] = 'स्प्यामयुक्त पृष्ठहरु खोज्नुहोस् ';
+$lang['revert'] = 'छानिएक पृष्ठहरुलाई पूर्वस्थितिमा फर्काउनुहोस् ।';
+$lang['reverted'] = '%s लाई %s संस्करणमा फर्काइयो ।';
+$lang['removed'] = '%s लाई हटाइयो ।';
+$lang['revstart'] = 'पूर्वस्थितिमा फर्काउने कार्य सुरु भयो । यसले लामो समय लिन सक्छ। यदि स्क्रिप्टको समय का्र्य सकिनु पूर्व सकियो भने । तपाईले सानो सानो टुक्रा लिएर पुर्वरुपमा फर्काउनु पर्ने हुन्छ ।';
+$lang['revstop'] = 'पूर्वस्थितिमा फर्काउने कार्य सफलतापूर्वक सकियो ।';
+$lang['note1'] = 'नोट: यो खोज वर्ण सम्वेदनशील छ';
diff --git a/lib/plugins/revert/lang/nl/intro.txt b/lib/plugins/revert/lang/nl/intro.txt
new file mode 100644
index 000000000..db8f5a06c
--- /dev/null
+++ b/lib/plugins/revert/lang/nl/intro.txt
@@ -0,0 +1,3 @@
+===== Herstelmanager =====
+
+Deze pagina helpt u bij het herstellen van pagina's na een spam-aanval. Vul een zoekterm in (bijvoorbeeld een spam url) om een lijst te krijgen van bekladde pagina's, bevestig dat de pagina's inderdaad spam bevatten en herstel de wijzigingen.
diff --git a/lib/plugins/revert/lang/nl/lang.php b/lib/plugins/revert/lang/nl/lang.php
new file mode 100644
index 000000000..32e14c2c4
--- /dev/null
+++ b/lib/plugins/revert/lang/nl/lang.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Dutch language file
+ *
+ * @author Wouter Schoot <wouter@schoot.org>
+ * @author John de Graaff <john@de-graaff.net>
+ * @author Niels Schoot <niels.schoot@quintiq.com>
+ * @author Dion Nicolaas <dion@nicolaas.net>
+ * @author Danny Rotsaert <danny.rotsaert@edpnet.be>
+ * @author Marijn Hofstra hofstra.m@gmail.com
+ * @author Matthias Carchon webmaster@c-mattic.be
+ * @author Marijn Hofstra <hofstra.m@gmail.com>
+ * @author Timon Van Overveldt <timonvo@gmail.com>
+ * @author Jeroen
+ * @author Ricardo Guijt <ricardoguijt@gmail.com>
+ */
+$lang['menu'] = 'Herstelmanager';
+$lang['filter'] = 'Zoek naar bekladde pagina\'s';
+$lang['revert'] = 'Herstel geselecteerde pagina\'s';
+$lang['reverted'] = '%s hersteld naar revisie %s';
+$lang['removed'] = '%s verwijderd';
+$lang['revstart'] = 'Herstelproces begonnen. Dit kan een lange tijd duren. Als het script een timeout genereerd voor het klaar is, moet je in kleinere selecties herstellen.';
+$lang['revstop'] = 'Herstelproces succesvol afgerond.';
+$lang['note1'] = 'NB: deze zoekopdracht is hoofdlettergevoelig';
+$lang['note2'] = 'NB: de pagina zal hersteld worden naar de laatste versie waar de opgegeven spam-term <i>%s</i> niet op voorkomt.';
diff --git a/lib/plugins/revert/lang/no/intro.txt b/lib/plugins/revert/lang/no/intro.txt
new file mode 100644
index 000000000..f48b98749
--- /dev/null
+++ b/lib/plugins/revert/lang/no/intro.txt
@@ -0,0 +1,3 @@
+====== Tilbakestillingsbehandler ======
+
+Denne siden hjelper deg å automatisk reversere forsøpling av sidene. For å finne en liste over forsøplede sider, skriv inn en søkestreng (f.eks. en søppel-URL). Bekreft deretter at de funnede sidene virkelig er forsøplet og tilbakestill endringene.
diff --git a/lib/plugins/revert/lang/no/lang.php b/lib/plugins/revert/lang/no/lang.php
new file mode 100644
index 000000000..299b12ea7
--- /dev/null
+++ b/lib/plugins/revert/lang/no/lang.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Norwegianlanguage file
+ *
+ * @author Thomas Nygreen <nygreen@gmail.com>
+ * @author Arild Burud <arildb@met.no>
+ * @author Torkill Bruland <torkar-b@online.no>
+ * @author Rune M. Andersen <rune.andersen@gmail.com>
+ * @author Jakob Vad Nielsen (me@jakobnielsen.net)
+ * @author Kjell Tore Næsgaard <kjell.t.nasgaard@ntnu.no>
+ * @author Knut Staring <knutst@gmail.com>
+ * @author Lisa Ditlefsen <lisa@vervesearch.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author Rune Rasmussen syntaxerror.no@gmail.com
+ * @author Jon Bøe <jonmagneboe@hotmail.com>
+ * @author Egil Hansen <egil@rosetta.no>
+ */
+$lang['menu'] = 'Tilbakestillingsbehandler';
+$lang['filter'] = 'Søk etter søppelmeldinger';
+$lang['revert'] = 'Tilbakestill valgte sider';
+$lang['reverted'] = '%s tilbakestilt til revisjon %s';
+$lang['removed'] = '%s fjernet';
+$lang['revstart'] = 'Prosessen med tilbakestilling er startet. Hvis det skjer et
+tidsavbrudd før prosessen er ferdig, må du tilbakestille
+færre sider om gangen.';
+$lang['revstop'] = 'Tilbakestillingen er fullført.';
+$lang['note1'] = 'Merk: søket skiller mellom store og små bokstaver';
+$lang['note2'] = 'Merk: siden vil bli tilbakestilt til den siste versjonen som ikke inneholder det oppgitte søppel-ordet <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/pl/intro.txt b/lib/plugins/revert/lang/pl/intro.txt
new file mode 100644
index 000000000..410948a2f
--- /dev/null
+++ b/lib/plugins/revert/lang/pl/intro.txt
@@ -0,0 +1,3 @@
+====== Menadżer przywracania ======
+
+Menadżer przywracania przeznaczony jest do automatycznego naprawiania stron, które uległy wandalizmom. W celu naprawienia uszkodzonych stron, wyszukaj je a następnie oznacz i przywróć poprzednie wersje.
diff --git a/lib/plugins/revert/lang/pl/lang.php b/lib/plugins/revert/lang/pl/lang.php
new file mode 100644
index 000000000..30ab60fda
--- /dev/null
+++ b/lib/plugins/revert/lang/pl/lang.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * polish language file
+ * @author Grzegorz Żur <grzegorz.zur@gmail.com>
+ * @author Mariusz Kujawski <marinespl@gmail.com>
+ * @author Maciej Kurczewski <pipijajko@gmail.com>
+ * @author Sławomir Boczek <slawkens@gmail.com>
+ * @author sleshek@wp.pl
+ * @author Leszek Stachowski <shazarre@gmail.com>
+ * @author maros <dobrimaros@yahoo.pl>
+ * @author Grzegorz Widła <dzesdzes@gmail.com>
+ * @author Łukasz Chmaj <teachmeter@gmail.com>
+ * @author Begina Felicysym <begina.felicysym@wp.eu>
+ */
+$lang['menu'] = 'Menadżer przywracania';
+$lang['filter'] = 'Wyszukaj uszkodzone strony';
+$lang['revert'] = 'Napraw zaznaczone strony';
+$lang['reverted'] = 'Stronę %s zastąpiono wersją %s';
+$lang['removed'] = 'Stronę %s usunięto';
+$lang['revstart'] = 'Naprawa rozpoczęta. To może zająć kilka minut. Jeśli strona przestanie się ładować, spróbuj ponownie zaznaczając mniejszą liczbę stron.';
+$lang['revstop'] = 'Naprawa zakończona pomyślnie!';
+$lang['note1'] = 'Uwaga: duże i małe litery są rozróżniane';
+$lang['note2'] = 'Uwaga: zostanie przywrócona ostatnia wersja strony niezawierająca wyrażenia <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/pt-br/intro.txt b/lib/plugins/revert/lang/pt-br/intro.txt
new file mode 100644
index 000000000..5ce9890db
--- /dev/null
+++ b/lib/plugins/revert/lang/pt-br/intro.txt
@@ -0,0 +1,3 @@
+====== Gerenciador de Reversões ======
+
+Essa página ajuda a reverter automaticamente um ataque de spam. Para encontrar as páginas que sofreram ataque, primeiro entre com um termo na busca (ex.: a URL do spam), então confirme que as páginas encontradas são realmente spam e reverta as edições.
diff --git a/lib/plugins/revert/lang/pt-br/lang.php b/lib/plugins/revert/lang/pt-br/lang.php
new file mode 100644
index 000000000..c4a2f742b
--- /dev/null
+++ b/lib/plugins/revert/lang/pt-br/lang.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Lucien Raven <lucienraven@yahoo.com.br>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Flávio Veras <flaviove@gmail.com>
+ * @author Jeferson Propheta <jeferson.propheta@gmail.com>
+ * @author jair.henrique@gmail.com
+ * @author Luis Dantas <luis@dantas.com>
+ * @author Frederico Guimarães <frederico@teia.bio.br>
+ * @author Jair Henrique <jair.henrique@gmail.com>
+ * @author Luis Dantas <luisdantas@gmail.com>
+ * @author Sergio Motta sergio@cisne.com.br
+ * @author Isaias Masiero Filho <masiero@masiero.org>
+ * @author Balaco Baco <balacobaco@imap.cc>
+ */
+$lang['menu'] = 'Gerenciador de reversões';
+$lang['filter'] = 'Procura por páginas com spam';
+$lang['revert'] = 'Reverte as páginas selecionadas';
+$lang['reverted'] = '%s revertida para a revisão %s';
+$lang['removed'] = '%s removida';
+$lang['revstart'] = 'O processo de reversão foi iniciado. Isso pode levar muito tempo. Se o tempo de execução do script expirar antes dele encerrar, você deverá tentar novamente usando blocos menores.';
+$lang['revstop'] = 'O processo de reversão terminou com sucesso.';
+$lang['note1'] = 'Nota: esta busca diferencia maiúsculas/minúsculas';
+$lang['note2'] = 'Nota: a página será revertida para a última versão que não contém o termo de spam <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/pt/intro.txt b/lib/plugins/revert/lang/pt/intro.txt
new file mode 100644
index 000000000..7adfe5f21
--- /dev/null
+++ b/lib/plugins/revert/lang/pt/intro.txt
@@ -0,0 +1,3 @@
+====== Gerir Reversões ======
+
+Esta página ajuda a reverter automaticamente de um ataque spam. Para encontrar as páginas afectadas insira primeiro um texto de pesquisa (i.e spam URL), confirme as páginas encontradas como sendo resultantes de um ataque spam e reverta essas edições. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/pt/lang.php b/lib/plugins/revert/lang/pt/lang.php
new file mode 100644
index 000000000..3b2850f41
--- /dev/null
+++ b/lib/plugins/revert/lang/pt/lang.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author José Monteiro <Jose.Monteiro@DoWeDo-IT.com>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Fil <fil@meteopt.com>
+ * @author André Neves <drakferion@gmail.com>
+ * @author José Campos zecarlosdecampos@gmail.com
+ */
+$lang['menu'] = 'Gestor de Reversões';
+$lang['filter'] = 'Pesquisar por páginas "spammy"';
+$lang['revert'] = 'Reverter páginas seleccionadas';
+$lang['reverted'] = '%s revertida para revisão %s';
+$lang['removed'] = '%s removidas.';
+$lang['revstart'] = 'Processo de reversão iniciado. A sua execução pode demorar. Se der timeout antes de terminar então é preciso escolher quantidades menores de páginas a reverter.';
+$lang['revstop'] = 'Processo de reversão bem sucedido.';
+$lang['note1'] = 'Nota: a pesquisa é case-sensitive';
+$lang['note2'] = 'Nota: a página será revertida para a versão anterior que não contém os termos spam pesquisados: <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/ro/intro.txt b/lib/plugins/revert/lang/ro/intro.txt
new file mode 100644
index 000000000..3a030359b
--- /dev/null
+++ b/lib/plugins/revert/lang/ro/intro.txt
@@ -0,0 +1,3 @@
+====== Manager Reveniri ======
+
+Această pagină ajută revenirea automată în cazul unui atac spam. Pentru a găsi o listă a paginilor cu spam, întroduceţi mai întâi un şir de căutat (de ex. Un URL spam), apoi confirmaţi dacă paginile găsite conţin într-adevăr spam şi anulaţi editările.
diff --git a/lib/plugins/revert/lang/ro/lang.php b/lib/plugins/revert/lang/ro/lang.php
new file mode 100644
index 000000000..094f4dc71
--- /dev/null
+++ b/lib/plugins/revert/lang/ro/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Romanian language file
+ *
+ * @author Sergiu Baltariu <s_baltariu@yahoo.com>
+ * @author s_baltariu@yahoo.com
+ * @author Emanuel-Emeric Andrasi <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrași <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andraşi <em.andrasi@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrasi <em.andrasi@mandrivausers.ro>
+ * @author Marius OLAR <olarmariusalex@gmail.com>
+ * @author Emanuel-Emeric Andrași <em.andrasi@mandrivausers.ro>
+ */
+$lang['menu'] = 'Manager Reveniri';
+$lang['filter'] = 'Caută pagini cu posibil spam';
+$lang['revert'] = 'Revenire pentru paginile selectate';
+$lang['reverted'] = '%s revenită la versiunea %s';
+$lang['removed'] = '%s eliminată';
+$lang['revstart'] = 'Procesul de revenire a început. Acesta poate dura mult timp.Dacă scriptul expiră înainte de finalizare, trebuie să reveniţi în paşi mai mici.';
+$lang['revstop'] = 'Procesul de revenire s-a finalizat cu succes.';
+$lang['note1'] = 'Notă: această căutare este sensibilă la majuscule.';
+$lang['note2'] = 'Notă: pagina va reveni la ultima versiune ce nu conţine termenul de spam <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/ru/intro.txt b/lib/plugins/revert/lang/ru/intro.txt
new file mode 100644
index 000000000..52d1f8d3d
--- /dev/null
+++ b/lib/plugins/revert/lang/ru/intro.txt
@@ -0,0 +1,3 @@
+====== Менеджер откаток ======
+
+Эта страница поможет вам в автоматической откатке изменений после спам-атаки. Для того, чтобы найти спам-страницы, введите ключевые слова и произведите поиск (например, по URL спамера). Затем убедитесь, что найденные страницы действительно содержат спам и сделайте откатку изменений.
diff --git a/lib/plugins/revert/lang/ru/lang.php b/lib/plugins/revert/lang/ru/lang.php
new file mode 100644
index 000000000..9624d8fd6
--- /dev/null
+++ b/lib/plugins/revert/lang/ru/lang.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * russian language file
+ * @author Denis Simakov <akinoame1@gmail.com>
+ * @author Andrew Pleshakov <beotiger@mail.ru>
+ * @author Змей Этерийский evil_snake@eternion.ru
+ * @author Hikaru Nakajima <jisatsu@mail.ru>
+ * @author Alexei Tereschenko <alexeitlex@yahoo.com>
+ * @author Irina Ponomareva irinaponomareva@webperfectionist.com
+ * @author Alexander Sorkin <kibizoid@gmail.com>
+ * @author Kirill Krasnov <krasnovforum@gmail.com>
+ * @author Vlad Tsybenko <vlad.development@gmail.com>
+ * @author Aleksey Osadchiy <rfc@nm.ru>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Ladyko Andrey <fylh@succexy.spb.ru>
+ * @author Eugene <windy.wanderer@gmail.com>
+ */
+$lang['menu'] = 'Менеджер откаток';
+$lang['filter'] = 'Поиск спам-страниц';
+$lang['revert'] = 'Откатить изменения для выбранных страниц';
+$lang['reverted'] = '%s откачена к версии %s';
+$lang['removed'] = '%s удалена';
+$lang['revstart'] = 'Начат процесс откатки. Он может занять много времени. Если скрипт не успевает завершить работу и выдаёт ошибку, необходимо произвести откатку более маленькими частями.';
+$lang['revstop'] = 'Процесс откатки успешно завершён.';
+$lang['note1'] = 'Замечание: поиск с учётом регистра';
+$lang['note2'] = 'Замечание: страница будет восстановлена до последней версии, не содержащей спам-термин <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/sk/intro.txt b/lib/plugins/revert/lang/sk/intro.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/lib/plugins/revert/lang/sk/intro.txt
diff --git a/lib/plugins/revert/lang/sk/lang.php b/lib/plugins/revert/lang/sk/lang.php
new file mode 100644
index 000000000..368d2d929
--- /dev/null
+++ b/lib/plugins/revert/lang/sk/lang.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Slovaklanguage file
+ *
+ * @author Michal Mesko <michal.mesko@gmail.com>
+ * @author exusik@gmail.com
+ * @author Martin Michalek <michalek.dev@gmail.com>
+ */
+$lang['menu'] = 'Reverzný manažér';
+$lang['filter'] = 'Hľadať spamerské stránky';
+$lang['revert'] = 'Vrátiť vybrané stránky';
+$lang['reverted'] = '%s vrátená na revíziu %s';
+$lang['removed'] = '%s odstránená';
+$lang['revstart'] = 'Proces reverzie bol spustený. Toto môže trvať dlhý čas. Ak skript prekročí daný maximálny časový interval pred tým, ako skončí, musíte urobiť reverziu v menších dávkach.';
+$lang['revstop'] = 'Proces reverzie sa úspešne skončil.';
+$lang['note1'] = 'Poznámka: vyhľadávanie rozlišuje medzi veľkými a malými písmenami';
+$lang['note2'] = 'Poznámka: táto stránka bude vrátená do poslednej verzie, ktorá neobsahuje spamový výraz <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/sl/intro.txt b/lib/plugins/revert/lang/sl/intro.txt
new file mode 100644
index 000000000..4e2cabf96
--- /dev/null
+++ b/lib/plugins/revert/lang/sl/intro.txt
@@ -0,0 +1,3 @@
+====== Povrnitev okvarjene vsebine ======
+
+Na tej strani je mogoče povrniti vsebino wiki strani na izvorne vrednosti po napadu na stran in vpisu neželenih vsebin. Za iskanje strani z neželeno vsebino, uporabite iskalnik z ustreznim nizom (npr. naslov URL), potem pa potrdite, da so najdene strani res z neželeno vsebino in nato povrnite stanje na zadnjo pravo različico.
diff --git a/lib/plugins/revert/lang/sl/lang.php b/lib/plugins/revert/lang/sl/lang.php
new file mode 100644
index 000000000..92b0427ce
--- /dev/null
+++ b/lib/plugins/revert/lang/sl/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Slovenian language file
+ *
+ * @author Matej Urbančič (mateju@svn.gnome.org)
+ */
+$lang['menu'] = 'Povrnitev okvarjene vsebine';
+$lang['filter'] = 'Iskanje strani z neželeno vsebino';
+$lang['revert'] = 'Povrni izbrane strani';
+$lang['reverted'] = 'stran %s je povrnjena na različico %s';
+$lang['removed'] = 'stran %s je odstranjena';
+$lang['revstart'] = 'Postopek povrnitve vsebine je začet. Opravilo je lahko dolgotrajno. V kolikor opravilo časovno poteče prek končanjem povrnitve, bo treba postopek ponoviti na manjših odsekih.';
+$lang['revstop'] = 'Postopek povrnitve vsebine je uspešno končan.';
+$lang['note1'] = 'Opomba: iskanje upošteva velikost črk';
+$lang['note2'] = 'Opomba: stran bo povrnjena na zadnjo različico brez neželenega pojma <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/sq/intro.txt b/lib/plugins/revert/lang/sq/intro.txt
new file mode 100644
index 000000000..25e16b6eb
--- /dev/null
+++ b/lib/plugins/revert/lang/sq/intro.txt
@@ -0,0 +1,3 @@
+====== Menaxhuesi Rikthimit ======
+
+Kjo faqe ndihmon për rikthimin automatik në rast të një sulmi spam. Për të gjetur një listë me faqe spam në fillim fut një varg kërkimi (psh një URL spam), dhe pastaj konfirmo që faqet e gjetura janë me të vërtetë spam dhe rikthe redaktimet. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/sq/lang.php b/lib/plugins/revert/lang/sq/lang.php
new file mode 100644
index 000000000..45ae4997c
--- /dev/null
+++ b/lib/plugins/revert/lang/sq/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Albanian language file
+ *
+ * @author Leonard Elezi leonard.elezi@depinfo.info
+ */
+$lang['menu'] = 'Menaxhuesi Rikthimit';
+$lang['filter'] = 'Kërko faqe me spam';
+$lang['revert'] = 'Rikthe faqet e përzgjedhura';
+$lang['reverted'] = '%s u rikthye në rishikimin %s';
+$lang['removed'] = '%s u hoq';
+$lang['revstart'] = 'Proçesi i rikthimit filloi. Kjo mund të zgjasë për një kohë të gjatë. Nëse koha e skriptit mbaron para përfundimit, atëherë rikthimi duhet të bëhet me copa të vogla.';
+$lang['revstop'] = 'Proçesi i rikthimit mbaroi me sukses.';
+$lang['note1'] = 'Shënim: në këtë kërkim bëhet dallim midis gërmave kapitale dhe gërmave të vogla.';
+$lang['note2'] = 'Shënim: faqja do të rikthehet në versionin e fundit që nuk përmban term-in spam të dhënë <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/sr/intro.txt b/lib/plugins/revert/lang/sr/intro.txt
new file mode 100644
index 000000000..8c288e7f1
--- /dev/null
+++ b/lib/plugins/revert/lang/sr/intro.txt
@@ -0,0 +1,3 @@
+====== Управљач за враћање ======
+
+Ова страна вам помаже од напада спама аутоматским враћањем на старе верзије страница. Да бисте пронашли спамоване странице откуцајте реч за претрагу (тј. реч која се појављује у спаму), затим потврдите да се на пронађеним страницама стварно налази спам и онда вратите на стање пре промена. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/sr/lang.php b/lib/plugins/revert/lang/sr/lang.php
new file mode 100644
index 000000000..62c712ad1
--- /dev/null
+++ b/lib/plugins/revert/lang/sr/lang.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Serbian language file
+ *
+ * @author Иван Петровић petrovicivan@ubuntusrbija.org
+ * @author Ivan Petrovic <petrovicivan@ubuntusrbija.org>
+ * @author Miroslav Šolti <solti.miroslav@gmail.com>
+ */
+$lang['menu'] = 'Управљач за враћање';
+$lang['filter'] = 'Претрага спам страница';
+$lang['revert'] = 'Врати одабране странице';
+$lang['reverted'] = '%s враћена на ревизију %s';
+$lang['removed'] = '%s је уклоњена';
+$lang['revstart'] = 'Процес враћања је покренут. Може потрајати дуже време. Ако истекне време пре завршетка потребно је да покренете у мањим деловима.';
+$lang['revstop'] = 'Процес враћања је успешно завршен.';
+$lang['note1'] = 'Напомена: ова претрага разликује велика и мала слова';
+$lang['note2'] = 'Напомена: страница ће бити враћена на последњу верзију која не садржи спам израз <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/sv/intro.txt b/lib/plugins/revert/lang/sv/intro.txt
new file mode 100644
index 000000000..cd7f322a3
--- /dev/null
+++ b/lib/plugins/revert/lang/sv/intro.txt
@@ -0,0 +1,3 @@
+====== Hantera återställningar ======
+
+Den här sidan hjälper till med automatiskt återställning efter en spamattack. För att hitta spammade sidor, ange först en söksträng (till exempel en webbadress). Kontrollera sedan att sidorna som hittades verkligen är spam, och återställ sedan redigeringarna.
diff --git a/lib/plugins/revert/lang/sv/lang.php b/lib/plugins/revert/lang/sv/lang.php
new file mode 100644
index 000000000..29c6702eb
--- /dev/null
+++ b/lib/plugins/revert/lang/sv/lang.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Swedish language file
+ *
+ * @author Per Foreby <per@foreby.se>
+ * @author Nicklas Henriksson <nicklas[at]nihe.se>
+ * @author Håkan Sandell <hakan.sandell[at]mydata.se>
+ * @author Dennis Karlsson
+ * @author Tormod Otter Johansson <tormod@latast.se>
+ * @author emil@sys.nu
+ * @author Pontus Bergendahl <pontus.bergendahl@gmail.com>
+ * @author Tormod Johansson tormod.otter.johansson@gmail.com
+ * @author Emil Lind <emil@sys.nu>
+ * @author Bogge Bogge <bogge@bogge.com>
+ * @author Peter Åström <eaustreum@gmail.com>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ * @author mikael@mallander.net
+ */
+$lang['menu'] = 'Hantera återställningar';
+$lang['filter'] = 'Sök efter spamsidor';
+$lang['revert'] = 'Återställ markerade redigeringar';
+$lang['reverted'] = '%s återställd till version %s';
+$lang['removed'] = '%s borttagen';
+$lang['revstart'] = 'Återställningen startad. Detta kan ta lång tid. Om
+ skriptet får en timeout innan det är färdigt måste du köra återställningen
+ med färre sidor åt gången.';
+$lang['revstop'] = 'Återställningen avslutades utan problem.';
+$lang['note1'] = 'OBS: sökningen skiljer på stora och små bokstäver';
+$lang['note2'] = 'OBS: sidan kommer att återställas till den senaste versionen som inte innehåller den angivna söksträngen <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/th/intro.txt b/lib/plugins/revert/lang/th/intro.txt
new file mode 100644
index 000000000..2bfd27e59
--- /dev/null
+++ b/lib/plugins/revert/lang/th/intro.txt
@@ -0,0 +1,3 @@
+====== ตัวจัดการกู้คืนสภาพเอกสาร ======
+
+หน้านี้จะช่วยคุณด้วยการกู้คืนหน้าที่ถูกแสปมโดยอัตโนมัติ เพื่อที่จะค้นหารายการหน้าที่ถูกสแปม อันดับแรกให้กรอกข้อความสืบค้น (เช่น URL เว็บโฆษณาที่มาสแปมไว้), จากนั้นให้ยืนยันว่าเพจที่พบนั้นถูกสแปมจริงๆ แล้วจึงสั่งคืนสภาพต้นฉบับ \ No newline at end of file
diff --git a/lib/plugins/revert/lang/th/lang.php b/lib/plugins/revert/lang/th/lang.php
new file mode 100644
index 000000000..86e4f9ca4
--- /dev/null
+++ b/lib/plugins/revert/lang/th/lang.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Thai language file
+ *
+ * @author Komgrit Niyomrath <n.komgrit@gmail.com>
+ * @author Kittithat Arnontavilas mrtomyum@gmail.com
+ * @author Arthit Suriyawongkul <arthit@gmail.com>
+ * @author Kittithat Arnontavilas <mrtomyum@gmail.com>
+ * @author Thanasak Sompaisansin <jombthep@gmail.com>
+ */
+$lang['menu'] = 'ตัวจัดการคืนสภาพเอกสารฉบับเดิม';
+$lang['filter'] = 'ค้นหาเพจที่ถูกแสปม';
+$lang['revert'] = 'คืนสภาพเพจที่เลือกไว้';
+$lang['reverted'] = 'คืนสภาพ %s กลับไปเป็นฉบับ %s';
+$lang['removed'] = 'ถอดทิ้ง %s';
+$lang['revstart'] = 'กระบวนการคืนสภาพได้เริ่มต้นแล้ว นี่อาจต้องใช้เวลานาน ถ้าหมดเวลาที่กำหนดสำหรับสคริปต์ก่อนที่จะสำเร็จ คุณต้องไปทำการแบ่งข้อมูลให้เล็กลงเพื่อการคืนสภาพทีละส่วน';
+$lang['revstop'] = 'กระบวนการคืนสภาพสำเร็จเรียบร้อย';
+$lang['note1'] = 'คำเตือน: การค้นนี้นับตัวพิมพ์ใหญ่เล็ก (case sensitive)';
+$lang['note2'] = 'คำเตือน: เพจจะถูกคืนสภาพไปยังรุ่นล่าสุดที่ไม่มีประโยคสแปมนี้ <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/tr/intro.txt b/lib/plugins/revert/lang/tr/intro.txt
new file mode 100644
index 000000000..ff123995a
--- /dev/null
+++ b/lib/plugins/revert/lang/tr/intro.txt
@@ -0,0 +1,3 @@
+====== Eskiye Döndürme Yöneticisi ======
+
+Bu sayfa spam saldırılarına karşı otomatik eski haline çevirim yapmanızı sağlar. Spam içerikli sayfayı bulmak için bir anahtar kelime girin (mesela spam URLsi), daha sonra spame maruz kalan sayfalar olduğundan emin olup eski haline çevirin. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/tr/lang.php b/lib/plugins/revert/lang/tr/lang.php
new file mode 100644
index 000000000..aa1458a95
--- /dev/null
+++ b/lib/plugins/revert/lang/tr/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Turkish language file
+ *
+ * @author Aydın Coşkuner <aydinweb@gmail.com>
+ * @author Cihan Kahveci <kahvecicihan@gmail.com>
+ * @author Yavuz Selim <yavuzselim@gmail.com>
+ * @author Caleb Maclennan <caleb@alerque.com>
+ */
+$lang['menu'] = 'Eskiye Döndürme';
+$lang['filter'] = 'Spam bulunan sayfaları ara';
+$lang['revert'] = 'Seçili sayfaları eskiye döndür';
+$lang['reverted'] = '%s %s sürümüne geri çevrildi. ';
+$lang['removed'] = '%s kaldırıldı';
+$lang['revstart'] = 'Eskiye döndürme işlemi başlatıldı. Bu işlem uzun sürebilir. Eğer script işlemi tamamlayamadan zaman aşımına uğrarsa küçük parçalar halinde işlemi uygulayın.';
+$lang['revstop'] = 'Eskiye döndürme işlemi başarıyla tamamlandı.';
+$lang['note1'] = 'Not: bu aramada küçük harf büyük harf ayrımı vardır.';
+$lang['note2'] = 'Not: bu sayfa <i>%s</i> spam kelimelerini içermeyen son haline geri çevirilecektir.';
diff --git a/lib/plugins/revert/lang/uk/intro.txt b/lib/plugins/revert/lang/uk/intro.txt
new file mode 100644
index 000000000..7bf5dfcb9
--- /dev/null
+++ b/lib/plugins/revert/lang/uk/intro.txt
@@ -0,0 +1,3 @@
+====== Менеджер відновлення ======
+
+Ця сторінка дозволяє вам автоматично відновлюватися після спамерських атак. Для створення списку зіпсутих сторінок спочатку введіть рядок (напр. спамерське посилання), а потім підтвердіть, що знайдена сторінка дійсно є спамом і відновіть редагування. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/uk/lang.php b/lib/plugins/revert/lang/uk/lang.php
new file mode 100644
index 000000000..310f8e8da
--- /dev/null
+++ b/lib/plugins/revert/lang/uk/lang.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Ukrainian language file
+ *
+ * @author serg_stetsuk@ukr.net
+ * @author okunia@gmail.com
+ * @author Oleksandr Kunytsia <okunia@gmail.com>
+ * @author Uko uko@uar.net
+ * @author Ulrikhe Lukoie <lukoie@gmail>.com
+ * @author Kate Arzamastseva pshns@ukr.net
+ */
+$lang['menu'] = 'Менеджер відновлення';
+$lang['filter'] = 'Пошук спамних сторінок';
+$lang['revert'] = 'Відновити обрані сторінки';
+$lang['reverted'] = '%s відновлено до версії %s';
+$lang['removed'] = '%s вилучено';
+$lang['revstart'] = 'Розпочато процес відновлення. Це може зайняти багато часу. Якщо скрипт не закінчує роботу до таймауту, необхідно відновлювати меншими частинами.';
+$lang['revstop'] = 'Процес відновлення успішно закінчено.';
+$lang['note1'] = 'Увага: пошук залежить від регістру символів';
+$lang['note2'] = 'Увага: сторінку буде відновлено до останньої версії, яка не містить спамерського терміну <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/zh-tw/intro.txt b/lib/plugins/revert/lang/zh-tw/intro.txt
new file mode 100644
index 000000000..17632b1dd
--- /dev/null
+++ b/lib/plugins/revert/lang/zh-tw/intro.txt
@@ -0,0 +1,3 @@
+====== 還原管理器 ======
+
+本頁面能幫助您自動還原被垃圾訊息攻擊的頁面過來。先輸入關鍵字詞搜尋包含垃圾訊息的頁面(如垃圾訊息的 URL),確認找到的頁面確實包含垃圾訊息,再將它們還原。
diff --git a/lib/plugins/revert/lang/zh-tw/lang.php b/lib/plugins/revert/lang/zh-tw/lang.php
new file mode 100644
index 000000000..a853ccd2e
--- /dev/null
+++ b/lib/plugins/revert/lang/zh-tw/lang.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Chinese Traditional language file
+ *
+ * @author Li-Jiun Huang <ljhuang.tw@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-simptrad.html
+ * @author Wayne San <waynesan@zerozone.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmai.com>
+ * @author Cheng-Wei Chien <e.cwchien@gmail.com>
+ * @author Danny Lin <danny0838@pchome.com.tw>
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '還原管理';
+$lang['filter'] = '搜索包含垃圾訊息的頁面';
+$lang['revert'] = '還原選取的頁面';
+$lang['reverted'] = '%s 已還原為版本 %s';
+$lang['removed'] = '%s 已移除';
+$lang['revstart'] = '已開始還原操作。有可能需要很長時間。如果程式執行逾時,請嘗試分次還原少量內容。';
+$lang['revstop'] = '還原程序已成功完成。';
+$lang['note1'] = '注意:搜尋區分大小寫';
+$lang['note2'] = '注意:此頁面將被還原為最後一個不含垃圾訊息 <i>%s</i> 的版本。';
diff --git a/lib/plugins/revert/lang/zh/intro.txt b/lib/plugins/revert/lang/zh/intro.txt
new file mode 100644
index 000000000..c697f8aea
--- /dev/null
+++ b/lib/plugins/revert/lang/zh/intro.txt
@@ -0,0 +1,3 @@
+====== 还原管理器 ======
+
+该页面能帮助您的页面从垃圾信息的攻击中自动还原过来。 请先输入关键词搜索包含垃圾信息的页面(如某个垃圾信息的 URL),然后请确定搜索结果的确包含垃圾信息,并将其还原至先前的修订版。
diff --git a/lib/plugins/revert/lang/zh/lang.php b/lib/plugins/revert/lang/zh/lang.php
new file mode 100644
index 000000000..d4d010f29
--- /dev/null
+++ b/lib/plugins/revert/lang/zh/lang.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Chinese(Simplified) language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-tradsimp.html
+ * @author George Sheraton guxd@163.com
+ * @author Simon zhan <simonzhan@21cn.com>
+ * @author mr.jinyi@gmail.com
+ * @author ben <ben@livetom.com>
+ * @author lainme <lainme993@gmail.com>
+ * @author caii <zhoucaiqi@gmail.com>
+ * @author Hiphen Lee <jacob.b.leung@gmail.com>
+ * @author caii, patent agent in China <zhoucaiqi@gmail.com>
+ * @author lainme993@gmail.com
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '还原管理器';
+$lang['filter'] = '搜索包含垃圾信息的页面';
+$lang['revert'] = '还原选中的页面';
+$lang['reverted'] = '%s 还原至修订版 %s';
+$lang['removed'] = '%s 已移除';
+$lang['revstart'] = '已开始还原操作。有可能需要很长时间。如果计时器在还原操作完成前停止了,请尝试还原较少的内容。';
+$lang['revstop'] = '还原操作成功完成。';
+$lang['note1'] = '请注意:本次搜索区分大小写';
+$lang['note2'] = '请注意:本页面将被还原至不包含给定垃圾信息 <i>%s</i> 的最近的修订版。';
diff --git a/lib/plugins/revert/plugin.info.txt b/lib/plugins/revert/plugin.info.txt
new file mode 100644
index 000000000..5bb6f3413
--- /dev/null
+++ b/lib/plugins/revert/plugin.info.txt
@@ -0,0 +1,6 @@
+author Andreas Gohr
+email andi@splitbrain.org
+date 2008-12-10
+name Revert Manager
+desc Allows you to mass revert recent edits
+url http://dokuwiki.org/plugin:revert
diff --git a/lib/plugins/safefnrecode/action.php b/lib/plugins/safefnrecode/action.php
new file mode 100644
index 000000000..5d3eaae3a
--- /dev/null
+++ b/lib/plugins/safefnrecode/action.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * DokuWiki Plugin safefnrecode (Action Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+// must be run within Dokuwiki
+if (!defined('DOKU_INC')) die();
+
+require_once DOKU_PLUGIN.'action.php';
+
+class action_plugin_safefnrecode extends DokuWiki_Action_Plugin {
+
+ public function register(Doku_Event_Handler &$controller) {
+
+ $controller->register_hook('INDEXER_TASKS_RUN', 'BEFORE', $this, 'handle_indexer_tasks_run');
+
+ }
+
+ public function handle_indexer_tasks_run(Doku_Event &$event, $param) {
+ global $conf;
+ if($conf['fnencode'] != 'safe') return;
+
+ if(!file_exists($conf['datadir'].'_safefn.recoded')){
+ $this->recode($conf['datadir']);
+ touch($conf['datadir'].'_safefn.recoded');
+ }
+
+ if(!file_exists($conf['olddir'].'_safefn.recoded')){
+ $this->recode($conf['olddir']);
+ touch($conf['olddir'].'_safefn.recoded');
+ }
+
+ if(!file_exists($conf['metadir'].'_safefn.recoded')){
+ $this->recode($conf['metadir']);
+ touch($conf['metadir'].'_safefn.recoded');
+ }
+
+ if(!file_exists($conf['mediadir'].'_safefn.recoded')){
+ $this->recode($conf['mediadir']);
+ touch($conf['mediadir'].'_safefn.recoded');
+ }
+
+ }
+
+ /**
+ * Recursive function to rename all safe encoded files to use the new
+ * square bracket post indicator
+ */
+ private function recode($dir){
+ $dh = opendir($dir);
+ if(!$dh) return;
+ while (($file = readdir($dh)) !== false) {
+ if($file == '.' || $file == '..') continue; # cur and upper dir
+ if(is_dir("$dir/$file")) $this->recode("$dir/$file"); #recurse
+ if(strpos($file,'%') === false) continue; # no encoding used
+ $new = preg_replace('/(%[^\]]*?)\./','\1]',$file); # new post indicator
+ if(preg_match('/%[^\]]+$/',$new)) $new .= ']'; # fix end FS#2122
+ rename("$dir/$file","$dir/$new"); # rename it
+ }
+ closedir($dh);
+ }
+
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/lib/plugins/safefnrecode/plugin.info.txt b/lib/plugins/safefnrecode/plugin.info.txt
new file mode 100644
index 000000000..b1600060c
--- /dev/null
+++ b/lib/plugins/safefnrecode/plugin.info.txt
@@ -0,0 +1,7 @@
+base safefnrecode
+author Andreas Gohr
+email andi@splitbrain.org
+date 2011-04-03
+name safefnrecode plugin
+desc Changes existing page and foldernames for the change in the safe filename encoding
+url http://www.dokuwiki.org/plugin:safefnrecode
diff --git a/lib/plugins/syntax.php b/lib/plugins/syntax.php
new file mode 100644
index 000000000..12451f636
--- /dev/null
+++ b/lib/plugins/syntax.php
@@ -0,0 +1,282 @@
+<?php
+/**
+ * Syntax Plugin Prototype
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * All DokuWiki plugins to extend the parser/rendering mechanism
+ * need to inherit from this class
+ */
+class DokuWiki_Syntax_Plugin extends Doku_Parser_Mode {
+
+ var $allowedModesSetup = false;
+ var $localised = false; // set to true by setupLocale() after loading language dependent strings
+ var $lang = array(); // array to hold language dependent strings, best accessed via ->getLang()
+ var $configloaded = false; // set to true by loadConfig() after loading plugin configuration variables
+ var $conf = array(); // array to hold plugin settings, best accessed via ->getConf()
+
+ /**
+ * General Info
+ *
+ * Needs to return a associative array with the following values:
+ *
+ * author - Author of the plugin
+ * email - Email address to contact the author
+ * date - Last modified date of the plugin in YYYY-MM-DD format
+ * name - Name of the plugin
+ * desc - Short description of the plugin (Text only)
+ * url - Website with more information on the plugin (eg. syntax description)
+ */
+ function getInfo(){
+ $parts = explode('_',get_class($this));
+ $info = DOKU_PLUGIN.'/'.$parts[2].'/plugin.info.txt';
+ if(@file_exists($info)) return confToHash($info);
+ trigger_error('getInfo() not implemented in '.get_class($this).' and '.$info.' not found', E_USER_WARNING);
+ }
+
+ /**
+ * Syntax Type
+ *
+ * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
+ */
+ function getType(){
+ trigger_error('getType() not implemented in '.get_class($this), E_USER_WARNING);
+ }
+
+ /**
+ * Allowed Mode Types
+ *
+ * Defines the mode types for other dokuwiki markup that maybe nested within the
+ * plugin's own markup. Needs to return an array of one or more of the mode types
+ * defined in $PARSER_MODES in parser.php
+ */
+ function getAllowedTypes() {
+ return array();
+ }
+
+ /**
+ * Paragraph Type
+ *
+ * Defines how this syntax is handled regarding paragraphs. This is important
+ * for correct XHTML nesting. Should return one of the following:
+ *
+ * 'normal' - The plugin can be used inside paragraphs
+ * 'block' - Open paragraphs need to be closed before plugin output
+ * 'stack' - Special case. Plugin wraps other paragraphs.
+ *
+ * @see Doku_Handler_Block
+ */
+ function getPType(){
+ return 'normal';
+ }
+
+ /**
+ * Handler to prepare matched data for the rendering process
+ *
+ * This function can only pass data to render() via its return value - render()
+ * may be not be run during the object's current life.
+ *
+ * Usually you should only need the $match param.
+ *
+ * @param $match string The text matched by the patterns
+ * @param $state int The lexer state for the match
+ * @param $pos int The character position of the matched text
+ * @param $handler ref Reference to the Doku_Handler object
+ * @return array Return an array with all data you want to use in render
+ */
+ function handle($match, $state, $pos, &$handler){
+ trigger_error('handle() not implemented in '.get_class($this), E_USER_WARNING);
+ }
+
+ /**
+ * Handles the actual output creation.
+ *
+ * The function must not assume any other of the classes methods have been run
+ * during the object's current life. The only reliable data it receives are its
+ * parameters.
+ *
+ * The function should always check for the given output format and return false
+ * when a format isn't supported.
+ *
+ * $renderer contains a reference to the renderer object which is
+ * currently handling the rendering. You need to use it for writing
+ * the output. How this is done depends on the renderer used (specified
+ * by $format
+ *
+ * The contents of the $data array depends on what the handler() function above
+ * created
+ *
+ * @param $format string output format being rendered
+ * @param $renderer ref reference to the current renderer object
+ * @param $data array data created by handler()
+ * @return boolean rendered correctly?
+ */
+ function render($format, &$renderer, $data) {
+ trigger_error('render() not implemented in '.get_class($this), E_USER_WARNING);
+
+ }
+
+ /**
+ * There should be no need to override these functions
+ */
+ function accepts($mode) {
+
+ if (!$this->allowedModesSetup) {
+ global $PARSER_MODES;
+
+ $allowedModeTypes = $this->getAllowedTypes();
+ foreach($allowedModeTypes as $mt) {
+ $this->allowedModes = array_merge($this->allowedModes, $PARSER_MODES[$mt]);
+ }
+
+ $idx = array_search(substr(get_class($this), 7), (array) $this->allowedModes);
+ if ($idx !== false) {
+ unset($this->allowedModes[$idx]);
+ }
+ $this->allowedModesSetup = true;
+ }
+
+ return parent::accepts($mode);
+ }
+
+ // plugin introspection methods
+ // extract from class name, format = <plugin type>_plugin_<name>[_<component name>]
+ function getPluginType() { list($t) = explode('_', get_class($this), 2); return $t; }
+ function getPluginName() { list($t, $p, $n) = explode('_', get_class($this), 4); return $n; }
+ function getPluginComponent() { list($t, $p, $n, $c) = explode('_', get_class($this), 4); return (isset($c)?$c:''); }
+
+ // localisation methods
+ /**
+ * getLang($id)
+ *
+ * use this function to access plugin language strings
+ * to try to minimise unnecessary loading of the strings when the plugin doesn't require them
+ * e.g. when info plugin is querying plugins for information about themselves.
+ *
+ * @param $id id of the string to be retrieved
+ * @return string string in appropriate language or english if not available
+ */
+ function getLang($id) {
+ if (!$this->localised) $this->setupLocale();
+
+ return (isset($this->lang[$id]) ? $this->lang[$id] : '');
+ }
+
+ /**
+ * locale_xhtml($id)
+ *
+ * retrieve a language dependent wiki page and pass to xhtml renderer for display
+ * plugin equivalent of p_locale_xhtml()
+ *
+ * @param $id id of language dependent wiki page
+ * @return string parsed contents of the wiki page in xhtml format
+ */
+ function locale_xhtml($id) {
+ return p_cached_output($this->localFN($id));
+ }
+
+ /**
+ * localFN($id)
+ * prepends appropriate path for a language dependent filename
+ * plugin equivalent of localFN()
+ */
+ function localFN($id) {
+ global $conf;
+ $plugin = $this->getPluginName();
+ $file = DOKU_CONF.'/plugin_lang/'.$plugin.'/'.$conf['lang'].'/'.$id.'.txt';
+ if (!@file_exists($file)){
+ $file = DOKU_PLUGIN.$plugin.'/lang/'.$conf['lang'].'/'.$id.'.txt';
+ if(!@file_exists($file)){
+ //fall back to english
+ $file = DOKU_PLUGIN.$plugin.'/lang/en/'.$id.'.txt';
+ }
+ }
+ return $file;
+ }
+
+ /**
+ * setupLocale()
+ * reads all the plugins language dependent strings into $this->lang
+ * this function is automatically called by getLang()
+ */
+ function setupLocale() {
+ if ($this->localised) return;
+
+ global $conf; // definitely don't invoke "global $lang"
+ $path = DOKU_PLUGIN.$this->getPluginName().'/lang/';
+
+ // don't include once, in case several plugin components require the same language file
+ @include($path.'en/lang.php');
+ if ($conf['lang'] != 'en') @include($path.$conf['lang'].'/lang.php');
+
+ $this->lang = $lang;
+ $this->localised = true;
+ }
+
+ // configuration methods
+ /**
+ * getConf($setting)
+ *
+ * use this function to access plugin configuration variables
+ */
+ function getConf($setting){
+
+ if (!$this->configloaded){ $this->loadConfig(); }
+
+ return $this->conf[$setting];
+ }
+
+ /**
+ * loadConfig()
+ * merges the plugin's default settings with any local settings
+ * this function is automatically called through getConf()
+ */
+ function loadConfig(){
+ global $conf;
+
+ $defaults = $this->readDefaultSettings();
+ $plugin = $this->getPluginName();
+
+ foreach ($defaults as $key => $value) {
+ if (isset($conf['plugin'][$plugin][$key])) continue;
+ $conf['plugin'][$plugin][$key] = $value;
+ }
+
+ $this->configloaded = true;
+ $this->conf =& $conf['plugin'][$plugin];
+ }
+
+ /**
+ * read the plugin's default configuration settings from conf/default.php
+ * this function is automatically called through getConf()
+ *
+ * @return array setting => value
+ */
+ function readDefaultSettings() {
+
+ $path = DOKU_PLUGIN.$this->getPluginName().'/conf/';
+ $conf = array();
+
+ if (@file_exists($path.'default.php')) {
+ include($path.'default.php');
+ }
+
+ return $conf;
+ }
+
+ /**
+ * Allow the plugin to prevent DokuWiki from reusing an instance
+ *
+ * @return bool false if the plugin has to be instantiated
+ */
+ function isSingleton() {
+ return true;
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/plugins/usermanager/admin.php b/lib/plugins/usermanager/admin.php
new file mode 100644
index 000000000..8b646b426
--- /dev/null
+++ b/lib/plugins/usermanager/admin.php
@@ -0,0 +1,630 @@
+<?php
+/*
+ * User Manager
+ *
+ * Dokuwiki Admin Plugin
+ *
+ * This version of the user manager has been modified to only work with
+ * objectified version of auth system
+ *
+ * @author neolao <neolao@neolao.com>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+if(!defined('DOKU_PLUGIN_IMAGES')) define('DOKU_PLUGIN_IMAGES',DOKU_BASE.'lib/plugins/usermanager/images/');
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_usermanager extends DokuWiki_Admin_Plugin {
+
+ var $_auth = null; // auth object
+ var $_user_total = 0; // number of registered users
+ var $_filter = array(); // user selection filter(s)
+ var $_start = 0; // index of first user to be displayed
+ var $_last = 0; // index of the last user to be displayed
+ var $_pagesize = 20; // number of users to list on one page
+ var $_edit_user = ''; // set to user selected for editing
+ var $_edit_userdata = array();
+ var $_disabled = ''; // if disabled set to explanatory string
+
+ /**
+ * Constructor
+ */
+ function admin_plugin_usermanager(){
+ global $auth;
+
+ $this->setupLocale();
+
+ if (!isset($auth)) {
+ $this->disabled = $this->lang['noauth'];
+ } else if (!$auth->canDo('getUsers')) {
+ $this->disabled = $this->lang['nosupport'];
+ } else {
+
+ // we're good to go
+ $this->_auth = & $auth;
+
+ }
+ }
+
+ /**
+ * return prompt for admin menu
+ */
+ function getMenuText($language) {
+
+ if (!is_null($this->_auth))
+ return parent::getMenuText($language);
+
+ return $this->getLang('menu').' '.$this->disabled;
+ }
+
+ /**
+ * return sort order for position in admin menu
+ */
+ function getMenuSort() {
+ return 2;
+ }
+
+ /**
+ * handle user request
+ */
+ function handle() {
+ global $ID;
+
+ if (is_null($this->_auth)) return false;
+
+ // extract the command and any specific parameters
+ // submit button name is of the form - fn[cmd][param(s)]
+ $fn = $_REQUEST['fn'];
+
+ if (is_array($fn)) {
+ $cmd = key($fn);
+ $param = is_array($fn[$cmd]) ? key($fn[$cmd]) : null;
+ } else {
+ $cmd = $fn;
+ $param = null;
+ }
+
+ if ($cmd != "search") {
+ if (!empty($_REQUEST['start']))
+ $this->_start = $_REQUEST['start'];
+ $this->_filter = $this->_retrieveFilter();
+ }
+
+ switch($cmd){
+ case "add" : $this->_addUser(); break;
+ case "delete" : $this->_deleteUser(); break;
+ case "modify" : $this->_modifyUser(); break;
+ case "edit" : $this->_editUser($param); break;
+ case "search" : $this->_setFilter($param);
+ $this->_start = 0;
+ break;
+ }
+
+ $this->_user_total = $this->_auth->canDo('getUserCount') ? $this->_auth->getUserCount($this->_filter) : -1;
+
+ // page handling
+ switch($cmd){
+ case 'start' : $this->_start = 0; break;
+ case 'prev' : $this->_start -= $this->_pagesize; break;
+ case 'next' : $this->_start += $this->_pagesize; break;
+ case 'last' : $this->_start = $this->_user_total; break;
+ }
+ $this->_validatePagination();
+ }
+
+ /**
+ * output appropriate html
+ */
+ function html() {
+ global $ID;
+
+ if(is_null($this->_auth)) {
+ print $this->lang['badauth'];
+ return false;
+ }
+
+ $user_list = $this->_auth->retrieveUsers($this->_start, $this->_pagesize, $this->_filter);
+ $users = array_keys($user_list);
+
+ $page_buttons = $this->_pagination();
+ $delete_disable = $this->_auth->canDo('delUser') ? '' : 'disabled="disabled"';
+
+ $editable = $this->_auth->canDo('UserMod');
+
+ print $this->locale_xhtml('intro');
+ print $this->locale_xhtml('list');
+
+ ptln("<div id=\"user__manager\">");
+ ptln("<div class=\"level2\">");
+
+ if ($this->_user_total > 0) {
+ ptln("<p>".sprintf($this->lang['summary'],$this->_start+1,$this->_last,$this->_user_total,$this->_auth->getUserCount())."</p>");
+ } else {
+ ptln("<p>".sprintf($this->lang['nonefound'],$this->_auth->getUserCount())."</p>");
+ }
+ ptln("<form action=\"".wl($ID)."\" method=\"post\">");
+ formSecurityToken();
+ ptln(" <div class=\"table\">");
+ ptln(" <table class=\"inline\">");
+ ptln(" <thead>");
+ ptln(" <tr>");
+ ptln(" <th>&nbsp;</th><th>".$this->lang["user_id"]."</th><th>".$this->lang["user_name"]."</th><th>".$this->lang["user_mail"]."</th><th>".$this->lang["user_groups"]."</th>");
+ ptln(" </tr>");
+
+ ptln(" <tr>");
+ ptln(" <td class=\"rightalign\"><input type=\"image\" src=\"".DOKU_PLUGIN_IMAGES."search.png\" name=\"fn[search][new]\" title=\"".$this->lang['search_prompt']."\" alt=\"".$this->lang['search']."\" class=\"button\" /></td>");
+ ptln(" <td><input type=\"text\" name=\"userid\" class=\"edit\" value=\"".$this->_htmlFilter('user')."\" /></td>");
+ ptln(" <td><input type=\"text\" name=\"username\" class=\"edit\" value=\"".$this->_htmlFilter('name')."\" /></td>");
+ ptln(" <td><input type=\"text\" name=\"usermail\" class=\"edit\" value=\"".$this->_htmlFilter('mail')."\" /></td>");
+ ptln(" <td><input type=\"text\" name=\"usergroups\" class=\"edit\" value=\"".$this->_htmlFilter('grps')."\" /></td>");
+ ptln(" </tr>");
+ ptln(" </thead>");
+
+ if ($this->_user_total) {
+ ptln(" <tbody>");
+ foreach ($user_list as $user => $userinfo) {
+ extract($userinfo);
+ $groups = join(', ',$grps);
+ ptln(" <tr class=\"user_info\">");
+ ptln(" <td class=\"centeralign\"><input type=\"checkbox\" name=\"delete[".$user."]\" ".$delete_disable." /></td>");
+ if ($editable) {
+ ptln(" <td><a href=\"".wl($ID,array('fn[edit]['.hsc($user).']' => 1,
+ 'do' => 'admin',
+ 'page' => 'usermanager',
+ 'sectok' => getSecurityToken())).
+ "\" title=\"".$this->lang['edit_prompt']."\">".hsc($user)."</a></td>");
+ } else {
+ ptln(" <td>".hsc($user)."</td>");
+ }
+ ptln(" <td>".hsc($name)."</td><td>".hsc($mail)."</td><td>".hsc($groups)."</td>");
+ ptln(" </tr>");
+ }
+ ptln(" </tbody>");
+ }
+
+ ptln(" <tbody>");
+ ptln(" <tr><td colspan=\"5\" class=\"centeralign\">");
+ ptln(" <span class=\"medialeft\">");
+ ptln(" <input type=\"submit\" name=\"fn[delete]\" ".$delete_disable." class=\"button\" value=\"".$this->lang['delete_selected']."\" id=\"usrmgr__del\" />");
+ ptln(" </span>");
+ ptln(" <span class=\"mediaright\">");
+ ptln(" <input type=\"submit\" name=\"fn[start]\" ".$page_buttons['start']." class=\"button\" value=\"".$this->lang['start']."\" />");
+ ptln(" <input type=\"submit\" name=\"fn[prev]\" ".$page_buttons['prev']." class=\"button\" value=\"".$this->lang['prev']."\" />");
+ ptln(" <input type=\"submit\" name=\"fn[next]\" ".$page_buttons['next']." class=\"button\" value=\"".$this->lang['next']."\" />");
+ ptln(" <input type=\"submit\" name=\"fn[last]\" ".$page_buttons['last']." class=\"button\" value=\"".$this->lang['last']."\" />");
+ ptln(" </span>");
+ ptln(" <input type=\"submit\" name=\"fn[search][clear]\" class=\"button\" value=\"".$this->lang['clear']."\" />");
+ ptln(" <input type=\"hidden\" name=\"do\" value=\"admin\" />");
+ ptln(" <input type=\"hidden\" name=\"page\" value=\"usermanager\" />");
+
+ $this->_htmlFilterSettings(2);
+
+ ptln(" </td></tr>");
+ ptln(" </tbody>");
+ ptln(" </table>");
+ ptln(" </div>");
+
+ ptln("</form>");
+ ptln("</div>");
+
+ $style = $this->_edit_user ? " class=\"edit_user\"" : "";
+
+ if ($this->_auth->canDo('addUser')) {
+ ptln("<div".$style.">");
+ print $this->locale_xhtml('add');
+ ptln(" <div class=\"level2\">");
+
+ $this->_htmlUserForm('add',null,array(),4);
+
+ ptln(" </div>");
+ ptln("</div>");
+ }
+
+ if($this->_edit_user && $this->_auth->canDo('UserMod')){
+ ptln("<div".$style." id=\"scroll__here\">");
+ print $this->locale_xhtml('edit');
+ ptln(" <div class=\"level2\">");
+
+ $this->_htmlUserForm('modify',$this->_edit_user,$this->_edit_userdata,4);
+
+ ptln(" </div>");
+ ptln("</div>");
+ }
+ ptln("</div>");
+ }
+
+
+ /**
+ * @todo disable fields which the backend can't change
+ */
+ function _htmlUserForm($cmd,$user='',$userdata=array(),$indent=0) {
+ global $conf;
+ global $ID;
+
+ $name = $mail = $groups = '';
+ $notes = array();
+
+ if ($user) {
+ extract($userdata);
+ if (!empty($grps)) $groups = join(',',$grps);
+ } else {
+ $notes[] = sprintf($this->lang['note_group'],$conf['defaultgroup']);
+ }
+
+ ptln("<form action=\"".wl($ID)."\" method=\"post\">",$indent);
+ formSecurityToken();
+ ptln(" <div class=\"table\">",$indent);
+ ptln(" <table class=\"inline\">",$indent);
+ ptln(" <thead>",$indent);
+ ptln(" <tr><th>".$this->lang["field"]."</th><th>".$this->lang["value"]."</th></tr>",$indent);
+ ptln(" </thead>",$indent);
+ ptln(" <tbody>",$indent);
+
+ $this->_htmlInputField($cmd."_userid", "userid", $this->lang["user_id"], $user, $this->_auth->canDo("modLogin"), $indent+6);
+ $this->_htmlInputField($cmd."_userpass", "userpass", $this->lang["user_pass"], "", $this->_auth->canDo("modPass"), $indent+6);
+ $this->_htmlInputField($cmd."_username", "username", $this->lang["user_name"], $name, $this->_auth->canDo("modName"), $indent+6);
+ $this->_htmlInputField($cmd."_usermail", "usermail", $this->lang["user_mail"], $mail, $this->_auth->canDo("modMail"), $indent+6);
+ $this->_htmlInputField($cmd."_usergroups","usergroups",$this->lang["user_groups"],$groups,$this->_auth->canDo("modGroups"),$indent+6);
+
+ if ($this->_auth->canDo("modPass")) {
+ $notes[] = $this->lang['note_pass'];
+ if ($user) {
+ $notes[] = $this->lang['note_notify'];
+ }
+
+ ptln("<tr><td><label for=\"".$cmd."_usernotify\" >".$this->lang["user_notify"].": </label></td><td><input type=\"checkbox\" id=\"".$cmd."_usernotify\" name=\"usernotify\" value=\"1\" /></td></tr>", $indent);
+ }
+
+ ptln(" </tbody>",$indent);
+ ptln(" <tbody>",$indent);
+ ptln(" <tr>",$indent);
+ ptln(" <td colspan=\"2\">",$indent);
+ ptln(" <input type=\"hidden\" name=\"do\" value=\"admin\" />",$indent);
+ ptln(" <input type=\"hidden\" name=\"page\" value=\"usermanager\" />",$indent);
+
+ // save current $user, we need this to access details if the name is changed
+ if ($user)
+ ptln(" <input type=\"hidden\" name=\"userid_old\" value=\"".$user."\" />",$indent);
+
+ $this->_htmlFilterSettings($indent+10);
+
+ ptln(" <input type=\"submit\" name=\"fn[".$cmd."]\" class=\"button\" value=\"".$this->lang[$cmd]."\" />",$indent);
+ ptln(" </td>",$indent);
+ ptln(" </tr>",$indent);
+ ptln(" </tbody>",$indent);
+ ptln(" </table>",$indent);
+ ptln(" </div>",$indent);
+
+ foreach ($notes as $note)
+ ptln("<div class=\"fn\">".$note."</div>",$indent);
+
+ ptln("</form>",$indent);
+ }
+
+ function _htmlInputField($id, $name, $label, $value, $cando, $indent=0) {
+ $class = $cando ? '' : ' class="disabled"';
+ $disabled = $cando ? '' : ' disabled="disabled"';
+ echo str_pad('',$indent);
+
+ if($name == 'userpass'){
+ $fieldtype = 'password';
+ $autocomp = 'autocomplete="off"';
+ }else{
+ $fieldtype = 'text';
+ $autocomp = '';
+ }
+
+
+ echo "<tr $class>";
+ echo "<td><label for=\"$id\" >$label: </label></td>";
+ echo "<td>";
+ if($cando){
+ echo "<input type=\"$fieldtype\" id=\"$id\" name=\"$name\" value=\"$value\" class=\"edit\" $autocomp />";
+ }else{
+ echo "<input type=\"hidden\" name=\"$name\" value=\"$value\" />";
+ echo "<input type=\"$fieldtype\" id=\"$id\" name=\"$name\" value=\"$value\" class=\"edit disabled\" disabled=\"disabled\" />";
+ }
+ echo "</td>";
+ echo "</tr>";
+ }
+
+ function _htmlFilter($key) {
+ if (empty($this->_filter)) return '';
+ return (isset($this->_filter[$key]) ? hsc($this->_filter[$key]) : '');
+ }
+
+ function _htmlFilterSettings($indent=0) {
+
+ ptln("<input type=\"hidden\" name=\"start\" value=\"".$this->_start."\" />",$indent);
+
+ foreach ($this->_filter as $key => $filter) {
+ ptln("<input type=\"hidden\" name=\"filter[".$key."]\" value=\"".hsc($filter)."\" />",$indent);
+ }
+ }
+
+ function _addUser(){
+ if (!checkSecurityToken()) return false;
+ if (!$this->_auth->canDo('addUser')) return false;
+
+ list($user,$pass,$name,$mail,$grps) = $this->_retrieveUser();
+ if (empty($user)) return false;
+
+ if ($this->_auth->canDo('modPass')){
+ if (empty($pass)){
+ if(!empty($_REQUEST['usernotify'])){
+ $pass = auth_pwgen();
+ } else {
+ msg($this->lang['add_fail'], -1);
+ return false;
+ }
+ }
+ } else {
+ if (!empty($pass)){
+ msg($this->lang['add_fail'], -1);
+ return false;
+ }
+ }
+
+ if ($this->_auth->canDo('modName')){
+ if (empty($name)){
+ msg($this->lang['add_fail'], -1);
+ return false;
+ }
+ } else {
+ if (!empty($name)){
+ return false;
+ }
+ }
+
+ if ($this->_auth->canDo('modMail')){
+ if (empty($mail)){
+ msg($this->lang['add_fail'], -1);
+ return false;
+ }
+ } else {
+ if (!empty($mail)){
+ return false;
+ }
+ }
+
+ if ($ok = $this->_auth->triggerUserMod('create', array($user,$pass,$name,$mail,$grps))) {
+
+ msg($this->lang['add_ok'], 1);
+
+ if (!empty($_REQUEST['usernotify']) && $pass) {
+ $this->_notifyUser($user,$pass);
+ }
+ } else {
+ msg($this->lang['add_fail'], -1);
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Delete user
+ */
+ function _deleteUser(){
+ global $conf;
+
+ if (!checkSecurityToken()) return false;
+ if (!$this->_auth->canDo('delUser')) return false;
+
+ $selected = $_REQUEST['delete'];
+ if (!is_array($selected) || empty($selected)) return false;
+ $selected = array_keys($selected);
+
+ if(in_array($_SERVER['REMOTE_USER'], $selected)) {
+ msg("You can't delete yourself!", -1);
+ return false;
+ }
+
+ $count = $this->_auth->triggerUserMod('delete', array($selected));
+ if ($count == count($selected)) {
+ $text = str_replace('%d', $count, $this->lang['delete_ok']);
+ msg("$text.", 1);
+ } else {
+ $part1 = str_replace('%d', $count, $this->lang['delete_ok']);
+ $part2 = str_replace('%d', (count($selected)-$count), $this->lang['delete_fail']);
+ msg("$part1, $part2",-1);
+ }
+
+ // invalidate all sessions
+ io_saveFile($conf['cachedir'].'/sessionpurge',time());
+
+ return true;
+ }
+
+ /**
+ * Edit user (a user has been selected for editing)
+ */
+ function _editUser($param) {
+ if (!checkSecurityToken()) return false;
+ if (!$this->_auth->canDo('UserMod')) return false;
+
+ $user = cleanID(preg_replace('/.*:/','',$param));
+ $userdata = $this->_auth->getUserData($user);
+
+ // no user found?
+ if (!$userdata) {
+ msg($this->lang['edit_usermissing'],-1);
+ return false;
+ }
+
+ $this->_edit_user = $user;
+ $this->_edit_userdata = $userdata;
+
+ return true;
+ }
+
+ /**
+ * Modify user (modified user data has been recieved)
+ */
+ function _modifyUser(){
+ global $conf;
+
+ if (!checkSecurityToken()) return false;
+ if (!$this->_auth->canDo('UserMod')) return false;
+
+ // get currently valid user data
+ $olduser = cleanID(preg_replace('/.*:/','',$_REQUEST['userid_old']));
+ $oldinfo = $this->_auth->getUserData($olduser);
+
+ // get new user data subject to change
+ list($newuser,$newpass,$newname,$newmail,$newgrps) = $this->_retrieveUser();
+ if (empty($newuser)) return false;
+
+ $changes = array();
+ if ($newuser != $olduser) {
+
+ if (!$this->_auth->canDo('modLogin')) { // sanity check, shouldn't be possible
+ msg($this->lang['update_fail'],-1);
+ return false;
+ }
+
+ // check if $newuser already exists
+ if ($this->_auth->getUserData($newuser)) {
+ msg(sprintf($this->lang['update_exists'],$newuser),-1);
+ $re_edit = true;
+ } else {
+ $changes['user'] = $newuser;
+ }
+ }
+
+ // generate password if left empty and notification is on
+ if(!empty($_REQUEST['usernotify']) && empty($newpass)){
+ $newpass = auth_pwgen();
+ }
+
+ if (!empty($newpass) && $this->_auth->canDo('modPass'))
+ $changes['pass'] = $newpass;
+ if (!empty($newname) && $this->_auth->canDo('modName') && $newname != $oldinfo['name'])
+ $changes['name'] = $newname;
+ if (!empty($newmail) && $this->_auth->canDo('modMail') && $newmail != $oldinfo['mail'])
+ $changes['mail'] = $newmail;
+ if (!empty($newgrps) && $this->_auth->canDo('modGroups') && $newgrps != $oldinfo['grps'])
+ $changes['grps'] = $newgrps;
+
+ if ($ok = $this->_auth->triggerUserMod('modify', array($olduser, $changes))) {
+ msg($this->lang['update_ok'],1);
+
+ if (!empty($_REQUEST['usernotify']) && $newpass) {
+ $notify = empty($changes['user']) ? $olduser : $newuser;
+ $this->_notifyUser($notify,$newpass);
+ }
+
+ // invalidate all sessions
+ io_saveFile($conf['cachedir'].'/sessionpurge',time());
+
+ } else {
+ msg($this->lang['update_fail'],-1);
+ }
+
+ if (!empty($re_edit)) {
+ $this->_editUser($olduser);
+ }
+
+ return $ok;
+ }
+
+ /**
+ * send password change notification email
+ */
+ function _notifyUser($user, $password) {
+
+ if ($sent = auth_sendPassword($user,$password)) {
+ msg($this->lang['notify_ok'], 1);
+ } else {
+ msg($this->lang['notify_fail'], -1);
+ }
+
+ return $sent;
+ }
+
+ /**
+ * retrieve & clean user data from the form
+ *
+ * @return array(user, password, full name, email, array(groups))
+ */
+ function _retrieveUser($clean=true) {
+ global $auth;
+
+ $user[0] = ($clean) ? $auth->cleanUser($_REQUEST['userid']) : $_REQUEST['userid'];
+ $user[1] = $_REQUEST['userpass'];
+ $user[2] = $_REQUEST['username'];
+ $user[3] = $_REQUEST['usermail'];
+ $user[4] = explode(',',$_REQUEST['usergroups']);
+
+ $user[4] = array_map('trim',$user[4]);
+ if($clean) $user[4] = array_map(array($auth,'cleanGroup'),$user[4]);
+ $user[4] = array_filter($user[4]);
+ $user[4] = array_unique($user[4]);
+ if(!count($user[4])) $user[4] = null;
+
+ return $user;
+ }
+
+ function _setFilter($op) {
+
+ $this->_filter = array();
+
+ if ($op == 'new') {
+ list($user,$pass,$name,$mail,$grps) = $this->_retrieveUser(false);
+
+ if (!empty($user)) $this->_filter['user'] = $user;
+ if (!empty($name)) $this->_filter['name'] = $name;
+ if (!empty($mail)) $this->_filter['mail'] = $mail;
+ if (!empty($grps)) $this->_filter['grps'] = join('|',$grps);
+ }
+ }
+
+ function _retrieveFilter() {
+
+ $t_filter = $_REQUEST['filter'];
+ if (!is_array($t_filter)) return array();
+
+ // messy, but this way we ensure we aren't getting any additional crap from malicious users
+ $filter = array();
+
+ if (isset($t_filter['user'])) $filter['user'] = $t_filter['user'];
+ if (isset($t_filter['name'])) $filter['name'] = $t_filter['name'];
+ if (isset($t_filter['mail'])) $filter['mail'] = $t_filter['mail'];
+ if (isset($t_filter['grps'])) $filter['grps'] = $t_filter['grps'];
+
+ return $filter;
+ }
+
+ function _validatePagination() {
+
+ if ($this->_start >= $this->_user_total) {
+ $this->_start = $this->_user_total - $this->_pagesize;
+ }
+ if ($this->_start < 0) $this->_start = 0;
+
+ $this->_last = min($this->_user_total, $this->_start + $this->_pagesize);
+ }
+
+ /*
+ * return an array of strings to enable/disable pagination buttons
+ */
+ function _pagination() {
+
+ $disabled = 'disabled="disabled"';
+
+ $buttons['start'] = $buttons['prev'] = ($this->_start == 0) ? $disabled : '';
+
+ if ($this->_user_total == -1) {
+ $buttons['last'] = $disabled;
+ $buttons['next'] = '';
+ } else {
+ $buttons['last'] = $buttons['next'] = (($this->_start + $this->_pagesize) >= $this->_user_total) ? $disabled : '';
+ }
+
+ return $buttons;
+ }
+}
diff --git a/lib/plugins/usermanager/images/search.png b/lib/plugins/usermanager/images/search.png
new file mode 100644
index 000000000..e9dabc11e
--- /dev/null
+++ b/lib/plugins/usermanager/images/search.png
Binary files differ
diff --git a/lib/plugins/usermanager/lang/af/lang.php b/lib/plugins/usermanager/lang/af/lang.php
new file mode 100644
index 000000000..9a6c5666d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/af/lang.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Afrikaans language file
+ *
+ */
+$lang['user_pass'] = 'Wagwoord';
+$lang['user_name'] = 'Regte Naam';
+$lang['user_mail'] = 'E-pos';
+$lang['edit'] = 'Verander';
+$lang['search'] = 'Soek';
+$lang['start'] = 'begin';
+$lang['prev'] = 'voorigste';
+$lang['next'] = 'volgende';
+$lang['last'] = 'einde';
diff --git a/lib/plugins/usermanager/lang/ar/add.txt b/lib/plugins/usermanager/lang/ar/add.txt
new file mode 100644
index 000000000..14a10a27d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ar/add.txt
@@ -0,0 +1 @@
+==== إضافة حساب ==== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ar/delete.txt b/lib/plugins/usermanager/lang/ar/delete.txt
new file mode 100644
index 000000000..d44bb9fda
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ar/delete.txt
@@ -0,0 +1 @@
+==== حذف الحساب ==== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ar/edit.txt b/lib/plugins/usermanager/lang/ar/edit.txt
new file mode 100644
index 000000000..bd9876d82
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ar/edit.txt
@@ -0,0 +1 @@
+==== تعديل المستخدم ==== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ar/intro.txt b/lib/plugins/usermanager/lang/ar/intro.txt
new file mode 100644
index 000000000..1cfb841fa
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ar/intro.txt
@@ -0,0 +1 @@
+====== مدير المستخدمين ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ar/lang.php b/lib/plugins/usermanager/lang/ar/lang.php
new file mode 100644
index 000000000..d4b891320
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ar/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Arabic language file
+ *
+ * @author Yaman Hokan <always.smile.yh@hotmail.com>
+ * @author Usama Akkad <uahello@gmail.com>
+ * @author uahello@gmail.com
+ */
+$lang['menu'] = 'مدير المستخدمين';
+$lang['noauth'] = '(مصادقة المستخدمين غير متوفرة)';
+$lang['nosupport'] = '(إدارة المستخدمين غير متوفرة)';
+$lang['badauth'] = 'آلية مصادقة غير صالحة';
+$lang['user_id'] = 'اسم المستخدم';
+$lang['user_pass'] = 'كلمة السر';
+$lang['user_name'] = 'الاسم الحقيقي';
+$lang['user_mail'] = 'البريد الالكتروني';
+$lang['user_groups'] = 'المجموعات';
+$lang['field'] = 'حقل';
+$lang['value'] = 'القيمة';
+$lang['add'] = 'إضافة';
+$lang['delete'] = 'حذف';
+$lang['delete_selected'] = 'حذف المختار';
+$lang['edit'] = 'تحرير';
+$lang['edit_prompt'] = 'حرر هذا المستخدم';
+$lang['modify'] = 'حفظ التعديلات';
+$lang['search'] = 'بحث';
+$lang['search_prompt'] = 'ابدأ البحث';
+$lang['clear'] = 'صفّر مرشح البحث';
+$lang['filter'] = 'المرشّح';
+$lang['summary'] = 'عرض المستخدمين %1$d-%2$d of %3$d وجد. %4$d مستخدم كلي.';
+$lang['nonefound'] = 'لم يوجد مستخدمين. %d مستخدم كليا.';
+$lang['delete_ok'] = '%d مستخدم حذفوا';
+$lang['delete_fail'] = '%d فشل حذفهم.';
+$lang['update_ok'] = 'حُدث المستخدم بنجاح';
+$lang['update_fail'] = 'فشل تحديث المستخدم';
+$lang['update_exists'] = 'لقد فشل تغيير اسم المستخدم , اسم المستخدم المحدد (%s) غير متاح . ( سيتم تطبيق أي تغييرات أخرى )';
+$lang['start'] = 'ابدأ';
+$lang['prev'] = 'السابق';
+$lang['next'] = 'التالي';
+$lang['last'] = 'الأخير';
+$lang['edit_usermissing'] = 'لم يعثر على المستخدم المحدد، يحتمل أن اسم المستخدم قد حذف أو غُير في مكان آخر.';
+$lang['user_notify'] = 'أشعر المستخدم';
+$lang['note_notify'] = 'بريد الاشعار يرسل فقط إن اعطي المستخدم كلمة سر جديدة.';
+$lang['note_group'] = 'المستخدمون الجدد سيضافون للمجموعة الافتراضية (%s) إن لم تُحدد لهم مجموعة.';
+$lang['note_pass'] = 'ستولد كلمة المرور تلقائيا إن تُرك الحقل فارغا مع تمكين إشعار المستخدم.';
+$lang['add_ok'] = 'اضيف المستخدم بنجاح';
+$lang['add_fail'] = 'فشلت إضافة المستخدم';
+$lang['notify_ok'] = 'ارسلت رسالة الاشعار';
+$lang['notify_fail'] = 'تعذر ارسال بريد الاشعار';
diff --git a/lib/plugins/usermanager/lang/ar/list.txt b/lib/plugins/usermanager/lang/ar/list.txt
new file mode 100644
index 000000000..02e9a0363
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ar/list.txt
@@ -0,0 +1 @@
+===== قائمة المستخدمين ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/bg/add.txt b/lib/plugins/usermanager/lang/bg/add.txt
new file mode 100644
index 000000000..e0678198b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/bg/add.txt
@@ -0,0 +1 @@
+===== Добавяне на потребител =====
diff --git a/lib/plugins/usermanager/lang/bg/delete.txt b/lib/plugins/usermanager/lang/bg/delete.txt
new file mode 100644
index 000000000..aa60fc3df
--- /dev/null
+++ b/lib/plugins/usermanager/lang/bg/delete.txt
@@ -0,0 +1 @@
+===== Изтриване на потребител =====
diff --git a/lib/plugins/usermanager/lang/bg/edit.txt b/lib/plugins/usermanager/lang/bg/edit.txt
new file mode 100644
index 000000000..652d03617
--- /dev/null
+++ b/lib/plugins/usermanager/lang/bg/edit.txt
@@ -0,0 +1 @@
+===== Редактиране на потребител =====
diff --git a/lib/plugins/usermanager/lang/bg/intro.txt b/lib/plugins/usermanager/lang/bg/intro.txt
new file mode 100644
index 000000000..0a9afd513
--- /dev/null
+++ b/lib/plugins/usermanager/lang/bg/intro.txt
@@ -0,0 +1 @@
+====== Управление на потребителите ======
diff --git a/lib/plugins/usermanager/lang/bg/lang.php b/lib/plugins/usermanager/lang/bg/lang.php
new file mode 100644
index 000000000..9ed27f42a
--- /dev/null
+++ b/lib/plugins/usermanager/lang/bg/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * bulgarian language file
+ *
+ * @author Nikolay Vladimirov <nikolay@vladimiroff.com>
+ * @author Viktor Usunov <usun0v@mail.bg>
+ * @author Kiril <neohidra@gmail.com>
+ */
+$lang['menu'] = 'Диспечер на потребителите';
+$lang['noauth'] = '(удостоверяването на потребители не е налично)';
+$lang['nosupport'] = '(управлението на потребители не се поддържа)';
+$lang['badauth'] = 'невалиден механизъм за удостоверяване';
+$lang['user_id'] = 'Потребител';
+$lang['user_pass'] = 'Парола';
+$lang['user_name'] = 'Истинско име';
+$lang['user_mail'] = 'Електронна поща';
+$lang['user_groups'] = 'Групи';
+$lang['field'] = 'Поле';
+$lang['value'] = 'Стойност';
+$lang['add'] = 'Добави';
+$lang['delete'] = 'Изтрий';
+$lang['delete_selected'] = 'Изтрий избраните';
+$lang['edit'] = 'Редактирай';
+$lang['edit_prompt'] = 'Редактиране на потребителя';
+$lang['modify'] = 'Запиши промените';
+$lang['search'] = 'Търсене';
+$lang['search_prompt'] = 'Търси';
+$lang['clear'] = 'Обновяване на търсенето';
+$lang['filter'] = 'Филтър';
+$lang['summary'] = 'Показване на потребители %1$d-%2$d от %3$d намерени. Общо %4$d потребителя.';
+$lang['nonefound'] = 'Не са намерени потребители. Общо %d потребителя.';
+$lang['delete_ok'] = '%d изтрити потребителя';
+$lang['delete_fail'] = 'изтриването на %d се провали.';
+$lang['update_ok'] = 'Обновяването на потребителя е успешно';
+$lang['update_fail'] = 'Обновяването на потребителя се провали';
+$lang['update_exists'] = 'Смяната на потребителското име се провали, въведеното потребителско име (%s) вече съществува (всички други промени ще бъдат приложени).';
+$lang['start'] = 'начало';
+$lang['prev'] = 'назад';
+$lang['next'] = 'напред';
+$lang['last'] = 'край';
+$lang['edit_usermissing'] = 'Избраният потребител не е намерен, въведеното потребителско име може да е изтрито или променено другаде.';
+$lang['user_notify'] = 'Уведомяване на потребителя';
+$lang['note_notify'] = 'Ел. писмо се изпраща само ако бъде променена паролата на потребителя.';
+$lang['note_group'] = 'Новите потребители биват добавяни към стандартната групата (%s) ако не е посочена друга.';
+$lang['note_pass'] = 'Паролата ще бъде генерирана автоматично, ако оставите полето празно и функцията за уведомяване на потребителя е включена.';
+$lang['add_ok'] = 'Добавянето на потребителя е успешно';
+$lang['add_fail'] = 'Добавянето на потребителя се провали';
+$lang['notify_ok'] = 'Изпратено е осведомително ел. писмо';
+$lang['notify_fail'] = 'Изпращането на осведомително ел. писмо не е възможно';
diff --git a/lib/plugins/usermanager/lang/bg/list.txt b/lib/plugins/usermanager/lang/bg/list.txt
new file mode 100644
index 000000000..106856c0e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/bg/list.txt
@@ -0,0 +1 @@
+===== Списък на потребителите =====
diff --git a/lib/plugins/usermanager/lang/ca-valencia/add.txt b/lib/plugins/usermanager/lang/ca-valencia/add.txt
new file mode 100644
index 000000000..df5ba9235
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca-valencia/add.txt
@@ -0,0 +1 @@
+===== Afegir usuari =====
diff --git a/lib/plugins/usermanager/lang/ca-valencia/delete.txt b/lib/plugins/usermanager/lang/ca-valencia/delete.txt
new file mode 100644
index 000000000..f386b589a
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca-valencia/delete.txt
@@ -0,0 +1 @@
+===== Borrar usuari =====
diff --git a/lib/plugins/usermanager/lang/ca-valencia/edit.txt b/lib/plugins/usermanager/lang/ca-valencia/edit.txt
new file mode 100644
index 000000000..6b78c127f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca-valencia/edit.txt
@@ -0,0 +1 @@
+===== Editar usuari =====
diff --git a/lib/plugins/usermanager/lang/ca-valencia/intro.txt b/lib/plugins/usermanager/lang/ca-valencia/intro.txt
new file mode 100644
index 000000000..540a0702e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca-valencia/intro.txt
@@ -0,0 +1 @@
+====== Gestor d'usuaris ======
diff --git a/lib/plugins/usermanager/lang/ca-valencia/lang.php b/lib/plugins/usermanager/lang/ca-valencia/lang.php
new file mode 100644
index 000000000..5b0c628ed
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca-valencia/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Valencian language file
+ *
+ * @author Bernat Arlandis i Mañó <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@llenguaitecnologia.com>
+ */
+$lang['menu'] = 'Gestor d\'usuaris';
+$lang['noauth'] = '(autenticació d\'usuaris no disponible)';
+$lang['nosupport'] = '(gestió d\'usuaris no admesa)';
+$lang['badauth'] = 'mecanisme d\'autenticació no vàlit';
+$lang['user_id'] = 'Usuari';
+$lang['user_pass'] = 'Contrasenya';
+$lang['user_name'] = 'Nom real';
+$lang['user_mail'] = 'Correu electrònic';
+$lang['user_groups'] = 'Grups';
+$lang['field'] = 'Camp';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Afegir';
+$lang['delete'] = 'Borrar';
+$lang['delete_selected'] = 'Borrar seleccionats';
+$lang['edit'] = 'Editar';
+$lang['edit_prompt'] = 'Editar est usuari';
+$lang['modify'] = 'Guardar canvis';
+$lang['search'] = 'Buscar';
+$lang['search_prompt'] = 'Començar busca';
+$lang['clear'] = 'Reiniciar filtre de busques';
+$lang['filter'] = 'Filtre';
+$lang['summary'] = 'Mostrant usuaris %1$d-%2$d de %3$d trobats. %4$d usuaris totals.';
+$lang['nonefound'] = 'No s\'han trobat usuaris. %d usuaris totals.';
+$lang['delete_ok'] = '%d usuaris borrats';
+$lang['delete_fail'] = 'Erro borrant %d.';
+$lang['update_ok'] = 'Usuari actualisat correctament';
+$lang['update_fail'] = 'Erro actualisant usuari';
+$lang['update_exists'] = 'Erro canviant el nom de l\'usuari, el nom d\'usuari que ha donat ya existix (els demés canvis s\'aplicaran).';
+$lang['start'] = 'primera';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'següent';
+$lang['last'] = 'última';
+$lang['edit_usermissing'] = 'L\'usuari seleccionat no existix, pot haver segut borrat o modificat des d\'un atre lloc.';
+$lang['user_notify'] = 'Notificar a l\'usuari';
+$lang['note_notify'] = 'Els correus de notificació només s\'envien si a l\'usuari se li assigna una contrasenya nova.';
+$lang['note_group'] = 'Els usuaris nous s\'afegiran al grup predeterminat (%s) si no se n\'especifica atre.';
+$lang['note_pass'] = 'Si es deixa el camp buit i la notificació a l\'usuari està desactivada s\'autogenerarà la contrasenya.';
+$lang['add_ok'] = 'Usuari afegit correctament';
+$lang['add_fail'] = 'Erro afegint usuari';
+$lang['notify_ok'] = 'Correu de notificació enviat';
+$lang['notify_fail'] = 'Erro enviant el correu de notificació';
diff --git a/lib/plugins/usermanager/lang/ca-valencia/list.txt b/lib/plugins/usermanager/lang/ca-valencia/list.txt
new file mode 100644
index 000000000..15af2d56f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca-valencia/list.txt
@@ -0,0 +1 @@
+===== Llista d'usuaris =====
diff --git a/lib/plugins/usermanager/lang/ca/add.txt b/lib/plugins/usermanager/lang/ca/add.txt
new file mode 100644
index 000000000..07c599476
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca/add.txt
@@ -0,0 +1 @@
+===== Nou usuari ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ca/delete.txt b/lib/plugins/usermanager/lang/ca/delete.txt
new file mode 100644
index 000000000..90878e563
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca/delete.txt
@@ -0,0 +1 @@
+===== Supressió d'usuari ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ca/edit.txt b/lib/plugins/usermanager/lang/ca/edit.txt
new file mode 100644
index 000000000..f7dc8cb8e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca/edit.txt
@@ -0,0 +1 @@
+===== Edició d'usuari ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ca/intro.txt b/lib/plugins/usermanager/lang/ca/intro.txt
new file mode 100644
index 000000000..864aa1008
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca/intro.txt
@@ -0,0 +1 @@
+======= Gestió d'usuaris ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ca/lang.php b/lib/plugins/usermanager/lang/ca/lang.php
new file mode 100644
index 000000000..445556973
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Catalan language file
+ *
+ * @author Carles Bellver <carles.bellver@gmail.com>
+ * @author carles.bellver@gmail.com
+ * @author carles.bellver@cent.uji.es
+ * @author Carles Bellver <carles.bellver@cent.uji.es>
+ */
+$lang['menu'] = 'Gestió d\'usuaris';
+$lang['noauth'] = '(l\'autenticació d\'usuaris no està disponible)';
+$lang['nosupport'] = '(la gestió d\'usuaris no funciona)';
+$lang['badauth'] = 'el mecanisme d\'autenticació no és vàlid';
+$lang['user_id'] = 'Usuari';
+$lang['user_pass'] = 'Contrasenya';
+$lang['user_name'] = 'Nom real';
+$lang['user_mail'] = 'Correu electrònic';
+$lang['user_groups'] = 'Grups';
+$lang['field'] = 'Camp';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Afegeix';
+$lang['delete'] = 'Suprimeix';
+$lang['delete_selected'] = 'Suprimeix els seleccionats';
+$lang['edit'] = 'Edita';
+$lang['edit_prompt'] = 'Edita aquest usuari';
+$lang['modify'] = 'Desa els canvis';
+$lang['search'] = 'Cerca';
+$lang['search_prompt'] = 'Fes la cerca';
+$lang['clear'] = 'Reinicia el filtre de cerca';
+$lang['filter'] = 'Filtre';
+$lang['summary'] = 'Visualització d\'usuaris %1$d-%2$d de %3$d trobats. %4$d usuaris en total.';
+$lang['nonefound'] = 'No s\'han trobat usuaris. %d usuaris en total.';
+$lang['delete_ok'] = 'S\'han suprimit %d usuaris';
+$lang['delete_fail'] = 'No s\'han pogut suprimir %d.';
+$lang['update_ok'] = 'L\'usuari ha estat actualitzat amb èxit';
+$lang['update_fail'] = 'Ha fallat l\'actualització de l\'usuari';
+$lang['update_exists'] = 'No s\'ha pogut canviar el nom de l\'usuari. El nom d\'usuari especificat (%s) ja existeix (qualsevol altre canvi sí que serà efectiu).';
+$lang['start'] = 'inici';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'següent';
+$lang['last'] = 'final';
+$lang['edit_usermissing'] = 'L\'usuari seleccionat no s\'ha pogut trobar. Potser el nom d\'usuari especificat s\'ha suprimit o modificat des d\'un altre lloc.';
+$lang['user_notify'] = 'Notificació a l\'usuari';
+$lang['note_notify'] = 'Els correus de notificació només s\'envien si es canvia la contrasenya de l\'usuari.';
+$lang['note_group'] = 'Els nous usuaris s\'afegeixen al grup per defecte (%s) si no s\'especifica un altre grup.';
+$lang['note_pass'] = 'La contrasenya es generarà automàticament si el camp es deixa en blanc i les notificacions estan habilitades per a aquest usuari.';
+$lang['add_ok'] = 'L\'usuari s\'ha afegit amb èxit';
+$lang['add_fail'] = 'No s\'ha pogut afegir l\'usuari';
+$lang['notify_ok'] = 'S\'ha enviat el correu de notificació';
+$lang['notify_fail'] = 'No s\'ha pogut enviar el correu de notificació';
diff --git a/lib/plugins/usermanager/lang/ca/list.txt b/lib/plugins/usermanager/lang/ca/list.txt
new file mode 100644
index 000000000..22e1587f4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca/list.txt
@@ -0,0 +1 @@
+===== Llista d'usuaris ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/cs/add.txt b/lib/plugins/usermanager/lang/cs/add.txt
new file mode 100644
index 000000000..39b14d554
--- /dev/null
+++ b/lib/plugins/usermanager/lang/cs/add.txt
@@ -0,0 +1 @@
+===== Přidat uživatele =====
diff --git a/lib/plugins/usermanager/lang/cs/delete.txt b/lib/plugins/usermanager/lang/cs/delete.txt
new file mode 100644
index 000000000..a8790d87d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/cs/delete.txt
@@ -0,0 +1 @@
+===== Smazat uživatele =====
diff --git a/lib/plugins/usermanager/lang/cs/edit.txt b/lib/plugins/usermanager/lang/cs/edit.txt
new file mode 100644
index 000000000..d8ba38605
--- /dev/null
+++ b/lib/plugins/usermanager/lang/cs/edit.txt
@@ -0,0 +1 @@
+===== Upravit uživatele =====
diff --git a/lib/plugins/usermanager/lang/cs/intro.txt b/lib/plugins/usermanager/lang/cs/intro.txt
new file mode 100644
index 000000000..5b8f6e90b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/cs/intro.txt
@@ -0,0 +1 @@
+====== Správa uživatelů ======
diff --git a/lib/plugins/usermanager/lang/cs/lang.php b/lib/plugins/usermanager/lang/cs/lang.php
new file mode 100644
index 000000000..fe54d4cce
--- /dev/null
+++ b/lib/plugins/usermanager/lang/cs/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Czech language file
+ *
+ * @author Tomas Valenta <t.valenta@sh.cvut.cz>
+ * @author Zbynek Krivka <zbynek.krivka@seznam.cz>
+ * @author Bohumir Zamecnik <bohumir@zamecnik.org>
+ * @author tomas@valenta.cz
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @author Lefty <lefty@multihost.cz>
+ * @author Vojta Beran <xmamut@email.cz>
+ * @author zbynek.krivka@seznam.cz
+ */
+$lang['menu'] = 'Správa uživatelů';
+$lang['noauth'] = '(autentizace uživatelů není k dispozici)';
+$lang['nosupport'] = '(správa uživatelů není podporována)';
+$lang['badauth'] = 'chybná metoda autentizace';
+$lang['user_id'] = 'Uživatel';
+$lang['user_pass'] = 'Heslo';
+$lang['user_name'] = 'Celé jméno';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Skupiny';
+$lang['field'] = 'Položka';
+$lang['value'] = 'Hodnota';
+$lang['add'] = 'Přidat';
+$lang['delete'] = 'Smazat';
+$lang['delete_selected'] = 'Smazat vybrané';
+$lang['edit'] = 'Upravit';
+$lang['edit_prompt'] = 'Upravit uživatele';
+$lang['modify'] = 'Uložit změny';
+$lang['search'] = 'Hledání';
+$lang['search_prompt'] = 'Prohledat';
+$lang['clear'] = 'Zrušit vyhledávací filtr';
+$lang['filter'] = 'Filtr';
+$lang['summary'] = 'Zobrazuji uživatele %1$d-%2$d z %3$d nalezených. Celkem %4$d uživatelů.';
+$lang['nonefound'] = 'Žadný uživatel nenalezen. Celkem %d uživatelů.';
+$lang['delete_ok'] = '%d uživatelů smazáno';
+$lang['delete_fail'] = '%d uživatelů nelze smazat.';
+$lang['update_ok'] = 'Uživatel upraven';
+$lang['update_fail'] = 'Úprava uživatele selhala';
+$lang['update_exists'] = 'Jméno nelze změnit, jelikož zadané uživatelské jméno (%s) již existuje (ostatní změny ale budou provedeny).';
+$lang['start'] = 'první';
+$lang['prev'] = 'předchozí';
+$lang['next'] = 'další';
+$lang['last'] = 'poslední';
+$lang['edit_usermissing'] = 'Vybraný uživatel nebyl nalezen, zadané uživatelského mohlo být smazáno nebo změněno.';
+$lang['user_notify'] = 'Upozornit uživatele';
+$lang['note_notify'] = 'Maily s upozorněním se budou posílat pouze, když uživatel dostává nové heslo.';
+$lang['note_group'] = 'Noví uživatelé budou přidáváni do této výchozí skupiny (%s), pokud pro ně není uvedena žádná skupina.';
+$lang['note_pass'] = 'Heslo bude automaticky vygenerováno pokud je pole ponecháno prázdné a je zapnutá notifikace uživatele.';
+$lang['add_ok'] = 'Uživatel úspěšně vytvořen';
+$lang['add_fail'] = 'Vytvoření uživatele selhalo';
+$lang['notify_ok'] = 'Odeslán mail s upozorněním';
+$lang['notify_fail'] = 'Mail s upozorněním nebylo možno odeslat';
diff --git a/lib/plugins/usermanager/lang/cs/list.txt b/lib/plugins/usermanager/lang/cs/list.txt
new file mode 100644
index 000000000..36b87fed9
--- /dev/null
+++ b/lib/plugins/usermanager/lang/cs/list.txt
@@ -0,0 +1 @@
+===== Seznam uživatelů =====
diff --git a/lib/plugins/usermanager/lang/da/add.txt b/lib/plugins/usermanager/lang/da/add.txt
new file mode 100644
index 000000000..d97de4248
--- /dev/null
+++ b/lib/plugins/usermanager/lang/da/add.txt
@@ -0,0 +1 @@
+===== Tilføj bruger =====
diff --git a/lib/plugins/usermanager/lang/da/delete.txt b/lib/plugins/usermanager/lang/da/delete.txt
new file mode 100644
index 000000000..dff05454c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/da/delete.txt
@@ -0,0 +1 @@
+===== Slet bruger =====
diff --git a/lib/plugins/usermanager/lang/da/edit.txt b/lib/plugins/usermanager/lang/da/edit.txt
new file mode 100644
index 000000000..05d63b7b0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/da/edit.txt
@@ -0,0 +1 @@
+===== Rediger bruger =====
diff --git a/lib/plugins/usermanager/lang/da/intro.txt b/lib/plugins/usermanager/lang/da/intro.txt
new file mode 100644
index 000000000..3f597a243
--- /dev/null
+++ b/lib/plugins/usermanager/lang/da/intro.txt
@@ -0,0 +1 @@
+====== Brugerstyring ======
diff --git a/lib/plugins/usermanager/lang/da/lang.php b/lib/plugins/usermanager/lang/da/lang.php
new file mode 100644
index 000000000..ea3109374
--- /dev/null
+++ b/lib/plugins/usermanager/lang/da/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Danish language file
+ *
+ * @author Lars Næsbye Christensen <larsnaesbye@stud.ku.dk>
+ * @author Kalle Sommer Nielsen <kalle@php.net>
+ * @author Esben Laursen <hyber@hyber.dk>
+ * @author Harith <haj@berlingske.dk>
+ * @author Daniel Ejsing-Duun <dokuwiki@zilvador.dk>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author rasmus@kinnerup.com
+ * @author Michael Pedersen subben@gmail.com
+ */
+$lang['menu'] = 'Brugerstyring';
+$lang['noauth'] = '(Brugervalidering er ikke tilgængelig)';
+$lang['nosupport'] = '(Brugerstyring er ikke understøttet)';
+$lang['badauth'] = 'Ugyldig brugerbekræftelsesfunktion';
+$lang['user_id'] = 'Bruger';
+$lang['user_pass'] = 'Adgangskode';
+$lang['user_name'] = 'Navn';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Grupper';
+$lang['field'] = 'Felt';
+$lang['value'] = 'Værdi';
+$lang['add'] = 'Tilføj';
+$lang['delete'] = 'Slet';
+$lang['delete_selected'] = 'Slet valgte';
+$lang['edit'] = 'Rediger';
+$lang['edit_prompt'] = 'Rediger denne bruger';
+$lang['modify'] = 'Gem ændringer';
+$lang['search'] = 'Søg';
+$lang['search_prompt'] = 'Udfør søgning';
+$lang['clear'] = 'Nulstil søgefilter';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Viser brugerne %1$d-%2$d ud af %3$d fundne. %4$d brugere totalt.';
+$lang['nonefound'] = 'Ingen brugere fundet. %d brugere totalt.';
+$lang['delete_ok'] = '%d brugere slettet';
+$lang['delete_fail'] = '%d kunne ikke slettes.';
+$lang['update_ok'] = 'Bruger opdateret korrekt';
+$lang['update_fail'] = 'Brugeropdatering mislykkedes';
+$lang['update_exists'] = 'Ændring af brugernavn mislykkedes, det valgte brugernavn (%s) er allerede optaget (andre ændringer vil blive udført).';
+$lang['start'] = 'begynde';
+$lang['prev'] = 'forrige';
+$lang['next'] = 'næste';
+$lang['last'] = 'sidste';
+$lang['edit_usermissing'] = 'Den valgte bruger blev ikke fundet. Brugernavnet kan være slettet eller ændret andetsteds.';
+$lang['user_notify'] = 'Meddel bruger';
+$lang['note_notify'] = 'Meddelelser bliver kun sendt, hvis brugeren får givet et nyt adgangskode.';
+$lang['note_group'] = 'Nye brugere vil blive tilføjet til standardgruppen (%s), hvis ingen gruppe er opgivet.';
+$lang['note_pass'] = 'Adgangskoden vil blive dannet automatisk, hvis feltet er tomt og underretning af brugeren er aktiveret.';
+$lang['add_ok'] = 'Bruger tilføjet uden fejl.';
+$lang['add_fail'] = 'Tilføjelse af bruger mislykkedes';
+$lang['notify_ok'] = 'Meddelelse sendt';
+$lang['notify_fail'] = 'Meddelelse kunne ikke sendes';
diff --git a/lib/plugins/usermanager/lang/da/list.txt b/lib/plugins/usermanager/lang/da/list.txt
new file mode 100644
index 000000000..11d1710a0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/da/list.txt
@@ -0,0 +1 @@
+===== Brugerliste =====
diff --git a/lib/plugins/usermanager/lang/de-informal/add.txt b/lib/plugins/usermanager/lang/de-informal/add.txt
new file mode 100644
index 000000000..1fc34c968
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de-informal/add.txt
@@ -0,0 +1 @@
+===== Benutzer hinzufügen ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/de-informal/delete.txt b/lib/plugins/usermanager/lang/de-informal/delete.txt
new file mode 100644
index 000000000..778396aa0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de-informal/delete.txt
@@ -0,0 +1 @@
+===== Benutzer gelöscht ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/de-informal/edit.txt b/lib/plugins/usermanager/lang/de-informal/edit.txt
new file mode 100644
index 000000000..291b0f19d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de-informal/edit.txt
@@ -0,0 +1 @@
+===== Benutzer bearbeiten ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/de-informal/intro.txt b/lib/plugins/usermanager/lang/de-informal/intro.txt
new file mode 100644
index 000000000..a5927a89d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de-informal/intro.txt
@@ -0,0 +1 @@
+===== Benutzerverwaltung ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/de-informal/lang.php b/lib/plugins/usermanager/lang/de-informal/lang.php
new file mode 100644
index 000000000..dbdce1fbf
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de-informal/lang.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * German (informal) language file
+ *
+ * @author Alexander Fischer <tbanus@os-forge.net>
+ * @author Juergen Schwarzer <jschwarzer@freenet.de>
+ * @author Marcel Metz <marcel_metz@gmx.de>
+ * @author Matthias Schulte <post@lupo49.de>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Benutzerverwalter';
+$lang['noauth'] = '(Benutzeranmeldung ist nicht verfügbar)';
+$lang['nosupport'] = '(Benutzerverwaltung wird nicht unterstützt)';
+$lang['badauth'] = 'Ungültige Authentifizierung';
+$lang['user_id'] = 'Benutzer';
+$lang['user_pass'] = 'Passwort';
+$lang['user_name'] = 'Echter Name';
+$lang['user_mail'] = 'E-Mail';
+$lang['user_groups'] = 'Gruppen';
+$lang['field'] = 'Feld';
+$lang['value'] = 'Wert';
+$lang['add'] = 'Zufügen';
+$lang['delete'] = 'Löschen';
+$lang['delete_selected'] = 'Lösche ausgewähltes';
+$lang['edit'] = 'Bearbeiten';
+$lang['edit_prompt'] = 'Bearbeite diesen Benutzer';
+$lang['modify'] = 'Änderungen speichern';
+$lang['search'] = 'Suchen';
+$lang['search_prompt'] = 'Suche ausführen';
+$lang['clear'] = 'Suchfilter zurücksetzen';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Zeige Benutzer %1$d-%2$d von %3$d gefundenen. %4$d Benutzer insgesamt.';
+$lang['nonefound'] = 'Keinen Benutzer gefunden. Insgesamt %d Benutzer.';
+$lang['delete_ok'] = '%d Benutzer wurden gelöscht';
+$lang['delete_fail'] = '%d konnte nicht gelöscht werden';
+$lang['update_ok'] = 'Benutzer wurde erfolgreich aktualisiert';
+$lang['update_fail'] = 'Aktualisierung des Benutzers ist fehlgeschlagen';
+$lang['update_exists'] = 'Benutzername konnte nicht geändert werden, der angegebene Benutzername (%s) existiert bereits (alle anderen Änderungen werden angewandt).';
+$lang['start'] = 'Start';
+$lang['prev'] = 'vorige';
+$lang['next'] = 'nächste';
+$lang['last'] = 'letzte';
+$lang['edit_usermissing'] = 'Der gewählte Benutzer wurde nicht gefunden. Der angegebene Benutzername könnte gelöscht oder an anderer Stelle geändert worden sein.';
+$lang['user_notify'] = 'Benutzer benachrichtigen';
+$lang['note_notify'] = 'Benachrichtigungsemails werden nur versandt, wenn der Benutzer ein neues Kennwort erhält.';
+$lang['note_group'] = 'Neue Benutzer werden zur Standardgruppe (%s) hinzugefügt, wenn keine Gruppe angegeben wird.';
+$lang['note_pass'] = 'Das Passwort wird automatisch erzeugt, wenn das Feld freigelassen wird und der Benutzer Benachrichtigungen aktiviert hat.';
+$lang['add_ok'] = 'Benutzer erfolgreich hinzugefügt';
+$lang['add_fail'] = 'Hinzufügen des Benutzers fehlgeschlagen';
+$lang['notify_ok'] = 'Benachrichtigungs-Mail wurde versendet';
+$lang['notify_fail'] = 'Benachrichtigungse-Mail konnte nicht gesendet werden';
diff --git a/lib/plugins/usermanager/lang/de-informal/list.txt b/lib/plugins/usermanager/lang/de-informal/list.txt
new file mode 100644
index 000000000..0a62012e5
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de-informal/list.txt
@@ -0,0 +1 @@
+===== Benutzerliste ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/de/add.txt b/lib/plugins/usermanager/lang/de/add.txt
new file mode 100644
index 000000000..925fa5042
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de/add.txt
@@ -0,0 +1 @@
+===== Benutzer hinzufügen =====
diff --git a/lib/plugins/usermanager/lang/de/delete.txt b/lib/plugins/usermanager/lang/de/delete.txt
new file mode 100644
index 000000000..4f3bbbd03
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de/delete.txt
@@ -0,0 +1 @@
+===== Benutzer löschen =====
diff --git a/lib/plugins/usermanager/lang/de/edit.txt b/lib/plugins/usermanager/lang/de/edit.txt
new file mode 100644
index 000000000..9419200dd
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de/edit.txt
@@ -0,0 +1 @@
+===== Benutzer ändern =====
diff --git a/lib/plugins/usermanager/lang/de/intro.txt b/lib/plugins/usermanager/lang/de/intro.txt
new file mode 100644
index 000000000..a5837b8c7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de/intro.txt
@@ -0,0 +1 @@
+====== Benutzer-Manager ======
diff --git a/lib/plugins/usermanager/lang/de/lang.php b/lib/plugins/usermanager/lang/de/lang.php
new file mode 100644
index 000000000..507fe1f7c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de/lang.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * German language file
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Dirk Einecke <dirk@dirkeinecke.de>
+ * @author Blitzi94@gmx.de
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Niels Lange <niels@boldencursief.nl>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Paul Lachewsky <kaeptn.haddock@gmail.com>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Benutzerverwaltung';
+$lang['noauth'] = '(Authentifizierungssystem nicht verfügbar)';
+$lang['nosupport'] = '(Benutzerverwaltung nicht unterstützt)';
+$lang['badauth'] = 'Ungültige Methode zur Authentifizierung';
+$lang['user_id'] = 'Benutzername';
+$lang['user_pass'] = 'Passwort';
+$lang['user_name'] = 'Voller Name';
+$lang['user_mail'] = 'E-Mail';
+$lang['user_groups'] = 'Gruppen';
+$lang['field'] = 'Feld';
+$lang['value'] = 'Wert';
+$lang['add'] = 'Hinzufügen';
+$lang['delete'] = 'Löschen';
+$lang['delete_selected'] = 'Ausgewählte löschen';
+$lang['edit'] = 'Ändern';
+$lang['edit_prompt'] = 'Benutzerdaten ändern';
+$lang['modify'] = 'Speichern';
+$lang['search'] = 'Suchen';
+$lang['search_prompt'] = 'Benutzerdaten filtern';
+$lang['clear'] = 'Filter zurücksetzen';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Zeige Benutzer %1$d-%2$d von %3$d gefundenen. %4$d Benutzer insgesamt.';
+$lang['nonefound'] = 'Keine Benutzer gefunden. %d Benutzer insgesamt.';
+$lang['delete_ok'] = '%d Benutzer gelöscht';
+$lang['delete_fail'] = '%d konnten nicht gelöscht werden.';
+$lang['update_ok'] = 'Benutzerdaten erfolgreich geändert.';
+$lang['update_fail'] = 'Änderung der Benutzerdaten fehlgeschlagen.';
+$lang['update_exists'] = 'Nutzername konnte nicht geändert werden, weil der angegebene Nutzer (%s) bereits existiert (alle anderen Änderungen wurden durchgeführt).';
+$lang['start'] = 'Anfang';
+$lang['prev'] = 'Vorherige';
+$lang['next'] = 'Nächste';
+$lang['last'] = 'Ende';
+$lang['edit_usermissing'] = 'Der ausgewählte Nutzer wurde nicht gefunden. Möglicherweise wurde er gelöscht oder der Nutzer wurde anderswo geändert.';
+$lang['user_notify'] = 'Nutzer benachrichtigen';
+$lang['note_notify'] = 'Benachrichtigungs-E-Mails werden nur versandt, wenn ein neues Passwort vergeben wurde.';
+$lang['note_group'] = 'Neue Nutzer werden der Standard-Gruppe (%s) hinzugefügt, wenn keine Gruppe angegeben wurde.';
+$lang['note_pass'] = 'Das Passwort wird automatisch generiert, wenn das entsprechende Feld leergelassen wird und die Benachrichtigung des Nutzers aktiviert ist.';
+$lang['add_ok'] = 'Nutzer erfolgreich angelegt';
+$lang['add_fail'] = 'Nutzer konnte nicht angelegt werden';
+$lang['notify_ok'] = 'Benachrichtigungs-Mail wurde versandt';
+$lang['notify_fail'] = 'Benachrichtigungs-Mail konnte nicht versandt werden';
diff --git a/lib/plugins/usermanager/lang/de/list.txt b/lib/plugins/usermanager/lang/de/list.txt
new file mode 100644
index 000000000..8d6d5fb46
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de/list.txt
@@ -0,0 +1 @@
+===== Benutzerliste =====
diff --git a/lib/plugins/usermanager/lang/el/add.txt b/lib/plugins/usermanager/lang/el/add.txt
new file mode 100644
index 000000000..0616f8c53
--- /dev/null
+++ b/lib/plugins/usermanager/lang/el/add.txt
@@ -0,0 +1 @@
+===== Προσθήκη Χρήστη =====
diff --git a/lib/plugins/usermanager/lang/el/delete.txt b/lib/plugins/usermanager/lang/el/delete.txt
new file mode 100644
index 000000000..baf9bc054
--- /dev/null
+++ b/lib/plugins/usermanager/lang/el/delete.txt
@@ -0,0 +1 @@
+===== Διαγραφή Χρήστη =====
diff --git a/lib/plugins/usermanager/lang/el/edit.txt b/lib/plugins/usermanager/lang/el/edit.txt
new file mode 100644
index 000000000..dec59efd7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/el/edit.txt
@@ -0,0 +1 @@
+===== Τροποποίηση Χρήστη =====
diff --git a/lib/plugins/usermanager/lang/el/intro.txt b/lib/plugins/usermanager/lang/el/intro.txt
new file mode 100644
index 000000000..874c13b57
--- /dev/null
+++ b/lib/plugins/usermanager/lang/el/intro.txt
@@ -0,0 +1 @@
+====== Διαχείριση Χρηστών ======
diff --git a/lib/plugins/usermanager/lang/el/lang.php b/lib/plugins/usermanager/lang/el/lang.php
new file mode 100644
index 000000000..4b4d95379
--- /dev/null
+++ b/lib/plugins/usermanager/lang/el/lang.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Greek language file
+ *
+ * Based on DokuWiki Version rc2007-05-24 english language file
+ * Original english language file contents included for reference
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Thanos Massias <tm@thriasio.gr>
+ * @author Αθανάσιος Νταής <homunculus@wana.gr>
+ * @author Konstantinos Koryllos <koryllos@gmail.com>
+ * @author George Petsagourakis <petsagouris@gmail.com>
+ * @author Petros Vidalis <pvidalis@gmail.com>
+ */
+$lang['menu'] = 'Διαχείριση Χρηστών';
+$lang['noauth'] = '(η είσοδος χρηστών δεν είναι δυνατή)';
+$lang['nosupport'] = '(δεν υποστηρίζεται η διαχείριση χρηστών)';
+$lang['badauth'] = 'μη επιτρεπτός μηχανισμός πιστοποίησης';
+$lang['user_id'] = 'Χρήστης';
+$lang['user_pass'] = 'Κωδικός';
+$lang['user_name'] = 'Πλήρες όνομα';
+$lang['user_mail'] = 'e-mail';
+$lang['user_groups'] = 'Ομάδες';
+$lang['field'] = 'Πεδίο';
+$lang['value'] = 'Τιμή';
+$lang['add'] = 'Προσθήκη';
+$lang['delete'] = 'Διαγραφή';
+$lang['delete_selected'] = 'Διαγραφή επιλεγμένων χρηστών';
+$lang['edit'] = 'Τροποποίηση';
+$lang['edit_prompt'] = 'Τροποποίηση χρήστη';
+$lang['modify'] = 'Αποθήκευση αλλαγών';
+$lang['search'] = 'Αναζήτηση';
+$lang['search_prompt'] = 'Εκκίνηση αναζήτησης';
+$lang['clear'] = 'Καθαρισμός φίλτρων';
+$lang['filter'] = 'Φίλτρο';
+$lang['summary'] = 'Εμφάνιση χρηστών %1$d-%2$d από %3$d σχετικούς. %4$d χρήστες συνολικά.';
+$lang['nonefound'] = 'Δεν βρέθηκαν σχετικοί χρήστες. %d χρήστες συνολικά.';
+$lang['delete_ok'] = '%d χρήστες διεγράφησαν';
+$lang['delete_fail'] = '%d χρήστες δεν διεγράφησαν.';
+$lang['update_ok'] = 'Επιτυχημένη τροποποίηση προφίλ χρήστη';
+$lang['update_fail'] = 'Αποτυχημένη τροποποίηση προφίλ χρήστη';
+$lang['update_exists'] = 'Η αλλαγή ονόματος χρήστη απέτυχε -- το νέο όνομα χρήστη (%s) ήδη υπάρχει (τυχόν άλλες αλλαγές θα εφαρμοστούν).';
+$lang['start'] = 'αρχή';
+$lang['prev'] = 'προηγούμενα';
+$lang['next'] = 'επόμενα';
+$lang['last'] = 'τέλος';
+$lang['edit_usermissing'] = 'Ο επιλεγμένος χρήστης δεν βρέθηκε. Πιθανόν να διαγράφηκε στο μεταξύ.';
+$lang['user_notify'] = 'Ειδοποίηση χρήστη';
+$lang['note_notify'] = 'Τα ενημερωτικά e-mails στέλνονται μόνο όταν δίνεται νέος κωδικός στον χρήστη.';
+$lang['note_group'] = 'Οι νέοι χρήστες θα ανήκουν στην ομάδα (%s) αν δεν οριστεί άλλη ομάδα.';
+$lang['note_pass'] = 'Ο κωδικός θα δημιουργηθεί αυτόματα εάν το πεδίο μείνει κενό και έχει επιλεγεί η αποστολή ειδοποίησης χρήστη.';
+$lang['add_ok'] = 'Επιτυχημένη εγγραφή χρήστη';
+$lang['add_fail'] = 'Η εγγραφή του χρήστη απέτυχε';
+$lang['notify_ok'] = 'Εστάλη ενημερωτικό e-mail';
+$lang['notify_fail'] = 'Δεν ήταν δυνατή η αποστολή του ενημερωτικού e-mail';
diff --git a/lib/plugins/usermanager/lang/el/list.txt b/lib/plugins/usermanager/lang/el/list.txt
new file mode 100644
index 000000000..adb5c210b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/el/list.txt
@@ -0,0 +1 @@
+===== Κατάλογος Χρηστών =====
diff --git a/lib/plugins/usermanager/lang/en/add.txt b/lib/plugins/usermanager/lang/en/add.txt
new file mode 100644
index 000000000..9afecb5cd
--- /dev/null
+++ b/lib/plugins/usermanager/lang/en/add.txt
@@ -0,0 +1 @@
+===== Add user =====
diff --git a/lib/plugins/usermanager/lang/en/delete.txt b/lib/plugins/usermanager/lang/en/delete.txt
new file mode 100644
index 000000000..c3ca90dbb
--- /dev/null
+++ b/lib/plugins/usermanager/lang/en/delete.txt
@@ -0,0 +1 @@
+===== Delete user =====
diff --git a/lib/plugins/usermanager/lang/en/edit.txt b/lib/plugins/usermanager/lang/en/edit.txt
new file mode 100644
index 000000000..4d02dfddc
--- /dev/null
+++ b/lib/plugins/usermanager/lang/en/edit.txt
@@ -0,0 +1 @@
+===== Edit user =====
diff --git a/lib/plugins/usermanager/lang/en/intro.txt b/lib/plugins/usermanager/lang/en/intro.txt
new file mode 100644
index 000000000..73bf55613
--- /dev/null
+++ b/lib/plugins/usermanager/lang/en/intro.txt
@@ -0,0 +1 @@
+====== User Manager ======
diff --git a/lib/plugins/usermanager/lang/en/lang.php b/lib/plugins/usermanager/lang/en/lang.php
new file mode 100644
index 000000000..189a1db20
--- /dev/null
+++ b/lib/plugins/usermanager/lang/en/lang.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * English language file
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+
+$lang['menu'] = 'User Manager';
+
+// custom language strings for the plugin
+$lang['noauth'] = '(user authentication not available)';
+$lang['nosupport'] = '(user management not supported)';
+
+$lang['badauth'] = 'invalid auth mechanism'; // should never be displayed!
+
+$lang['user_id'] = 'User';
+$lang['user_pass'] = 'Password';
+$lang['user_name'] = 'Real Name';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Groups';
+
+$lang['field'] = 'Field';
+$lang['value'] = 'Value';
+$lang['add'] = 'Add';
+$lang['delete'] = 'Delete';
+$lang['delete_selected'] = 'Delete Selected';
+$lang['edit'] = 'Edit';
+$lang['edit_prompt'] = 'Edit this user';
+$lang['modify'] = 'Save Changes';
+$lang['search'] = 'Search';
+$lang['search_prompt'] = 'Perform search';
+$lang['clear'] = 'Reset Search Filter';
+$lang['filter'] = 'Filter';
+
+$lang['summary'] = 'Displaying users %1$d-%2$d of %3$d found. %4$d users total.';
+$lang['nonefound'] = 'No users found. %d users total.';
+$lang['delete_ok'] = '%d users deleted';
+$lang['delete_fail'] = '%d failed deleting.';
+$lang['update_ok'] = 'User updated successfully';
+$lang['update_fail'] = 'User update failed';
+$lang['update_exists'] = 'User name change failed, the specified user name (%s) already exists (any other changes will be applied).';
+
+$lang['start'] = 'start';
+$lang['prev'] = 'previous';
+$lang['next'] = 'next';
+$lang['last'] = 'last';
+
+// added after 2006-03-09 release
+$lang['edit_usermissing'] = 'Selected user not found, the specified user name may have been deleted or changed elsewhere.';
+$lang['user_notify'] = 'Notify user';
+$lang['note_notify'] = 'Notification emails are only sent if the user is given a new password.';
+$lang['note_group'] = 'New users will be added to the default group (%s) if no group is specified.';
+$lang['note_pass'] = 'The password will be autogenerated if the field is left empty and notification of the user is enabled.';
+$lang['add_ok'] = 'User added successfully';
+$lang['add_fail'] = 'User addition failed';
+$lang['notify_ok'] = 'Notification email sent';
+$lang['notify_fail'] = 'Notification email could not be sent';
+
diff --git a/lib/plugins/usermanager/lang/en/list.txt b/lib/plugins/usermanager/lang/en/list.txt
new file mode 100644
index 000000000..54c45caf7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/en/list.txt
@@ -0,0 +1 @@
+===== User List =====
diff --git a/lib/plugins/usermanager/lang/eo/add.txt b/lib/plugins/usermanager/lang/eo/add.txt
new file mode 100644
index 000000000..8775ff85d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eo/add.txt
@@ -0,0 +1 @@
+===== Aldoni uzanton ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eo/delete.txt b/lib/plugins/usermanager/lang/eo/delete.txt
new file mode 100644
index 000000000..0d94f8122
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eo/delete.txt
@@ -0,0 +1 @@
+===== Forigi uzanton ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eo/edit.txt b/lib/plugins/usermanager/lang/eo/edit.txt
new file mode 100644
index 000000000..2ced16e7c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eo/edit.txt
@@ -0,0 +1 @@
+===== Modifi uzanton ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eo/intro.txt b/lib/plugins/usermanager/lang/eo/intro.txt
new file mode 100644
index 000000000..2ef373f66
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eo/intro.txt
@@ -0,0 +1 @@
+====== Administrado de Uzantoj ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eo/lang.php b/lib/plugins/usermanager/lang/eo/lang.php
new file mode 100644
index 000000000..b5f1abc0e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eo/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Esperantolanguage file
+ *
+ * @author Felipe Castro <fefcas@uol.com.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Felipe Castro <fefcas (cxe) gmail (punkto) com>
+ * @author Felipo Kastro <fefcas@gmail.com>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Erik Pedersen <erik pedersen@shaw.ca>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert BOGENSCHNEIDER <robog@gmx.de>
+ * @author Robert BOGENSCHNEIDER <bogi@UEA.org>
+ */
+$lang['menu'] = 'Administrado de uzantoj';
+$lang['noauth'] = '(identiĝo de uzantoj ne disponeblas)';
+$lang['nosupport'] = '(administro de uzantoj ne estas subtenata)';
+$lang['badauth'] = 'tiu identiĝa procezo ne validas';
+$lang['user_id'] = 'Uzanto';
+$lang['user_pass'] = 'Pasvorto';
+$lang['user_name'] = 'Vera nomo';
+$lang['user_mail'] = 'Retadreso';
+$lang['user_groups'] = 'Grupoj';
+$lang['field'] = 'Kampo';
+$lang['value'] = 'Valoro';
+$lang['add'] = 'Aldoni';
+$lang['delete'] = 'Forigi';
+$lang['delete_selected'] = 'Forigi elektitan';
+$lang['edit'] = 'Modifi';
+$lang['edit_prompt'] = 'Modifi tiun ĉi uzanton';
+$lang['modify'] = 'Registri modifojn';
+$lang['search'] = 'Serĉi';
+$lang['search_prompt'] = 'Fari serĉon';
+$lang['clear'] = 'Refari serĉan filtron';
+$lang['filter'] = 'Filtro';
+$lang['summary'] = 'Montriĝas uzantoj %1$d-%2$d el %3$d trovitaj. %4$d uzantoj entute.';
+$lang['nonefound'] = 'Neniu uzantoj troviĝas. %d uzantoj entute.';
+$lang['delete_ok'] = '%d uzantoj estis forigitaj';
+$lang['delete_fail'] = '%d malsukcesis esti forigitaj.';
+$lang['update_ok'] = 'Tiu uzanto estis sukcese ĝisdatigita';
+$lang['update_fail'] = 'Malsukceso okazis por ĝisdatigi tiun uzanton';
+$lang['update_exists'] = 'Malsukceso okazis por ŝanĝi la nomon de tiu uzanto: la enmetita nomo (%s) jam ekzistas (ĉiuj aliaj ŝanĝoj estos aplikitaj)';
+$lang['start'] = 'Ekigi';
+$lang['prev'] = 'antaŭe';
+$lang['next'] = 'sekve';
+$lang['last'] = 'laste';
+$lang['edit_usermissing'] = 'La elektita uzanto ne estis trovita: tiu nomo povis esti forigita aŭ ŝanĝita aliloke.';
+$lang['user_notify'] = 'Avizi uzanton';
+$lang['note_notify'] = 'Avizantaj mesaĝoj estos sendataj nur se la uzanto ekhavos novan pasvorton.';
+$lang['note_group'] = 'Novaj uzantoj estos aldonitaj al la komuna grupo (%s) se neniu alia estos specifita.';
+$lang['note_pass'] = 'La pasvorto estos aŭtomate kreita se la kampo estos lasita malplena kaj \'aviso al uzantoj\' estos ebligita.';
+$lang['add_ok'] = 'La uzanto estis sukcese aldonita';
+$lang['add_fail'] = 'Malsukceso okazis por aldoni uzulon';
+$lang['notify_ok'] = 'Avizanta mesaĝo estis sendita';
+$lang['notify_fail'] = 'La avizanta mesaĝo ne povis esti sendita';
diff --git a/lib/plugins/usermanager/lang/eo/list.txt b/lib/plugins/usermanager/lang/eo/list.txt
new file mode 100644
index 000000000..714671afb
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eo/list.txt
@@ -0,0 +1 @@
+===== Listo de Uzantoj ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/es/add.txt b/lib/plugins/usermanager/lang/es/add.txt
new file mode 100644
index 000000000..90c56e31d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/es/add.txt
@@ -0,0 +1 @@
+===== Agregar un usuario =====
diff --git a/lib/plugins/usermanager/lang/es/delete.txt b/lib/plugins/usermanager/lang/es/delete.txt
new file mode 100644
index 000000000..4c552a9c1
--- /dev/null
+++ b/lib/plugins/usermanager/lang/es/delete.txt
@@ -0,0 +1 @@
+===== Eliminar un usuario =====
diff --git a/lib/plugins/usermanager/lang/es/edit.txt b/lib/plugins/usermanager/lang/es/edit.txt
new file mode 100644
index 000000000..ccdd26f86
--- /dev/null
+++ b/lib/plugins/usermanager/lang/es/edit.txt
@@ -0,0 +1 @@
+===== Editar datos del usuario =====
diff --git a/lib/plugins/usermanager/lang/es/intro.txt b/lib/plugins/usermanager/lang/es/intro.txt
new file mode 100644
index 000000000..e558d3a28
--- /dev/null
+++ b/lib/plugins/usermanager/lang/es/intro.txt
@@ -0,0 +1 @@
+====== Administración de usuarios ======
diff --git a/lib/plugins/usermanager/lang/es/lang.php b/lib/plugins/usermanager/lang/es/lang.php
new file mode 100644
index 000000000..c12b77b3d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/es/lang.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Spanish language file
+ *
+ * @author Miguel Pagano <miguel.pagano>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ * @author Gabriel Castillo <gch@pumas.ii.unam.mx>
+ * @author oliver@samera.com.py
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Manuel Meco <manuel.meco@gmail.com>
+ * @author VictorCastelan <victorcastelan@gmail.com>
+ * @author Jordan Mero hack.jord@gmail.com
+ * @author Felipe Martinez <metalmartinez@gmail.com>
+ * @author Javier Aranda <internet@javierav.com>
+ * @author Zerial <fernando@zerial.org>
+ * @author Marvin Ortega <maty1206@maryanlinux.com>
+ * @author Daniel Castro Alvarado <dancas2@gmail.com>
+ * @author Fernando J. Gómez <fjgomez@gmail.com>
+ * @author Victor Castelan <victorcastelan@gmail.com>
+ * @author Mauro Javier Giamberardino <mgiamberardino@gmail.com>
+ * @author emezeta <emezeta@infoprimo.com>
+ * @author Oscar Ciudad <oscar@jacho.net>
+ * @author Ruben Figols <ruben.figols@gmail.com>
+ */
+$lang['menu'] = 'Administración de usuarios';
+$lang['noauth'] = '(la autenticación de usuarios no está disponible)';
+$lang['nosupport'] = '(la administración de usuarios no está habilitada)';
+$lang['badauth'] = 'Mecanismo de autenticación inválido';
+$lang['user_id'] = 'Usuario';
+$lang['user_pass'] = 'Contraseña';
+$lang['user_name'] = 'Nombre';
+$lang['user_mail'] = 'Correo electrónico';
+$lang['user_groups'] = 'Grupos';
+$lang['field'] = 'Campo';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Agregar';
+$lang['delete'] = 'Eliminar';
+$lang['delete_selected'] = 'Eliminar seleccionados';
+$lang['edit'] = 'Editar';
+$lang['edit_prompt'] = 'Editar datos de este usuario';
+$lang['modify'] = 'Guardar los cambios';
+$lang['search'] = 'Buscar';
+$lang['search_prompt'] = 'Realizar la búsqueda';
+$lang['clear'] = 'Limpiar los filtros de la búsqueda';
+$lang['filter'] = 'Filtrar';
+$lang['summary'] = 'Mostrando los usuarios %1$d-%2$d de %3$d encontrados. Cantidad total de usuarios %4$d.';
+$lang['nonefound'] = 'No se encontraron usuarios que coincidan con los párametros de la búsqueda. Cantidad total de usuarios %d.';
+$lang['delete_ok'] = '%d usuarios eliminados';
+$lang['delete_fail'] = '%d no se pudieron eliminar.';
+$lang['update_ok'] = 'Los datos del usuario se actualizaron exitosamente ';
+$lang['update_fail'] = 'Los datos del usuario no se actualizaron';
+$lang['update_exists'] = 'El cambio de nombre de usuario falló, el nombre especificado (%s) ya está en uso (los otros cambios se aplicaron).';
+$lang['start'] = 'primera';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'siguiente';
+$lang['last'] = 'última';
+$lang['edit_usermissing'] = 'El usuario seleccionado no ha sido encontrado; el usuario especificado puede haber sido eliminado o cambiado en algún otro lugar.';
+$lang['user_notify'] = 'Notificar al usuario';
+$lang['note_notify'] = 'El correo electrónico de notificación sólo será enviado si se actualizo la contraseña del usuario.';
+$lang['note_group'] = 'Si no se especifica ningún grupo, los nuevos usuarios serán agregados al grupo por defecto (%s).';
+$lang['note_pass'] = 'Se generará una clave automáticamente si el campo izquierdo es vacío y se esta activo la notificación de usuario. ';
+$lang['add_ok'] = 'El usuario fue creado exitosamente';
+$lang['add_fail'] = 'Falló la creación del usuario';
+$lang['notify_ok'] = 'Se envió la notificación por correo electrónico';
+$lang['notify_fail'] = 'No se pudo enviar la notificación por correo electrónico';
diff --git a/lib/plugins/usermanager/lang/es/list.txt b/lib/plugins/usermanager/lang/es/list.txt
new file mode 100644
index 000000000..d0d32b913
--- /dev/null
+++ b/lib/plugins/usermanager/lang/es/list.txt
@@ -0,0 +1 @@
+===== Lista de usuarios =====
diff --git a/lib/plugins/usermanager/lang/et/lang.php b/lib/plugins/usermanager/lang/et/lang.php
new file mode 100644
index 000000000..2161df918
--- /dev/null
+++ b/lib/plugins/usermanager/lang/et/lang.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Estonian language file
+ *
+ * @author kristian.kankainen@kuu.la
+ * @author Rivo Zängov <eraser@eraser.ee>
+ */
+$lang['menu'] = 'Kasutajate haldamine';
+$lang['user_id'] = 'Kasutaja';
+$lang['user_pass'] = 'Parool';
+$lang['user_name'] = 'Tegelik nimi';
+$lang['user_mail'] = 'E-post';
+$lang['user_groups'] = 'Grupid';
+$lang['field'] = 'Väli';
+$lang['value'] = 'Väärtus';
+$lang['add'] = 'Lisa';
+$lang['delete'] = 'Kustuta';
+$lang['delete_selected'] = 'Kustuta valitud';
+$lang['edit'] = 'Muuda';
+$lang['edit_prompt'] = 'Muuda seda kasutajat';
+$lang['modify'] = 'Salvesta muudatused';
+$lang['search'] = 'Otsi';
+$lang['search_prompt'] = 'Soorita otsing';
+$lang['filter'] = 'Filtreeri';
+$lang['update_fail'] = 'Kasutaja uuendamine ebaõnnestus';
+$lang['start'] = 'esimesed';
+$lang['prev'] = 'eelmine';
+$lang['next'] = 'järgmine';
+$lang['last'] = 'viimased';
+$lang['user_notify'] = 'Teavita kasutajat';
diff --git a/lib/plugins/usermanager/lang/eu/add.txt b/lib/plugins/usermanager/lang/eu/add.txt
new file mode 100644
index 000000000..855c43218
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eu/add.txt
@@ -0,0 +1 @@
+===== Erabiltzailea gehitu ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eu/delete.txt b/lib/plugins/usermanager/lang/eu/delete.txt
new file mode 100644
index 000000000..987b98f20
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eu/delete.txt
@@ -0,0 +1 @@
+===== Erabiltzailea ezabatu ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eu/edit.txt b/lib/plugins/usermanager/lang/eu/edit.txt
new file mode 100644
index 000000000..82b92afe7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eu/edit.txt
@@ -0,0 +1 @@
+====== Editatu erabiltzailea ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eu/intro.txt b/lib/plugins/usermanager/lang/eu/intro.txt
new file mode 100644
index 000000000..848b3da05
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eu/intro.txt
@@ -0,0 +1 @@
+====== Erabiltzaile Kudeatzailea ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eu/lang.php b/lib/plugins/usermanager/lang/eu/lang.php
new file mode 100644
index 000000000..b6e04f7c4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eu/lang.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Basque language file
+ *
+ * @author Inko Illarramendi <inko.i.a@gmail.com>
+ */
+$lang['menu'] = 'Erabiltzaile Kudeatzailea';
+$lang['noauth'] = '(erabiltzaile kautotzea ez dago erabilgarri)';
+$lang['nosupport'] = '(erabiltzaile kudeaketa ez dago erabilgarri)';
+$lang['badauth'] = 'kautotze mekanismo baliogabea';
+$lang['user_id'] = 'Erabiltzailea';
+$lang['user_pass'] = 'Pasahitza';
+$lang['user_name'] = 'Benetako Izena';
+$lang['user_mail'] = 'Posta-e';
+$lang['user_groups'] = 'Taldeak';
+$lang['field'] = 'Eremu';
+$lang['value'] = 'Balioa';
+$lang['add'] = 'Gehitu';
+$lang['delete'] = 'Ezabatu';
+$lang['delete_selected'] = 'Ezabatu Hautatutakoak';
+$lang['edit'] = 'Editatu';
+$lang['edit_prompt'] = 'Editatu erabiltzaile hau';
+$lang['modify'] = 'Gorde Aldaketak';
+$lang['search'] = 'Bilatu';
+$lang['search_prompt'] = 'Egin bilaketa';
+$lang['clear'] = 'Berrasieratu Bilaketa Iragazkia';
+$lang['filter'] = 'Iragazi';
+$lang['summary'] = 'Erakusten diren erabiltzaileak %1$d-%2$d bilatutako %3$d erabiltzailetatik. %4$d erabiltzaile guztira.';
+$lang['nonefound'] = 'Ez da erabiltzailerik aurkitu. %d erabiltzaile guztira.';
+$lang['delete_ok'] = '%d erabiltzaile ezabatuak';
+$lang['delete_fail'] = '%d huts ezabatzean.';
+$lang['update_ok'] = 'Erabiltzailea arrakastaz eguneratuak';
+$lang['update_fail'] = 'Erabiltzaile eguneratzeak huts egin du ';
+$lang['update_exists'] = 'Erabiltzaile izen aldaketak huts egin du, zehaztutako erabiltzaile izena (%s) lehendik existitzen zen (beste edozein aldaketa ezarri egingo da).';
+$lang['start'] = 'hasi';
+$lang['prev'] = 'aurrekoa';
+$lang['next'] = 'hurrengoa';
+$lang['last'] = 'azkena';
+$lang['edit_usermissing'] = 'Aukeratutako erabiltzailea ez da aurkitu, zehaztutako erabiltzaile izena beste nonbait ezabatua edo aldatua izana gerta zitekeen.';
+$lang['user_notify'] = 'Erabiltzailea jakinarazi';
+$lang['note_notify'] = 'Jakinarazpen postak erabiltzaileari pasahitz berria ematen bazaio bakarrik bidaltzen dira.';
+$lang['note_group'] = 'Erabiltzaile berriak (%s) talde lehenetsira gehituko dira ez bada talderik zehazten.';
+$lang['note_pass'] = 'Pasahitza automatikoki sortuko da eremua hutsik uzten bada eta erabiltzailearen jakinarazpena gaitua badago.';
+$lang['add_ok'] = 'Erabiltzailea arrakastaz gehitua';
+$lang['add_fail'] = 'Erabiltzaile gehitzeak huts egin du';
+$lang['notify_ok'] = 'Jakinarazpen posta-e bidalia';
+$lang['notify_fail'] = 'Jakinarazpen posta-e ezin izan da bidali';
diff --git a/lib/plugins/usermanager/lang/eu/list.txt b/lib/plugins/usermanager/lang/eu/list.txt
new file mode 100644
index 000000000..fb80b14be
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eu/list.txt
@@ -0,0 +1 @@
+====== Erabiltzaile zerrenda ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fa/add.txt b/lib/plugins/usermanager/lang/fa/add.txt
new file mode 100644
index 000000000..32d604e43
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fa/add.txt
@@ -0,0 +1 @@
+===== افزودن کاربر ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fa/delete.txt b/lib/plugins/usermanager/lang/fa/delete.txt
new file mode 100644
index 000000000..f8a59ff10
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fa/delete.txt
@@ -0,0 +1 @@
+===== حذف کاربر ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fa/edit.txt b/lib/plugins/usermanager/lang/fa/edit.txt
new file mode 100644
index 000000000..33fe5b517
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fa/edit.txt
@@ -0,0 +1 @@
+===== ویرایش کاربر ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fa/intro.txt b/lib/plugins/usermanager/lang/fa/intro.txt
new file mode 100644
index 000000000..ffb850109
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fa/intro.txt
@@ -0,0 +1 @@
+===== مدیریت کاربران ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fa/lang.php b/lib/plugins/usermanager/lang/fa/lang.php
new file mode 100644
index 000000000..f9e973b9c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fa/lang.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Persian language file
+ *
+ * @author behrad eslamifar <behrad_es@yahoo.com)
+ * @author Mohsen Firoozmandan <info@mambolearn.com>
+ * @author omidmr@gmail.com
+ * @author Omid Mottaghi <omidmr@gmail.com>
+ * @author Mohammad Reza Shoaei <shoaei@gmail.com>
+ */
+$lang['menu'] = 'مدیریت کاربر';
+$lang['noauth'] = '(معتبرسازی کاربر ممکن نیست)';
+$lang['nosupport'] = '(مدیریت کاربر پشتیبانی نمی‌شود)';
+$lang['badauth'] = 'روش معتبرسازی اشتباه است';
+$lang['user_id'] = 'کاربر';
+$lang['user_pass'] = 'گذرواژه';
+$lang['user_name'] = 'نام حقیقی';
+$lang['user_mail'] = 'ایمیل';
+$lang['user_groups'] = 'گروه‌ها';
+$lang['field'] = 'فیلد';
+$lang['value'] = 'ارزش';
+$lang['add'] = 'اضافه کردن';
+$lang['delete'] = 'حذف';
+$lang['delete_selected'] = 'حذف انتخاب شده‌ها';
+$lang['edit'] = 'ویرایش';
+$lang['edit_prompt'] = 'ویرایش این کاربر';
+$lang['modify'] = 'ذخیره تغییرات';
+$lang['search'] = 'جستجو';
+$lang['search_prompt'] = 'انجام جستجو';
+$lang['clear'] = 'بازنویسی فیلترهای جستجو';
+$lang['filter'] = 'فیلتر';
+$lang['summary'] = 'نمایش کاربر %1$d-%2$d از %3$d. در کل %4$d کاربر.';
+$lang['nonefound'] = 'هیچ کاربری یافت نشد. در کل %d کاربر.';
+$lang['delete_ok'] = '%d کاربر حذف شد';
+$lang['delete_fail'] = 'حذف %d کاربر با مشکل مواجه شد.';
+$lang['update_ok'] = 'کاربر با موفقیت به روز رسانی شد.';
+$lang['update_fail'] = 'به روز رسانی کاربر با مشکل مواجه شد';
+$lang['update_exists'] = 'تغییر نام کاربری ممکن نیست، نام کاربری مورد نظر (%s) قبلن وجود داشته (مابقی تغییرات اعمال شده است)';
+$lang['start'] = 'شروع';
+$lang['prev'] = 'قبلی';
+$lang['next'] = 'بعدی';
+$lang['last'] = 'آخرین';
+$lang['edit_usermissing'] = 'کاربر انتخاب شده یافت نشد، نام کاربری مورد نظر در جایی دیگر حذف شده یا تغییر کرده.';
+$lang['user_notify'] = 'آگاه کردن کاربر';
+$lang['note_notify'] = 'ایمیلی برای آگاهی، فقط در زمان تغییر گذرواژه‌ ارسال می‌شود.';
+$lang['note_group'] = 'اگر گروهی انتخاب نشود، کاربران جدید به گروه پیش‌فرض (%s) افزوده خواهند شد.';
+$lang['note_pass'] = 'اگر فیلد گذرواژه خالی گذاشته شود، گذرواژه به طور خودکار تولید و ایمیلی برای کاربر ارسال خواهد شد.';
+$lang['add_ok'] = 'کاربر با موفقیت افزوده شد';
+$lang['add_fail'] = 'افزودن کاربر با مشکل مواجه شد';
+$lang['notify_ok'] = 'ایمیل آگاهی دهنده ارسال شد';
+$lang['notify_fail'] = 'ارسال ایمیل آگاهی دهنده با مشکل مواجه شد';
diff --git a/lib/plugins/usermanager/lang/fa/list.txt b/lib/plugins/usermanager/lang/fa/list.txt
new file mode 100644
index 000000000..b539bf18a
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fa/list.txt
@@ -0,0 +1 @@
+===== لیست کاربران ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fi/add.txt b/lib/plugins/usermanager/lang/fi/add.txt
new file mode 100644
index 000000000..5c4ee0a41
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fi/add.txt
@@ -0,0 +1 @@
+===== Lisää käyttäjä ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fi/delete.txt b/lib/plugins/usermanager/lang/fi/delete.txt
new file mode 100644
index 000000000..2203a20f8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fi/delete.txt
@@ -0,0 +1 @@
+===== Poista käyttäjä ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fi/edit.txt b/lib/plugins/usermanager/lang/fi/edit.txt
new file mode 100644
index 000000000..53e0b41ab
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fi/edit.txt
@@ -0,0 +1 @@
+===== Muokkaa käyttäjää ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fi/intro.txt b/lib/plugins/usermanager/lang/fi/intro.txt
new file mode 100644
index 000000000..2ef0bb509
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fi/intro.txt
@@ -0,0 +1 @@
+====== Käyttäjähallinta ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fi/lang.php b/lib/plugins/usermanager/lang/fi/lang.php
new file mode 100644
index 000000000..1db4bd7fb
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fi/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Finnish language file
+ *
+ * @author otto@valjakko.net
+ * @author Otto Vainio <otto@valjakko.net>
+ * @author Teemu Mattila <ghcsystems@gmail.com>
+ * @author Sami Olmari <sami@olmari.fi>
+ */
+$lang['menu'] = 'Käyttäjähallinta';
+$lang['noauth'] = '(autentikointi ei ole käytössä)';
+$lang['nosupport'] = '(käyttäjähallinta ei ole tuettu)';
+$lang['badauth'] = 'Viallinen autentikointimenetelmä';
+$lang['user_id'] = 'Käyttäjä';
+$lang['user_pass'] = 'Salasana';
+$lang['user_name'] = 'Oikea nimi';
+$lang['user_mail'] = 'Sähköposti';
+$lang['user_groups'] = 'Ryhmät';
+$lang['field'] = 'Kenttä';
+$lang['value'] = 'Arvo';
+$lang['add'] = 'Lisää';
+$lang['delete'] = 'Poista';
+$lang['delete_selected'] = 'Poista valittu';
+$lang['edit'] = 'Muokkaa';
+$lang['edit_prompt'] = 'Muokkaa ryhmää';
+$lang['modify'] = 'Tallenna muutokset';
+$lang['search'] = 'Hae';
+$lang['search_prompt'] = 'Tee haku';
+$lang['clear'] = 'Tyhjennä hakusuodatin';
+$lang['filter'] = 'Suodatin';
+$lang['summary'] = 'Näytetään käyttäjät %1$d-%2$d / %3$d löytynyttä. %4$d käyttäjää yhteensä.';
+$lang['nonefound'] = 'Ei löytynyt käyttäjiä. %d käyttäjää yhteensä.';
+$lang['delete_ok'] = '%d käyttäjää poistettu';
+$lang['delete_fail'] = '%d poistoa epäonnistui';
+$lang['update_ok'] = 'Käyttäjän päivitys onnistui';
+$lang['update_fail'] = 'Käyttäjän päivitys epäonnistui';
+$lang['update_exists'] = 'Käyttäjän nimen vaihto epäonnistui. Nimi (%s) on jo olemassa (muut muutokset onnistuivat)';
+$lang['start'] = 'alku';
+$lang['prev'] = 'edellinen';
+$lang['next'] = 'seuraava';
+$lang['last'] = 'viimeinen';
+$lang['edit_usermissing'] = 'Valittua käyttäjää ei löytynyt. Käyttäjä on voitu päivittää tai poistaa muualta.';
+$lang['user_notify'] = 'Tiedota käyttäjälle';
+$lang['note_notify'] = 'Tiedotus lähetetään vain, jos käyttäjälle on määritelty uusi salasana.';
+$lang['note_group'] = 'Uudelle käyttäjälle määritellään oletusryhmä (%s), jos ryhmää ei erikseen määritellä.';
+$lang['note_pass'] = 'Salasana luodaan automaattisesti, mikäli kenttä jätetään tyhjäksi ja jos käyttäjän tiedotus on päällä.';
+$lang['add_ok'] = 'Käyttäjä lisätty onnistuneesti';
+$lang['add_fail'] = 'Käyttäjän lisäys epäonnistui';
+$lang['notify_ok'] = 'Ilmoitus sähköpostilla lähetetty';
+$lang['notify_fail'] = 'Ilmoitusta sähköpostilla ei voitu lähettää';
diff --git a/lib/plugins/usermanager/lang/fi/list.txt b/lib/plugins/usermanager/lang/fi/list.txt
new file mode 100644
index 000000000..5ecf2ff7b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fi/list.txt
@@ -0,0 +1 @@
+===== Käyttäjälista ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fr/add.txt b/lib/plugins/usermanager/lang/fr/add.txt
new file mode 100644
index 000000000..e60b8b894
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fr/add.txt
@@ -0,0 +1 @@
+===== Ajouter un utilisateur =====
diff --git a/lib/plugins/usermanager/lang/fr/delete.txt b/lib/plugins/usermanager/lang/fr/delete.txt
new file mode 100644
index 000000000..778f44192
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fr/delete.txt
@@ -0,0 +1 @@
+===== Supprimer un utilisateur =====
diff --git a/lib/plugins/usermanager/lang/fr/edit.txt b/lib/plugins/usermanager/lang/fr/edit.txt
new file mode 100644
index 000000000..ec193eb5a
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fr/edit.txt
@@ -0,0 +1 @@
+===== Modifier les informations d'un utilisateur =====
diff --git a/lib/plugins/usermanager/lang/fr/intro.txt b/lib/plugins/usermanager/lang/fr/intro.txt
new file mode 100644
index 000000000..84987b0bf
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fr/intro.txt
@@ -0,0 +1 @@
+====== Gestion des utilisateurs ======
diff --git a/lib/plugins/usermanager/lang/fr/lang.php b/lib/plugins/usermanager/lang/fr/lang.php
new file mode 100644
index 000000000..948262a8f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fr/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * french language file
+ *
+ * @author Guy Brand <gb@unistra.fr>
+ * @author Delassaux Julien <julien@delassaux.fr>
+ * @author Maurice A. LeBlanc <leblancma@cooptel.qc.ca>
+ * @author stephane.gully@gmail.com
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author olivier duperray <duperray.olivier@laposte.net>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author Philippe Bajoit <philippe.bajoit@gmail.com>
+ * @author Florian Gaub <floriang@floriang.net>
+ * @author Samuel Dorsaz samuel.dorsaz@novelion.net
+ * @author Johan Guilbaud <guilbaud.johan@gmail.com>
+ * @author schplurtz@laposte.net
+ * @author skimpax@gmail.com
+ */
+$lang['menu'] = 'Gestion des utilisateurs';
+$lang['noauth'] = '(authentification utilisateur non disponible)';
+$lang['nosupport'] = '(gestion utilisateur non supportée)';
+$lang['badauth'] = 'mécanisme d\'authentification invalide';
+$lang['user_id'] = 'Identifiant ';
+$lang['user_pass'] = 'Mot de passe ';
+$lang['user_name'] = 'Nom ';
+$lang['user_mail'] = 'Courriel ';
+$lang['user_groups'] = 'Groupes ';
+$lang['field'] = 'Champ';
+$lang['value'] = 'Valeur';
+$lang['add'] = 'Ajouter';
+$lang['delete'] = 'Supprimer';
+$lang['delete_selected'] = 'Supprimer la sélection';
+$lang['edit'] = 'Modifier';
+$lang['edit_prompt'] = 'Modifier cet utilisateur';
+$lang['modify'] = 'Enregistrer les modifications';
+$lang['search'] = 'Rechercher';
+$lang['search_prompt'] = 'Effectuer la recherche';
+$lang['clear'] = 'Réinitialiser la recherche';
+$lang['filter'] = 'Filtre';
+$lang['summary'] = 'Affichage des utilisateurs %1$d-%2$d parmi %3$d trouvé(s). %4$d utilisateur(s) au total.';
+$lang['nonefound'] = 'Aucun utilisateur trouvé. %d utilisateur(s) au total.';
+$lang['delete_ok'] = '%d utilisateurs effacés';
+$lang['delete_fail'] = '%d effacement échoué.';
+$lang['update_ok'] = 'Utilisateur mis à jour avec succès';
+$lang['update_fail'] = 'Échec de la mise à jour utilisateur';
+$lang['update_exists'] = 'Échec du changement de nom d\'utilisateur, le nom spécifié (%s) existe déjà (toutes les autres modifications seront effectuées).';
+$lang['start'] = 'Démarrage';
+$lang['prev'] = 'Précédent';
+$lang['next'] = 'Suivant';
+$lang['last'] = 'Dernier';
+$lang['edit_usermissing'] = 'Utilisateur sélectionné non trouvé, cet utilisateur a peut-être été supprimé ou modifié ailleurs.';
+$lang['user_notify'] = 'Notifier l\'utilisateur ';
+$lang['note_notify'] = 'Envoi de notification par courriel uniquement lorsqu\'un nouveau mot de passe est attribué à l\'utilisateur.';
+$lang['note_group'] = 'Les nouveaux utilisateurs seront ajoutés au groupe par défaut (%s) si aucun groupe n\'est spécifié.';
+$lang['note_pass'] = 'Le mot de passe sera généré automatiquement si le champ est laissé vide et si la notification de l\'utilisateur est activée.';
+$lang['add_ok'] = 'Utilisateur ajouté avec succès';
+$lang['add_fail'] = 'Échec de l\'ajout de l\'utilisateur';
+$lang['notify_ok'] = 'Courriel de notification expédié';
+$lang['notify_fail'] = 'Échec de l\'expédition du courriel de notification';
diff --git a/lib/plugins/usermanager/lang/fr/list.txt b/lib/plugins/usermanager/lang/fr/list.txt
new file mode 100644
index 000000000..2d708fe43
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fr/list.txt
@@ -0,0 +1 @@
+===== Liste des utilisateurs =====
diff --git a/lib/plugins/usermanager/lang/gl/add.txt b/lib/plugins/usermanager/lang/gl/add.txt
new file mode 100644
index 000000000..7602c36ec
--- /dev/null
+++ b/lib/plugins/usermanager/lang/gl/add.txt
@@ -0,0 +1 @@
+===== Engadir usuario ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/gl/delete.txt b/lib/plugins/usermanager/lang/gl/delete.txt
new file mode 100644
index 000000000..4262a0c05
--- /dev/null
+++ b/lib/plugins/usermanager/lang/gl/delete.txt
@@ -0,0 +1 @@
+===== Eliminar usuario ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/gl/edit.txt b/lib/plugins/usermanager/lang/gl/edit.txt
new file mode 100644
index 000000000..11ef62cce
--- /dev/null
+++ b/lib/plugins/usermanager/lang/gl/edit.txt
@@ -0,0 +1 @@
+===== Editar usuario ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/gl/intro.txt b/lib/plugins/usermanager/lang/gl/intro.txt
new file mode 100644
index 000000000..77675e9d6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/gl/intro.txt
@@ -0,0 +1 @@
+====== Xestor de Usuarios ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/gl/lang.php b/lib/plugins/usermanager/lang/gl/lang.php
new file mode 100644
index 000000000..c9c633b39
--- /dev/null
+++ b/lib/plugins/usermanager/lang/gl/lang.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Galicianlanguage file
+ *
+ * @author Medúlio <medulio@ciberirmandade.org>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ */
+$lang['menu'] = 'Xestor de Usuarios';
+$lang['noauth'] = '(autenticación de usuarios non dispoñible)';
+$lang['nosupport'] = '(xestión de usuarios non soportada)';
+$lang['badauth'] = 'mecanismo de autenticación non válido';
+$lang['user_id'] = 'Usuario';
+$lang['user_pass'] = 'Contrasinal';
+$lang['user_name'] = 'Nome Real';
+$lang['user_mail'] = 'Correo-e';
+$lang['user_groups'] = 'Grupos';
+$lang['field'] = 'Campo';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Engadir';
+$lang['delete'] = 'Eliminar';
+$lang['delete_selected'] = 'Eliminar Seleccionados';
+$lang['edit'] = 'Editar';
+$lang['edit_prompt'] = 'Editar este usuario';
+$lang['modify'] = 'Gardar Trocos';
+$lang['search'] = 'Procurar';
+$lang['search_prompt'] = 'Facer procura';
+$lang['clear'] = 'Reiniciar Filtro de Procura';
+$lang['filter'] = 'Filtro';
+$lang['summary'] = 'Amosando usuarios %1$d-%2$d de %3$d atopados. %4$d usuarios en total.';
+$lang['nonefound'] = 'Non se atoparon usuarios. %d usuarios en total.';
+$lang['delete_ok'] = '%d usuarios eliminados';
+$lang['delete_fail'] = '%d non puideron ser eliminados.';
+$lang['update_ok'] = 'Usuario actualizado correctamente';
+$lang['update_fail'] = 'Non se puido actualizar o usuario';
+$lang['update_exists'] = 'Non se puido mudar o nome do usuario, xa que o nome especificado (%s) xa existe (o resto de trocos aplicaranse sen problemas).';
+$lang['start'] = 'comezo';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'seguinte';
+$lang['last'] = 'derradeiro';
+$lang['edit_usermissing'] = 'Non se atopou o usuario seleccionado, pode que o nome de usuario fose eliminado ou mudado nalgún intre.';
+$lang['user_notify'] = 'Notificar ao usuario';
+$lang['note_notify'] = 'Os correos-e de notificación envíanse só se o usuario obtén un novo contrasinal.';
+$lang['note_group'] = 'Os novos usuarios serán engadidos ao grupo por defecto (%s) se non se especifica outro.';
+$lang['note_pass'] = 'Se deixas o campo baleiro e a notificación ao usuario está activada xerarase automaticamente o contrasinal.';
+$lang['add_ok'] = 'Usuario engadido correctamente';
+$lang['add_fail'] = 'Non se puido engadir o usuario';
+$lang['notify_ok'] = 'Correo-e de notificación enviado';
+$lang['notify_fail'] = 'Non se puido enviar o correo-e de notificación';
diff --git a/lib/plugins/usermanager/lang/gl/list.txt b/lib/plugins/usermanager/lang/gl/list.txt
new file mode 100644
index 000000000..013b2d7d8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/gl/list.txt
@@ -0,0 +1 @@
+===== Lista de Usuarios ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/he/add.txt b/lib/plugins/usermanager/lang/he/add.txt
new file mode 100644
index 000000000..e2d1cb775
--- /dev/null
+++ b/lib/plugins/usermanager/lang/he/add.txt
@@ -0,0 +1 @@
+===== הוספת משתמש =====
diff --git a/lib/plugins/usermanager/lang/he/delete.txt b/lib/plugins/usermanager/lang/he/delete.txt
new file mode 100644
index 000000000..42d738b1d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/he/delete.txt
@@ -0,0 +1 @@
+===== מחיקת משתמש =====
diff --git a/lib/plugins/usermanager/lang/he/edit.txt b/lib/plugins/usermanager/lang/he/edit.txt
new file mode 100644
index 000000000..af90af359
--- /dev/null
+++ b/lib/plugins/usermanager/lang/he/edit.txt
@@ -0,0 +1 @@
+===== עריכת משתמש =====
diff --git a/lib/plugins/usermanager/lang/he/intro.txt b/lib/plugins/usermanager/lang/he/intro.txt
new file mode 100644
index 000000000..232c5153b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/he/intro.txt
@@ -0,0 +1 @@
+====== מנהל משתמשים ======
diff --git a/lib/plugins/usermanager/lang/he/lang.php b/lib/plugins/usermanager/lang/he/lang.php
new file mode 100644
index 000000000..601163013
--- /dev/null
+++ b/lib/plugins/usermanager/lang/he/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * hebrew language file
+ *
+ * @author DoK <kamberd@yahoo.com>
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ * @author Moshe Kaplan <mokplan@gmail.com>
+ * @author Yaron Yogev <yaronyogev@gmail.com>
+ * @author Yaron Shahrabani <sh.yaron@gmail.com>
+ */
+$lang['menu'] = 'מנהל משתמשים';
+$lang['noauth'] = '(אימות משתמשים אינו זמין)';
+$lang['nosupport'] = '(ניהול משתמשים אינו נתמך)';
+$lang['badauth'] = 'מנגנון אימות לא תקף';
+$lang['user_id'] = 'שם משתמש';
+$lang['user_pass'] = 'סיסמה';
+$lang['user_name'] = 'שם אמיתי';
+$lang['user_mail'] = 'דוא"ל';
+$lang['user_groups'] = 'קבוצות';
+$lang['field'] = 'שדה';
+$lang['value'] = 'ערך';
+$lang['add'] = 'הוספה';
+$lang['delete'] = 'מחיקה';
+$lang['delete_selected'] = 'מחיקת הבחירה';
+$lang['edit'] = 'עריכה';
+$lang['edit_prompt'] = 'עריכת משתמש זה';
+$lang['modify'] = 'שמירת שינוים';
+$lang['search'] = 'חיפוש';
+$lang['search_prompt'] = 'בצע חיפוש';
+$lang['clear'] = 'אתחל סינון חיפוש';
+$lang['filter'] = 'סינון';
+$lang['summary'] = 'מציג משתמשים %1$d-%2$d מתוך %3$d שנמצאו. %4$d בסך הכל.';
+$lang['nonefound'] = 'לא נמצאו משתמשים. סך כל המשתמשים %d.';
+$lang['delete_ok'] = '%d משתמשים נמחקו';
+$lang['delete_fail'] = '%d כשל במחיקה.';
+$lang['update_ok'] = 'משתמש עודכן בהצלחה';
+$lang['update_fail'] = 'עידכון המשתמש כשל';
+$lang['update_exists'] = 'שינוי שם המשתמש כשל, שם השמתמש שצויין (%s) כבר נמצא (כל השינויים האחרים יוחלו).';
+$lang['start'] = 'התחלה';
+$lang['prev'] = 'קודם';
+$lang['next'] = 'הבא';
+$lang['last'] = 'סוף';
+$lang['edit_usermissing'] = 'המשתמש שנבחר לא נמצא, ייתכן כי שם המשתמש שצויין נמחק או השתנה במקום אחר.';
+$lang['user_notify'] = 'הודע למשתמש';
+$lang['note_notify'] = 'הודעות בדוא"ל נשלחות רק במקרה שהמשתמש מקבל סיסמה חדשה.';
+$lang['note_group'] = 'משתמשים חדשים יוספו לקבוצת ברירת המחדל (%s) אם לא צוינה קבוצה אחרת.';
+$lang['add_ok'] = 'משתמש הוסף בהצלחה';
+$lang['add_fail'] = 'הוספת המשתמש כשלה';
+$lang['notify_ok'] = 'הודעה נשלחה';
+$lang['notify_fail'] = 'לא ניתן היה לשלוח הודעה';
diff --git a/lib/plugins/usermanager/lang/he/list.txt b/lib/plugins/usermanager/lang/he/list.txt
new file mode 100644
index 000000000..9308fbebb
--- /dev/null
+++ b/lib/plugins/usermanager/lang/he/list.txt
@@ -0,0 +1 @@
+===== רשימת משתמשים =====
diff --git a/lib/plugins/usermanager/lang/hi/lang.php b/lib/plugins/usermanager/lang/hi/lang.php
new file mode 100644
index 000000000..d6f78ffd6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hi/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Hindi language file
+ *
+ * @author Abhinav Tyagi <abhinavtyagi11@gmail.com>
+ * @author yndesai@gmail.com
+ */
diff --git a/lib/plugins/usermanager/lang/hr/lang.php b/lib/plugins/usermanager/lang/hr/lang.php
new file mode 100644
index 000000000..96f1d6afe
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hr/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Croatian language file
+ *
+ * @author Branko Rihtman <theney@gmail.com>
+ * @author Dražen Odobašić <dodobasic@gmail.com>
+ * @author Dejan Igrec dejan.igrec@gmail.com
+ */
diff --git a/lib/plugins/usermanager/lang/hu/add.txt b/lib/plugins/usermanager/lang/hu/add.txt
new file mode 100644
index 000000000..70a44c41d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hu/add.txt
@@ -0,0 +1,2 @@
+===== Felhasználó hozzáadása =====
+
diff --git a/lib/plugins/usermanager/lang/hu/delete.txt b/lib/plugins/usermanager/lang/hu/delete.txt
new file mode 100644
index 000000000..963d2e7b3
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hu/delete.txt
@@ -0,0 +1,2 @@
+===== Felhasználó törlése =====
+
diff --git a/lib/plugins/usermanager/lang/hu/edit.txt b/lib/plugins/usermanager/lang/hu/edit.txt
new file mode 100644
index 000000000..f82746094
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hu/edit.txt
@@ -0,0 +1,2 @@
+===== Felhasználó szerkesztése =====
+
diff --git a/lib/plugins/usermanager/lang/hu/intro.txt b/lib/plugins/usermanager/lang/hu/intro.txt
new file mode 100644
index 000000000..150aff848
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hu/intro.txt
@@ -0,0 +1,2 @@
+====== Felhasználók kezelése ======
+
diff --git a/lib/plugins/usermanager/lang/hu/lang.php b/lib/plugins/usermanager/lang/hu/lang.php
new file mode 100644
index 000000000..9b9740cb0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hu/lang.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Hungarian language file
+ *
+ * @author Sandor TIHANYI <stihanyi+dw@gmail.com>
+ * @author Siaynoq Mage <siaynoqmage@gmail.com>
+ * @author schilling.janos@gmail.com
+ * @author Szabó Dávid <szabo.david@gyumolcstarhely.hu>
+ * @author Sándor TIHANYI <stihanyi+dw@gmail.com>
+ * @author David Szabo <szabo.david@gyumolcstarhely.hu>
+ */
+$lang['menu'] = 'Felhasználók kezelése';
+$lang['noauth'] = '(A felhasználói azonosítás nem működik.)';
+$lang['nosupport'] = '(A felhasználók kezelése nem támogatott.)';
+$lang['badauth'] = 'nem érvényes autentikációs technika';
+$lang['user_id'] = 'Felhasználó azonosító';
+$lang['user_pass'] = 'Jelszó';
+$lang['user_name'] = 'Név';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Csoportok';
+$lang['field'] = 'Mező';
+$lang['value'] = 'Érték';
+$lang['add'] = 'Hozzáadás';
+$lang['delete'] = 'Törlés';
+$lang['delete_selected'] = 'Kiválasztottak törlése';
+$lang['edit'] = 'Szerkesztés';
+$lang['edit_prompt'] = 'A felhasználó szerkesztése';
+$lang['modify'] = 'Változások mentése';
+$lang['search'] = 'Keresés';
+$lang['search_prompt'] = 'Keresés';
+$lang['clear'] = 'Keresési szűrés törlése';
+$lang['filter'] = 'Szűrés';
+$lang['summary'] = '%1$d-%2$d. felhasználókat mutatom a(z) %3$d megtalált felhasználóból. %4$d felhasználó van összesen.';
+$lang['nonefound'] = 'Nem találtam ilyen felhasználót. %d felhasználó van összesen.';
+$lang['delete_ok'] = '%d felhasználó törölve.';
+$lang['delete_fail'] = '%d felhasználót nem sikerült törölni.';
+$lang['update_ok'] = 'A felhasználó adatait sikeresen elmentettem.';
+$lang['update_fail'] = 'A felhasználó adatainak mentése nem sikerült.';
+$lang['update_exists'] = 'A felhasználói azonosító változtatása nem sikerült, a megadott azonosító (%s) már létezik. (A többi változtatás mentve.)';
+$lang['start'] = 'első';
+$lang['prev'] = 'előző';
+$lang['next'] = 'következő';
+$lang['last'] = 'utolsó';
+$lang['edit_usermissing'] = 'A kiválasztott felhasználót nem találom, a felhasználói nevét törölték vagy megváltoztatták.';
+$lang['user_notify'] = 'Felhasználó értesítése';
+$lang['note_notify'] = 'Csak akkor küld értesítő e-mailt, ha a felhasználó új jelszót kapott.';
+$lang['note_group'] = 'Ha nincs csoport meghatározva, az új felhasználó az alapértelmezett csoportba (%s) kerül.';
+$lang['note_pass'] = 'Ha a baloldali mező üres, és a felhasználó értesítés aktív, akkor generált jelszó lesz.';
+$lang['add_ok'] = 'A felhasználó sikeresen hozzáadva.';
+$lang['add_fail'] = 'A felhasználó hozzáadása nem sikerült.';
+$lang['notify_ok'] = 'Értesítő levél elküldve.';
+$lang['notify_fail'] = 'Nem sikerült az értesítő levelet elküldeni.';
diff --git a/lib/plugins/usermanager/lang/hu/list.txt b/lib/plugins/usermanager/lang/hu/list.txt
new file mode 100644
index 000000000..9da7320c6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hu/list.txt
@@ -0,0 +1,2 @@
+===== Felhasználók listája =====
+
diff --git a/lib/plugins/usermanager/lang/ia/add.txt b/lib/plugins/usermanager/lang/ia/add.txt
new file mode 100644
index 000000000..4695834f4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ia/add.txt
@@ -0,0 +1 @@
+===== Adder usator ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ia/delete.txt b/lib/plugins/usermanager/lang/ia/delete.txt
new file mode 100644
index 000000000..db1b4c077
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ia/delete.txt
@@ -0,0 +1 @@
+===== Deler usator ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ia/edit.txt b/lib/plugins/usermanager/lang/ia/edit.txt
new file mode 100644
index 000000000..2fcf02378
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ia/edit.txt
@@ -0,0 +1 @@
+===== Modificar usator ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ia/intro.txt b/lib/plugins/usermanager/lang/ia/intro.txt
new file mode 100644
index 000000000..f4fafcb9b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ia/intro.txt
@@ -0,0 +1 @@
+====== Gestion de usatores ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ia/lang.php b/lib/plugins/usermanager/lang/ia/lang.php
new file mode 100644
index 000000000..a8b8f45c0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ia/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Interlingua language file
+ *
+ * @author robocap <robocap1@gmail.com>
+ * @author Martijn Dekker <martijn@inlv.org>
+ */
+$lang['menu'] = 'Gestion de usatores';
+$lang['noauth'] = '(authentication de usatores non disponibile)';
+$lang['nosupport'] = '(gestion de usatores non supportate)';
+$lang['badauth'] = 'mechanismo de authentication invalide';
+$lang['user_id'] = 'Usator';
+$lang['user_pass'] = 'Contrasigno';
+$lang['user_name'] = 'Nomine real';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Gruppos';
+$lang['field'] = 'Campo';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Adder';
+$lang['delete'] = 'Deler';
+$lang['delete_selected'] = 'Deler seligite';
+$lang['edit'] = 'Modificar';
+$lang['edit_prompt'] = 'Modificar iste usator';
+$lang['modify'] = 'Salveguardar cambios';
+$lang['search'] = 'Cercar';
+$lang['search_prompt'] = 'Executar recerca';
+$lang['clear'] = 'Reinitialisar filtro de recerca';
+$lang['filter'] = 'Filtro';
+$lang['summary'] = 'Presentation del usatores %1$d-%2$d de %3$d trovate. %4$d usatores in total.';
+$lang['nonefound'] = 'Nulle usator trovate. %d usatores in total.';
+$lang['delete_ok'] = '%d usatores delite';
+$lang['delete_fail'] = 'Deletion de %d usatores fallite.';
+$lang['update_ok'] = 'Actualisation del usator succedite';
+$lang['update_fail'] = 'Actualisation del usator fallite';
+$lang['update_exists'] = 'Le modification del nomine del usator ha fallite; le usator specificate (%s) ja existe. (Omne altere modificationes essera applicate.)
+';
+$lang['start'] = 'initio';
+$lang['prev'] = 'precedente';
+$lang['next'] = 'sequente';
+$lang['last'] = 'fin';
+$lang['edit_usermissing'] = 'Le usator seligite non ha essite trovate. Es possibile que le nomine de usator specificate ha essite delite o cambiate alterubi.';
+$lang['user_notify'] = 'Notificar usator';
+$lang['note_notify'] = 'Le messages de notification es solmente inviate un nove contrasigno es date al usator.';
+$lang['note_group'] = 'Nove usatores essera addite al gruppo predefinite (%s) si nulle gruppo es specificate.';
+$lang['note_pass'] = 'Le contrasigno essera automaticamente generate si le campo es lassate vacue e le notification del usator es activate.';
+$lang['add_ok'] = 'Addition del usator succedite';
+$lang['add_fail'] = 'Addition del usator fallite';
+$lang['notify_ok'] = 'Message de notification inviate';
+$lang['notify_fail'] = 'Le message de notification non poteva esser inviate';
diff --git a/lib/plugins/usermanager/lang/ia/list.txt b/lib/plugins/usermanager/lang/ia/list.txt
new file mode 100644
index 000000000..f545f06df
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ia/list.txt
@@ -0,0 +1 @@
+===== Lista de usatores ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/id-ni/lang.php b/lib/plugins/usermanager/lang/id-ni/lang.php
new file mode 100644
index 000000000..d367340b7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id-ni/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * idni language file
+ *
+ * @author Harefa <fidelis@harefa.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/usermanager/lang/id/add.txt b/lib/plugins/usermanager/lang/id/add.txt
new file mode 100644
index 000000000..eae407c04
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id/add.txt
@@ -0,0 +1 @@
+===== Tambah User ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/id/delete.txt b/lib/plugins/usermanager/lang/id/delete.txt
new file mode 100644
index 000000000..99e53c9ef
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id/delete.txt
@@ -0,0 +1 @@
+===== Hapus User ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/id/edit.txt b/lib/plugins/usermanager/lang/id/edit.txt
new file mode 100644
index 000000000..6d14f4fde
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id/edit.txt
@@ -0,0 +1 @@
+===== Edit User ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/id/intro.txt b/lib/plugins/usermanager/lang/id/intro.txt
new file mode 100644
index 000000000..de053f2ae
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id/intro.txt
@@ -0,0 +1 @@
+===== Manajemen User ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/id/lang.php b/lib/plugins/usermanager/lang/id/lang.php
new file mode 100644
index 000000000..457ad4963
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id/lang.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Indonesian language file
+ *
+ * @author Irwan Butar Butar <irwansah.putra@gmail.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
+$lang['menu'] = 'Manajemen User';
+$lang['noauth'] = '(autentikasi tidak tersedia)';
+$lang['nosupport'] = '(manajemen user tidak didukung)';
+$lang['badauth'] = 'mekanisme autentikasi invali';
+$lang['user_id'] = 'User';
+$lang['user_pass'] = 'Password';
+$lang['user_name'] = 'Nama Lengkap';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Grup';
+$lang['field'] = 'Field';
+$lang['value'] = 'Nilai';
+$lang['add'] = 'Tambah';
+$lang['delete'] = 'Hapus';
+$lang['delete_selected'] = 'Hapus pilihan';
+$lang['edit'] = 'Edit';
+$lang['edit_prompt'] = 'Edit user ini';
+$lang['modify'] = 'Simpan Perubahan';
+$lang['search'] = 'Pencarian';
+$lang['search_prompt'] = 'Lakukan pencarian';
+$lang['clear'] = 'Reset Filter Pencarian';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Menampilkan user %1$d-%2$d dari %3$d user yang ditemukan. Total semua user %4$d.';
+$lang['nonefound'] = 'User tidak ditemukan. Total semua user %d. ';
+$lang['delete_ok'] = 'User %d dihapus';
+$lang['delete_fail'] = 'User %d tidak berhasil dihapus';
+$lang['update_ok'] = 'User berhasil diubah';
+$lang['update_fail'] = 'Perubahan user tidak berhasil';
+$lang['update_exists'] = 'Perubahan username tidak berhasil, Username (%s) sudah ada (perubahan lain tetap dilakukan)';
+$lang['start'] = 'awal';
+$lang['prev'] = 'sebelumnya';
+$lang['next'] = 'berikutnya';
+$lang['last'] = 'terakhir';
+$lang['edit_usermissing'] = 'User yang dipilih tida ditemukan, username tersebut mungkin sudah dihapus atau diubah ditempat lain.';
+$lang['user_notify'] = 'Beritahu user';
+$lang['note_notify'] = 'Email notifikasi hanya dikirim jika user diberikan password baru';
+$lang['note_group'] = 'User baru akan ditambahkan ke grup default (%s) jika tidak ada grup yang diisi.';
+$lang['add_ok'] = 'User telah berhasil ditambahkan';
+$lang['add_fail'] = 'Penambahan user tidak berhasil.';
+$lang['notify_ok'] = 'Email notifikasi berhasil terkirim.';
+$lang['notify_fail'] = 'Email notifikasi tidak berhasil terkirim.';
diff --git a/lib/plugins/usermanager/lang/id/list.txt b/lib/plugins/usermanager/lang/id/list.txt
new file mode 100644
index 000000000..9b70bc157
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id/list.txt
@@ -0,0 +1 @@
+===== Daftar User ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/is/delete.txt b/lib/plugins/usermanager/lang/is/delete.txt
new file mode 100644
index 000000000..564006584
--- /dev/null
+++ b/lib/plugins/usermanager/lang/is/delete.txt
@@ -0,0 +1 @@
+===== Eyða notanda ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/is/lang.php b/lib/plugins/usermanager/lang/is/lang.php
new file mode 100644
index 000000000..cabf83d64
--- /dev/null
+++ b/lib/plugins/usermanager/lang/is/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Icelandic language file
+ *
+ * @author Hrannar Baldursson <hrannar.baldursson@gmail.com>
+ * @author Ólafur Gunnlaugsson <oli@audiotools.com>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ */
+$lang['user_id'] = 'Notandi';
+$lang['user_pass'] = 'Aðgangsorð';
+$lang['user_name'] = 'Raunnafn';
+$lang['user_groups'] = 'Hópar';
+$lang['field'] = 'Svæði';
+$lang['delete'] = 'Eyða';
+$lang['add_ok'] = 'Notandinn var bætt við';
+$lang['add_fail'] = 'Bæta við nýjum notanda mistókst';
+$lang['notify_ok'] = 'Tilkynning var sendast með tölvupósti';
+$lang['notify_fail'] = 'Ekki hægt að senda tilkynning með tölvupósti';
diff --git a/lib/plugins/usermanager/lang/it/add.txt b/lib/plugins/usermanager/lang/it/add.txt
new file mode 100644
index 000000000..9ce4c6e38
--- /dev/null
+++ b/lib/plugins/usermanager/lang/it/add.txt
@@ -0,0 +1 @@
+===== Aggiungi utente =====
diff --git a/lib/plugins/usermanager/lang/it/delete.txt b/lib/plugins/usermanager/lang/it/delete.txt
new file mode 100644
index 000000000..270061f0d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/it/delete.txt
@@ -0,0 +1 @@
+===== Elimina utente =====
diff --git a/lib/plugins/usermanager/lang/it/edit.txt b/lib/plugins/usermanager/lang/it/edit.txt
new file mode 100644
index 000000000..39767bfdc
--- /dev/null
+++ b/lib/plugins/usermanager/lang/it/edit.txt
@@ -0,0 +1 @@
+===== Modifica utente =====
diff --git a/lib/plugins/usermanager/lang/it/intro.txt b/lib/plugins/usermanager/lang/it/intro.txt
new file mode 100644
index 000000000..3421709d6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/it/intro.txt
@@ -0,0 +1 @@
+====== Gestione Utenti ======
diff --git a/lib/plugins/usermanager/lang/it/lang.php b/lib/plugins/usermanager/lang/it/lang.php
new file mode 100644
index 000000000..34c510def
--- /dev/null
+++ b/lib/plugins/usermanager/lang/it/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Italian language file
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Silvia Sargentoni <polinnia@tin.it>
+ * @author Pietro Battiston toobaz@email.it
+ * @author Diego Pierotto ita.translations@tiscali.it
+ * @author ita.translations@tiscali.it
+ * @author Lorenzo Breda <lbreda@gmail.com>
+ * @author snarchio@alice.it
+ * @author robocap <robocap1@gmail.com>
+ * @author Osman Tekin osman.tekin93@hotmail.it
+ * @author Jacopo Corbetta <jacopo.corbetta@gmail.com>
+ */
+$lang['menu'] = 'Gestione Utenti';
+$lang['noauth'] = '(autenticazione non disponibile)';
+$lang['nosupport'] = '(gestione utenti non supportata)';
+$lang['badauth'] = 'sistema di autenticazione non valido';
+$lang['user_id'] = 'ID utente';
+$lang['user_pass'] = 'Password';
+$lang['user_name'] = 'Nome completo';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Gruppi';
+$lang['field'] = 'Campo';
+$lang['value'] = 'Valore';
+$lang['add'] = 'Aggiungi';
+$lang['delete'] = 'Elimina';
+$lang['delete_selected'] = 'Elimina selezionati';
+$lang['edit'] = 'Modifica';
+$lang['edit_prompt'] = 'Modifica questo utente';
+$lang['modify'] = 'Salva modifiche';
+$lang['search'] = 'Cerca';
+$lang['search_prompt'] = 'Esegui ricerca';
+$lang['clear'] = 'Azzera filtro di ricerca';
+$lang['filter'] = 'Filtro';
+$lang['summary'] = 'Visualizzazione utenti %1$d-%2$d di %3$d trovati. %4$d utenti totali.';
+$lang['nonefound'] = 'Nessun utente trovato. %d utenti totali.';
+$lang['delete_ok'] = '%d utenti eliminati';
+$lang['delete_fail'] = 'Eliminazione %d fallita.';
+$lang['update_ok'] = 'Aggiornamento utente riuscito';
+$lang['update_fail'] = 'Aggiornamento utente fallito';
+$lang['update_exists'] = 'Modifica nome utente fallita, il nome utente specificato (%s) esiste già (qualunque altra modifica sarà applicata).';
+$lang['start'] = 'primo';
+$lang['prev'] = 'precedente';
+$lang['next'] = 'successivo';
+$lang['last'] = 'ultimo';
+$lang['edit_usermissing'] = 'Utente selezionato non trovato, il nome utente specificato potrebbe essere stato eliminato o modificato altrove.';
+$lang['user_notify'] = 'Notifica utente';
+$lang['note_notify'] = 'Le email di notifica sono inviate soltanto se all\'utente è stata assegnata una nuova password.';
+$lang['note_group'] = 'Se non si specifica alcun gruppo, i nuovi utenti saranno aggiunti al gruppo predefinito (%s).';
+$lang['note_pass'] = 'La password verrà generata automaticamente qualora il campo di inserimento relativo venisse lasciato vuoto e le notifiche all\'utente fossero abilitate.';
+$lang['add_ok'] = 'Utente aggiunto correttamente';
+$lang['add_fail'] = 'Aggiunta utente fallita';
+$lang['notify_ok'] = 'Email di notifica inviata';
+$lang['notify_fail'] = 'L\'email di notifica non può essere inviata';
diff --git a/lib/plugins/usermanager/lang/it/list.txt b/lib/plugins/usermanager/lang/it/list.txt
new file mode 100644
index 000000000..91e27a9de
--- /dev/null
+++ b/lib/plugins/usermanager/lang/it/list.txt
@@ -0,0 +1 @@
+===== Elenco Utenti =====
diff --git a/lib/plugins/usermanager/lang/ja/add.txt b/lib/plugins/usermanager/lang/ja/add.txt
new file mode 100644
index 000000000..87b30e0a0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ja/add.txt
@@ -0,0 +1 @@
+===== ユーザー作成 =====
diff --git a/lib/plugins/usermanager/lang/ja/delete.txt b/lib/plugins/usermanager/lang/ja/delete.txt
new file mode 100644
index 000000000..67ef23e23
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ja/delete.txt
@@ -0,0 +1 @@
+===== ユーザー削除 =====
diff --git a/lib/plugins/usermanager/lang/ja/edit.txt b/lib/plugins/usermanager/lang/ja/edit.txt
new file mode 100644
index 000000000..e7695e307
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ja/edit.txt
@@ -0,0 +1 @@
+===== ユーザー編集 =====
diff --git a/lib/plugins/usermanager/lang/ja/intro.txt b/lib/plugins/usermanager/lang/ja/intro.txt
new file mode 100644
index 000000000..5dbe51c8c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ja/intro.txt
@@ -0,0 +1 @@
+====== ユーザー管理 ======
diff --git a/lib/plugins/usermanager/lang/ja/lang.php b/lib/plugins/usermanager/lang/ja/lang.php
new file mode 100644
index 000000000..321bbafe8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ja/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * japanese language file
+ * @author Yuji Takenaka <webmaster@davilin.com>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Ikuo Obataya <i.obataya@gmail.com>
+ * @author Daniel Dupriest <kououken@gmail.com>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ */
+$lang['menu'] = 'ユーザー管理';
+$lang['noauth'] = '(ユーザー認証が無効です)';
+$lang['nosupport'] = '(ユーザー管理はサポートされていません)';
+$lang['badauth'] = '認証のメカニズムが無効です';
+$lang['user_id'] = 'ユーザー';
+$lang['user_pass'] = 'パスワード';
+$lang['user_name'] = '氏名';
+$lang['user_mail'] = 'メールアドレス';
+$lang['user_groups'] = 'グループ';
+$lang['field'] = '項目';
+$lang['value'] = '値';
+$lang['add'] = '追加';
+$lang['delete'] = '削除';
+$lang['delete_selected'] = '選択したユーザーを削除';
+$lang['edit'] = '編集';
+$lang['edit_prompt'] = 'このユーザーを編集';
+$lang['modify'] = '変更を保存';
+$lang['search'] = '検索';
+$lang['search_prompt'] = '検索を実行';
+$lang['clear'] = '検索フィルターをリセット';
+$lang['filter'] = 'フィルター';
+$lang['summary'] = 'ユーザー %1$d-%2$d / %3$d, 総ユーザー数 %4$d';
+$lang['nonefound'] = 'ユーザーが見つかりません, 総ユーザー数 %d';
+$lang['delete_ok'] = '%d ユーザーが削除されました';
+$lang['delete_fail'] = '%d ユーザーの削除に失敗しました';
+$lang['update_ok'] = 'ユーザーは更新されました';
+$lang['update_fail'] = 'ユーザーの更新に失敗しました';
+$lang['update_exists'] = 'ユーザー名(%s)は既に存在するため、ユーザー名の変更に失敗しました(その他の項目は変更されました)。';
+$lang['start'] = '最初';
+$lang['prev'] = '前へ';
+$lang['next'] = '次へ';
+$lang['last'] = '最後';
+$lang['edit_usermissing'] = '選択したユーザーは見つかりません。削除もしくは変更された可能性があります。';
+$lang['user_notify'] = '通知するユーザー';
+$lang['note_notify'] = 'ユーザーが新しいパスワードを設定した場合のみ、通知メールが送信されます。';
+$lang['note_group'] = 'グループを指定しない場合は、既定のグループ(%s)に登録されいます。';
+$lang['note_pass'] = 'パスワードを空欄とした場合は、パスワードを自動的に生成します。この場合、ユーザーへの通知が有効となります。';
+$lang['add_ok'] = 'ユーザーを登録しました';
+$lang['add_fail'] = 'ユーザーの登録に失敗しました';
+$lang['notify_ok'] = '通知メールを送信しました';
+$lang['notify_fail'] = '通知メールを送信できませんでした';
diff --git a/lib/plugins/usermanager/lang/ja/list.txt b/lib/plugins/usermanager/lang/ja/list.txt
new file mode 100644
index 000000000..182cc198c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ja/list.txt
@@ -0,0 +1 @@
+===== ユーザーリスト =====
diff --git a/lib/plugins/usermanager/lang/kk/lang.php b/lib/plugins/usermanager/lang/kk/lang.php
new file mode 100644
index 000000000..dde5b9577
--- /dev/null
+++ b/lib/plugins/usermanager/lang/kk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * kazakh language file
+ *
+ * @author Nurgozha Kaliaskarov astana08@gmail.com
+ */
diff --git a/lib/plugins/usermanager/lang/ko/add.txt b/lib/plugins/usermanager/lang/ko/add.txt
new file mode 100644
index 000000000..578ba5636
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ko/add.txt
@@ -0,0 +1 @@
+===== 사용자 추가 =====
diff --git a/lib/plugins/usermanager/lang/ko/delete.txt b/lib/plugins/usermanager/lang/ko/delete.txt
new file mode 100644
index 000000000..1e9c0ba73
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ko/delete.txt
@@ -0,0 +1 @@
+===== 사용자 삭제 =====
diff --git a/lib/plugins/usermanager/lang/ko/edit.txt b/lib/plugins/usermanager/lang/ko/edit.txt
new file mode 100644
index 000000000..b8b13c5c8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ko/edit.txt
@@ -0,0 +1 @@
+===== 사용자 정보 수정 =====
diff --git a/lib/plugins/usermanager/lang/ko/intro.txt b/lib/plugins/usermanager/lang/ko/intro.txt
new file mode 100644
index 000000000..8c8bfa5b9
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ko/intro.txt
@@ -0,0 +1 @@
+====== 사용자 관리 ======
diff --git a/lib/plugins/usermanager/lang/ko/lang.php b/lib/plugins/usermanager/lang/ko/lang.php
new file mode 100644
index 000000000..f2322414a
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ko/lang.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * korean language file
+ *
+ * @author jk Lee
+ * @author dongnak@gmail.com
+ * @author Song Younghwan <purluno@gmail.com>
+ * @author SONG Younghwan <purluno@gmail.com>
+ * @author Seung-Chul Yoo <dryoo@live.com>
+ */
+$lang['menu'] = '사용자 관리자';
+$lang['noauth'] = '(사용자 인증이 불가능합니다.)';
+$lang['nosupport'] = '(사용자 관리가 지원되지 않습니다.)';
+$lang['badauth'] = '유효하지 않은 인증 메카니즘입니다.';
+$lang['user_id'] = '사용자';
+$lang['user_pass'] = '패스워드';
+$lang['user_name'] = '실제 이름';
+$lang['user_mail'] = '이메일 ';
+$lang['user_groups'] = '그룹들';
+$lang['field'] = '항목';
+$lang['value'] = '값';
+$lang['add'] = '추가';
+$lang['delete'] = '삭제';
+$lang['delete_selected'] = '삭제 선택';
+$lang['edit'] = '수정';
+$lang['edit_prompt'] = '이 사용자 수정';
+$lang['modify'] = '변경 저장';
+$lang['search'] = '검색';
+$lang['search_prompt'] = '검색 실행';
+$lang['clear'] = '검색 필터 초기화';
+$lang['filter'] = '필터';
+$lang['summary'] = '검색된 사용자들 보기(%1$d-%2$d 중 %3$d). 전체 사용자 %4$d 명.';
+$lang['nonefound'] = '검색된 사용자가 없습니다. 전체 사용자 %d 명.';
+$lang['delete_ok'] = '%d 명의 사용자가 삭제되었습니다.';
+$lang['delete_fail'] = '%d 명의 사용자의 삭제가 실패했습니다.';
+$lang['update_ok'] = '사용자 갱신이 성공했습니다.';
+$lang['update_fail'] = '사용자 갱신이 실패했습니다.';
+$lang['update_exists'] = '사용자 이름 변경이 실패했습니다. 사용자 이름(%s)이 이미 존재합니다. (다른 항목들의 변경은 적용됩니다.)';
+$lang['start'] = '시작';
+$lang['prev'] = '이전';
+$lang['next'] = '다음';
+$lang['last'] = '마지막';
+$lang['edit_usermissing'] = '선택된 사용자를 찾을 수 없습니다, 사용자 이름이 삭제되거나 변경됐을 수도 있습니다.';
+$lang['user_notify'] = '사용자에게 알림';
+$lang['note_notify'] = '사용자에게 새로운 암호를 준 경우에만 알림 이메일이 보내집니다.';
+$lang['note_group'] = '새로운 사용자들은 어떤 그룹도 설정하지 않은 경우에 기본 그룹(%s)에 추가됩니다.';
+$lang['note_pass'] = '사용자 통지가 지정되어 있을때, 필드에 아무값도 입력하지 않으면 암호가 자동 생성 됩니다.';
+$lang['add_ok'] = '사용자가 성공적으로 추가되었습니다.';
+$lang['add_fail'] = '사용자 추가가 실패했습니다.';
+$lang['notify_ok'] = '알림 이메일이 성공적으로 발송되었습니다. ';
+$lang['notify_fail'] = '알림 이메일 발송이 실패했습니다.';
diff --git a/lib/plugins/usermanager/lang/ko/list.txt b/lib/plugins/usermanager/lang/ko/list.txt
new file mode 100644
index 000000000..93fa3d6f2
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ko/list.txt
@@ -0,0 +1 @@
+===== 사용자 목록 =====
diff --git a/lib/plugins/usermanager/lang/la/add.txt b/lib/plugins/usermanager/lang/la/add.txt
new file mode 100644
index 000000000..beb797c4a
--- /dev/null
+++ b/lib/plugins/usermanager/lang/la/add.txt
@@ -0,0 +1 @@
+===== Sodalem addere ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/la/delete.txt b/lib/plugins/usermanager/lang/la/delete.txt
new file mode 100644
index 000000000..1eb5e1f14
--- /dev/null
+++ b/lib/plugins/usermanager/lang/la/delete.txt
@@ -0,0 +1 @@
+===== Sodalem delere ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/la/edit.txt b/lib/plugins/usermanager/lang/la/edit.txt
new file mode 100644
index 000000000..4e3d3b2ae
--- /dev/null
+++ b/lib/plugins/usermanager/lang/la/edit.txt
@@ -0,0 +1 @@
+===== Sodalem recensere ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/la/intro.txt b/lib/plugins/usermanager/lang/la/intro.txt
new file mode 100644
index 000000000..7f5c011a8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/la/intro.txt
@@ -0,0 +1 @@
+====== Sodalis Tabella ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/la/lang.php b/lib/plugins/usermanager/lang/la/lang.php
new file mode 100644
index 000000000..52c848754
--- /dev/null
+++ b/lib/plugins/usermanager/lang/la/lang.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Latin language file
+ *
+ * @author Massimiliano Vassalli <vassalli.max@gmail.com>
+ */
+$lang['menu'] = 'Sodalis Tabella';
+$lang['noauth'] = '(Sodalis confirmatio deest)';
+$lang['nosupport'] = '(Sodalis administratio deest)';
+$lang['badauth'] = 'Confirmatio fieri non potest.';
+$lang['user_id'] = 'Sodalis';
+$lang['user_pass'] = 'Tessera';
+$lang['user_name'] = 'Nomen uerum';
+$lang['user_mail'] = 'Cursus Interretialis';
+$lang['user_groups'] = 'Grex';
+$lang['field'] = 'Campus';
+$lang['value'] = 'Vis';
+$lang['add'] = 'Addere';
+$lang['delete'] = 'Delere';
+$lang['delete_selected'] = 'Electa delere';
+$lang['edit'] = 'Recensere';
+$lang['edit_prompt'] = 'Sodalem recensere';
+$lang['modify'] = 'Mutata seruare';
+$lang['search'] = 'Quaerere';
+$lang['search_prompt'] = 'Agentem quaerere';
+$lang['clear'] = 'Colum quaerendi abrogare';
+$lang['filter'] = 'Colum';
+$lang['summary'] = 'Sodales %1$d-%2$d inter %3$d ostenduntur. Numerus Sodalium. %4$d.';
+$lang['nonefound'] = 'Sodalis non repertus. Numerus sodalium: %d';
+$lang['delete_ok'] = '%d Sodales delentur.';
+$lang['delete_fail'] = '%d non deleri possunt.';
+$lang['update_ok'] = 'Sodalis feliciter nouatus\a';
+$lang['update_fail'] = 'Sodalis infeliciter nouatus\a';
+$lang['update_exists'] = 'Nomen Sodalis non mutatur, eo quod hoc nomen (%s) iam electum est.';
+$lang['start'] = 'in primis';
+$lang['prev'] = 'antea';
+$lang['next'] = 'postea';
+$lang['last'] = 'in extremis';
+$lang['edit_usermissing'] = 'Hic Sodalis non inuenitur, eo quod nomen iam deletum uel mutatum est.';
+$lang['user_notify'] = 'Sodalem adnotare';
+$lang['note_notify'] = 'Adnotationes cursu interretiali missae solum si noua tessera petitur.';
+$lang['note_group'] = 'Noui\ae Sodales communi Gregi adduntur (%s) si Grex non elegitur.';
+$lang['note_pass'] = 'Tessera non generata nisi campus uacuos est et Sodalis adnotationes aptae faciuntur.';
+$lang['add_ok'] = 'Sodalis feliciter additur.';
+$lang['add_fail'] = 'Sodalis infeliciter additur.';
+$lang['notify_ok'] = 'Adnotationes cursu interretiali missae';
+$lang['notify_fail'] = 'Adnotationes cursu interretiali non missae';
diff --git a/lib/plugins/usermanager/lang/la/list.txt b/lib/plugins/usermanager/lang/la/list.txt
new file mode 100644
index 000000000..b470d2ea4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/la/list.txt
@@ -0,0 +1 @@
+===== Sodalis index ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/lb/lang.php b/lib/plugins/usermanager/lang/lb/lang.php
new file mode 100644
index 000000000..59acdf7a8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lb/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * lb language file
+ *
+ * @author joel@schintgen.net
+ */
diff --git a/lib/plugins/usermanager/lang/lb/list.txt b/lib/plugins/usermanager/lang/lb/list.txt
new file mode 100644
index 000000000..022afe831
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lb/list.txt
@@ -0,0 +1 @@
+===== Benotzerlëscht ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/lt/add.txt b/lib/plugins/usermanager/lang/lt/add.txt
new file mode 100644
index 000000000..32681ade7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lt/add.txt
@@ -0,0 +1,2 @@
+===== Pridėti vartotoją =====
+
diff --git a/lib/plugins/usermanager/lang/lt/delete.txt b/lib/plugins/usermanager/lang/lt/delete.txt
new file mode 100644
index 000000000..262713c98
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lt/delete.txt
@@ -0,0 +1,2 @@
+===== Ištrinti vartotoją =====
+
diff --git a/lib/plugins/usermanager/lang/lt/edit.txt b/lib/plugins/usermanager/lang/lt/edit.txt
new file mode 100644
index 000000000..da57ea380
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lt/edit.txt
@@ -0,0 +1,2 @@
+===== Redaguoti vartotoją =====
+
diff --git a/lib/plugins/usermanager/lang/lt/intro.txt b/lib/plugins/usermanager/lang/lt/intro.txt
new file mode 100644
index 000000000..61f80d52e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lt/intro.txt
@@ -0,0 +1,2 @@
+====== Vartotojų administravimas ======
+
diff --git a/lib/plugins/usermanager/lang/lt/lang.php b/lib/plugins/usermanager/lang/lt/lang.php
new file mode 100644
index 000000000..db3cf2d32
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lt/lang.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Lithuanian language file
+ *
+ * @author grawity <grawity@gmail.com>
+ * @author audrius.klevas@gmail.com
+ * @author Arunas Vaitekunas <aras@fan.lt>
+ */
+$lang['menu'] = 'Vartotojų administravimas';
+$lang['noauth'] = '(vartotojų autentifikacija neprieinama)';
+$lang['nosupport'] = '(vartotojų administravimas nepalaikomas)';
+$lang['badauth'] = 'neteisingas autentifikacijos būdas';
+$lang['user_id'] = 'Vartotojas';
+$lang['user_pass'] = 'Slaptažodis';
+$lang['user_name'] = 'Vardas';
+$lang['user_mail'] = 'El.paštas';
+$lang['user_groups'] = 'Grupės';
+$lang['field'] = 'Laukas';
+$lang['value'] = 'Turinys';
+$lang['add'] = 'Pridėti';
+$lang['delete'] = 'Pašalinti';
+$lang['delete_selected'] = 'Pašalinti pažymėtus';
+$lang['edit'] = 'Redaguoti';
+$lang['edit_prompt'] = 'Redaguoti šį vartotoją';
+$lang['modify'] = 'Išsaugoti';
+$lang['search'] = 'Paieška';
+$lang['search_prompt'] = 'Ieškoti';
+$lang['clear'] = 'Panaikinti filtrą';
+$lang['filter'] = 'Filtras';
+$lang['summary'] = 'Rodomi vartotojai %1$d-%2$d iš %3$d rastų. Iš viso %4$d vartotojų.';
+$lang['nonefound'] = 'Vartotojų nerasta. Iš viso %d vartotojų.';
+$lang['delete_ok'] = 'Pašalinta %d vartotojų';
+$lang['delete_fail'] = '%d nepavyko pašalinti.';
+$lang['update_ok'] = 'Vartotojas sėkmingai pakeistas';
+$lang['update_fail'] = 'Vartotojo pakeitimas nepavyko';
+$lang['update_exists'] = 'Vartotojo vardo pakeitimas nepavyko, nes nurodytas vartotojo vardas (%s) jau yra (kiti pakeitimai įvykdyti).';
+$lang['start'] = 'pradžia';
+$lang['prev'] = 'atgal';
+$lang['next'] = 'pirmyn';
+$lang['last'] = 'pabaiga';
+$lang['edit_usermissing'] = 'Pasirinktas vartotojas nerastas, nurodytas vartotojo vardas galėjo būti pašalintas ar pakeistas kitur.';
+$lang['user_notify'] = 'Įspėti vartotoją';
+$lang['note_notify'] = 'Įspėjimas siunčiamas tik tada, kai vartotojui priskiriamas naujas slaptažodis.';
+$lang['note_group'] = 'Jei grupė nenurodyta, nauji vartotojai pridedami į pagrindinę grupę (%s).';
+$lang['add_ok'] = 'Vartotojas sėkmingai pridėtas';
+$lang['add_fail'] = 'Vartotojo pridėjimas nepavyko';
+$lang['notify_ok'] = 'Įspėjimo el.laiškas išsiųstas';
+$lang['notify_fail'] = 'Įspėjimo el.laiško išsiųsti nepavyko';
diff --git a/lib/plugins/usermanager/lang/lt/list.txt b/lib/plugins/usermanager/lang/lt/list.txt
new file mode 100644
index 000000000..87be62843
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lt/list.txt
@@ -0,0 +1,2 @@
+===== Vartotojų sąrašas =====
+
diff --git a/lib/plugins/usermanager/lang/lv/add.txt b/lib/plugins/usermanager/lang/lv/add.txt
new file mode 100644
index 000000000..06fd70002
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lv/add.txt
@@ -0,0 +1 @@
+===== Pievienot lietotāju =====
diff --git a/lib/plugins/usermanager/lang/lv/delete.txt b/lib/plugins/usermanager/lang/lv/delete.txt
new file mode 100644
index 000000000..5f59af7b8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lv/delete.txt
@@ -0,0 +1 @@
+===== Dzēst lietotāju =====
diff --git a/lib/plugins/usermanager/lang/lv/edit.txt b/lib/plugins/usermanager/lang/lv/edit.txt
new file mode 100644
index 000000000..efb0b04d7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lv/edit.txt
@@ -0,0 +1 @@
+===== Labot lietotāju =====
diff --git a/lib/plugins/usermanager/lang/lv/intro.txt b/lib/plugins/usermanager/lang/lv/intro.txt
new file mode 100644
index 000000000..b248ddcb7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lv/intro.txt
@@ -0,0 +1 @@
+====== Lietotāju pārvaldnieks ======
diff --git a/lib/plugins/usermanager/lang/lv/lang.php b/lib/plugins/usermanager/lang/lv/lang.php
new file mode 100644
index 000000000..620678ff5
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lv/lang.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Latvian language file
+ *
+ * @author Aivars Miška <allefm@gmail.lv>
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['menu'] = 'Lietotāju pārvaldnieks';
+$lang['noauth'] = '(lietotāju autentifikācijas nav)';
+$lang['nosupport'] = '(lietotāju pārvaldība netiek uzturēta)';
+$lang['badauth'] = 'nederīgs autentifikācijas mehānisms';
+$lang['user_id'] = 'Lietotājs';
+$lang['user_pass'] = 'Parole';
+$lang['user_name'] = 'Vārds/uzvārds';
+$lang['user_mail'] = 'Epasts';
+$lang['user_groups'] = 'Grupas';
+$lang['field'] = 'Lauks';
+$lang['value'] = 'Vērtība';
+$lang['add'] = 'Pielikt';
+$lang['delete'] = 'Dzēst';
+$lang['delete_selected'] = 'Dzēst izvēlēto';
+$lang['edit'] = 'Labot';
+$lang['edit_prompt'] = 'Labot šo lietotāju';
+$lang['modify'] = 'Saglabāt izmaiņas';
+$lang['search'] = 'Meklēšana';
+$lang['search_prompt'] = 'Meklēt';
+$lang['clear'] = 'Noņemt meklēšanas filtru';
+$lang['filter'] = 'Filtrs';
+$lang['summary'] = 'Lietotāji %1$d.- %2$d. no %3$d atrastajiem. Pavisam %4$d lietotāji.';
+$lang['nonefound'] = 'Neviens nav atrasts. Pavisam %d lietotāju.';
+$lang['delete_ok'] = 'Dzēsti %d lietotāji';
+$lang['delete_fail'] = '%d neizdevās izdzēst.';
+$lang['update_ok'] = 'Lietotāja dati saglabāti';
+$lang['update_fail'] = 'Lietotāja dati nav saglabāti';
+$lang['update_exists'] = 'Lietotāja vārds nav nomainīts, norādīto vārdu (%s) kāds jau izmanto (pārējās izmaiņas tiks saglabātas).';
+$lang['start'] = 'sākums';
+$lang['prev'] = 'iepriekšējais';
+$lang['next'] = 'nākamais';
+$lang['last'] = 'pēdējais';
+$lang['edit_usermissing'] = 'Norādītais lietotājs nav atrasts, varbūt tas ir dzēst vai mainīts citur.';
+$lang['user_notify'] = 'Paziņot lietotājam';
+$lang['note_notify'] = 'Paziņojumus izsūta tikai tad, ja lietotājam dod jaunu paroli.';
+$lang['note_group'] = 'Ja nenorāda grupu, lietotāju pievieno noklusētajai grupai (%s).';
+$lang['note_pass'] = 'Ja paroles lauku atstāj tukšu un atzīmē paziņošanu lietotājam, parole tiks ģenerēta automātiski.';
+$lang['add_ok'] = 'Lietotājs veiksmīgi pievienots';
+$lang['add_fail'] = 'Lietotājs nav pievienots.';
+$lang['notify_ok'] = 'Paziņojums izsūtīts.';
+$lang['notify_fail'] = 'Nevar izsūtīt paziņojumu.';
diff --git a/lib/plugins/usermanager/lang/lv/list.txt b/lib/plugins/usermanager/lang/lv/list.txt
new file mode 100644
index 000000000..44a10d94c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lv/list.txt
@@ -0,0 +1 @@
+===== Lietotāju saraksts =====
diff --git a/lib/plugins/usermanager/lang/mk/add.txt b/lib/plugins/usermanager/lang/mk/add.txt
new file mode 100644
index 000000000..c90121d1b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mk/add.txt
@@ -0,0 +1 @@
+===== Додај корисник ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mk/delete.txt b/lib/plugins/usermanager/lang/mk/delete.txt
new file mode 100644
index 000000000..8a6b5e9b5
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mk/delete.txt
@@ -0,0 +1 @@
+===== Избриши корисник ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mk/edit.txt b/lib/plugins/usermanager/lang/mk/edit.txt
new file mode 100644
index 000000000..da6306141
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mk/edit.txt
@@ -0,0 +1 @@
+===== Уреди корисник ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mk/intro.txt b/lib/plugins/usermanager/lang/mk/intro.txt
new file mode 100644
index 000000000..747d00921
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mk/intro.txt
@@ -0,0 +1 @@
+===== Менаџер за корисник ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mk/lang.php b/lib/plugins/usermanager/lang/mk/lang.php
new file mode 100644
index 000000000..97ef51369
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mk/lang.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Macedonian language file
+ *
+ * @author Dimitar Talevski <dimi3.14@gmail.com>
+ */
+$lang['menu'] = 'Менаџер за корисник';
+$lang['noauth'] = '(автентикација на корисник не е достапна)';
+$lang['nosupport'] = '(менаџирање на корисник не е поддржано)';
+$lang['badauth'] = 'невалиден механизам за автентикација';
+$lang['user_id'] = 'Корисник';
+$lang['user_pass'] = 'Лозинка';
+$lang['user_name'] = 'Вистинско име';
+$lang['user_mail'] = 'Е-пошта';
+$lang['user_groups'] = 'Групи';
+$lang['field'] = 'Поле';
+$lang['value'] = 'Вредност';
+$lang['add'] = 'Додај';
+$lang['delete'] = 'Избриши';
+$lang['delete_selected'] = 'Избриши ги избраните';
+$lang['edit'] = 'Уреди';
+$lang['edit_prompt'] = 'Уреди го овој корисник';
+$lang['modify'] = 'Зачувај промени';
+$lang['search'] = 'Барај';
+$lang['search_prompt'] = 'Изврши пребарување';
+$lang['clear'] = 'Ресетирај го филтерот за пребарување';
+$lang['filter'] = 'Филтер';
+$lang['delete_ok'] = '%d корисници се избришани';
+$lang['delete_fail'] = '%d не успееја да се избришат.';
+$lang['update_ok'] = 'Корисникот е успешно ажуриран';
+$lang['update_fail'] = 'Корисникот не е успешно ажуриран';
+$lang['start'] = 'почеток';
+$lang['prev'] = 'претходна';
+$lang['next'] = 'следна';
+$lang['last'] = 'последна';
+$lang['user_notify'] = 'Извести го корисникот';
+$lang['add_ok'] = 'Корисникот е успешно додаден';
+$lang['add_fail'] = 'Додавањето на корисникот не е успешно';
diff --git a/lib/plugins/usermanager/lang/mk/list.txt b/lib/plugins/usermanager/lang/mk/list.txt
new file mode 100644
index 000000000..651462e9d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mk/list.txt
@@ -0,0 +1 @@
+===== Листа со корисници ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mr/add.txt b/lib/plugins/usermanager/lang/mr/add.txt
new file mode 100644
index 000000000..fc3a87737
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mr/add.txt
@@ -0,0 +1 @@
+====== सदस्य नोंद करा ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mr/delete.txt b/lib/plugins/usermanager/lang/mr/delete.txt
new file mode 100644
index 000000000..cf0e48551
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mr/delete.txt
@@ -0,0 +1 @@
+====== सदस्य डिलीट करा ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mr/edit.txt b/lib/plugins/usermanager/lang/mr/edit.txt
new file mode 100644
index 000000000..2d3d64915
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mr/edit.txt
@@ -0,0 +1 @@
+====== सदस्य बदला ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mr/intro.txt b/lib/plugins/usermanager/lang/mr/intro.txt
new file mode 100644
index 000000000..9253b323e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mr/intro.txt
@@ -0,0 +1 @@
+====== सदस्य व्यवस्थापक ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mr/lang.php b/lib/plugins/usermanager/lang/mr/lang.php
new file mode 100644
index 000000000..8915678cc
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mr/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Marathi language file
+ *
+ * @author ghatothkach@hotmail.com
+ * @author Padmanabh Kulkarni <kulkarnipadmanabh@gmail.com>
+ * @author Padmanabh Kulkarni<kulkarnipadmanabh@gmail.com>
+ * @author shantanoo@gmail.com
+ */
+$lang['menu'] = 'सदस्य व्यवस्थापक';
+$lang['noauth'] = '( सदस्य अधिकृत करण्याची सुविधा नाही )';
+$lang['nosupport'] = '( सदस्य व्यवस्थापन उपलब्ध नाही )';
+$lang['badauth'] = 'अधिकृत करण्याची व्यवस्था अवैध';
+$lang['user_id'] = 'सदस्य';
+$lang['user_pass'] = 'पासवर्ड';
+$lang['user_name'] = 'खरे नाव';
+$lang['user_mail'] = 'ईमेल';
+$lang['user_groups'] = 'गट';
+$lang['field'] = 'रकाना';
+$lang['value'] = 'किम्मत';
+$lang['add'] = 'जोड़ा';
+$lang['delete'] = 'डिलीट';
+$lang['delete_selected'] = 'निवडलेले डिलीट करा';
+$lang['edit'] = 'संपादन';
+$lang['edit_prompt'] = 'या सदस्याची माहिती बदला';
+$lang['modify'] = 'बदल सुरक्षित करा';
+$lang['search'] = 'शोध';
+$lang['search_prompt'] = 'शोध करा';
+$lang['clear'] = 'शोधाचे निकष बदला';
+$lang['filter'] = 'निकष';
+$lang['summary'] = 'सापडलेल्या %3$d सदस्यापैकी %1$d ते %2$d दाखवले आहेत. एकूण सदस्या %4$d.';
+$lang['nonefound'] = 'एकही सदस्य मिळाला नाही. एकूण सदस्य %d.';
+$lang['delete_ok'] = '%d सदस्य डिलीट केले.';
+$lang['delete_fail'] = '%d डिलीट करू शकलो नाही.';
+$lang['update_ok'] = 'सदस्याची माहिती यशस्वीरीत्या बदलली आहे';
+$lang['update_fail'] = 'सदस्याची माहिती बदलता आली नाही';
+$lang['update_exists'] = 'सदस्याचे नाव बदलू शकलो नाही. %s हे नाव आधीच अस्तित्वात आहे. ( इतर सर्व बदल केले जातील )';
+$lang['start'] = 'सुरुवात';
+$lang['prev'] = 'आधीचं';
+$lang['next'] = 'पुढचं';
+$lang['last'] = 'शेवटचं';
+$lang['edit_usermissing'] = 'दिलेला सदस्य सापडला नाही. तो कदाचित डिलीट झाला असेल किंवा बदलला गेला असेल.';
+$lang['user_notify'] = 'सदस्याला सूचित करा.';
+$lang['note_notify'] = 'सदस्याला नवीन पासवर्ड दिला तरच सूचनेचे ईमेल पाठवले जातात.';
+$lang['note_group'] = 'नवीन सदस्य जर गट निवडला नसेल तर %s या गटात टाकले जातील.';
+$lang['note_pass'] = 'पासवर्डचा रकाना रिकामा ठेवल्यास व सदस्य सूचना व्यवस्था चालू असल्यास पासवर्ड आपोआप तयार केला जाईल.';
+$lang['add_ok'] = 'सदस्य यशस्वीरीत्या नोंद झाला';
+$lang['add_fail'] = 'सदस्याची नोंद झाली नाही';
+$lang['notify_ok'] = 'सूचनेचा ईमेल पाठवला';
+$lang['notify_fail'] = 'सूचनेचा ईमेल पाठवला गेला नाही';
diff --git a/lib/plugins/usermanager/lang/mr/list.txt b/lib/plugins/usermanager/lang/mr/list.txt
new file mode 100644
index 000000000..ab6906771
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mr/list.txt
@@ -0,0 +1 @@
+====== सदस्य यादी ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ms/lang.php b/lib/plugins/usermanager/lang/ms/lang.php
new file mode 100644
index 000000000..77ad2a1c1
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ms/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Malay language file
+ *
+ * @author Markos
+ */
diff --git a/lib/plugins/usermanager/lang/ne/add.txt b/lib/plugins/usermanager/lang/ne/add.txt
new file mode 100644
index 000000000..868b12ab1
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ne/add.txt
@@ -0,0 +1 @@
+=====प्रयोगकर्ता थप्नुहोस् ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ne/delete.txt b/lib/plugins/usermanager/lang/ne/delete.txt
new file mode 100644
index 000000000..4441c8349
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ne/delete.txt
@@ -0,0 +1 @@
+===== प्रयोगकर्ता मेट्नुहोस ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ne/edit.txt b/lib/plugins/usermanager/lang/ne/edit.txt
new file mode 100644
index 000000000..040d2697d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ne/edit.txt
@@ -0,0 +1 @@
+===== प्रयोगकर्ता सम्पादन गर्नुहोस===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ne/intro.txt b/lib/plugins/usermanager/lang/ne/intro.txt
new file mode 100644
index 000000000..de08e483d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ne/intro.txt
@@ -0,0 +1 @@
+====== प्रयोगकर्ता व्यवस्थापक ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ne/lang.php b/lib/plugins/usermanager/lang/ne/lang.php
new file mode 100644
index 000000000..f68ed2074
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ne/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Nepali language file
+ *
+ * @author Saroj Kumar Dhakal <lotusnagarkot@gmail.com>
+ * @author SarojKumar Dhakal <lotusnagarkot@yahoo.com>
+ * @author Saroj Dhakal<lotusnagarkot@yahoo.com>
+ */
+$lang['menu'] = 'प्रयोगकर्ता व्यवस्थापक';
+$lang['noauth'] = '(प्रयोगकर्ता प्रमाणिकरण उपलब्ध छैन)';
+$lang['nosupport'] = '(प्रयोगकर्ता व्यवस्थापन समर्थित छैन)';
+$lang['badauth'] = 'अमान्य प्रमाणिकरण विधि';
+$lang['user_id'] = 'प्रयोगकर्ता';
+$lang['user_pass'] = 'प्रवेशशब्द';
+$lang['user_name'] = 'वास्तविक नाम';
+$lang['user_mail'] = 'इमेल';
+$lang['user_groups'] = 'समूह ';
+$lang['field'] = 'क्षेत्र';
+$lang['value'] = 'मान ';
+$lang['add'] = 'थप्नुहोस्';
+$lang['delete'] = 'मेट्नुहोस्';
+$lang['delete_selected'] = 'सेलेक्ट गरिएको मेट्नुहोस्';
+$lang['edit'] = 'सम्पादन गर्नुहोस्';
+$lang['edit_prompt'] = 'यो प्रयोगकर्ता सम्पादन गर्नुहोस् ';
+$lang['modify'] = 'परिवर्तन वचत गर्नुहोस्';
+$lang['search'] = 'खोज';
+$lang['search_prompt'] = 'खोज्नुहोस्';
+$lang['clear'] = 'खोज फिल्टर पूर्वरुपमा फर्काउनुहोस्';
+$lang['filter'] = 'फिल्टर ';
+$lang['summary'] = 'देखाउदै %1$d-%2$d of %3$d भेटिएका %4$d कुल प्रयोगकर्ता मध्येबाट ।';
+$lang['nonefound'] = '%d कुल प्रयोगकर्ता। कुनै पनि प्रयोगकर्ता भेटिएन ।';
+$lang['delete_ok'] = '%d प्रयोगकर्ता मेटिए';
+$lang['delete_fail'] = '%d प्रयोगकर्ता हटाउन सकिएन ';
+$lang['update_ok'] = 'प्रयोगकर्ता सफलतापूर्वक अध्यावधिक गरियो ';
+$lang['update_fail'] = 'प्रयोगकर्ता अध्यावधिक कार्य असफल';
+$lang['update_exists'] = 'पर्ययोगकर्ताको नाम परिवर्तन असफल, दिइएको प्रयोगकर्ता नाम( %s) पहिले देखि रहेको छ। ( यसबाहेकका परिवर्रनहरू गरिएका छन्)';
+$lang['start'] = 'सुरु गर्नुहोस्';
+$lang['prev'] = 'पहिलेको ';
+$lang['next'] = 'पछिको';
+$lang['last'] = 'अन्तिम';
+$lang['edit_usermissing'] = 'छानिएको प्रयोगकर्ता भेटिएन, खुलाइएको प्रयोगकर्ता मेटिएको या कतै परिवर्तन गरिएको हुनसक्छ।';
+$lang['user_notify'] = 'प्रयोगकर्तालाई जानकारी दिनुहोस् ';
+$lang['note_notify'] = 'जानकारी इमेल तब मात्र पठाइन्छ जब प्रयोगकर्तालाई नयाँ प्रवेश शब्द दिइन्छ।';
+$lang['note_group'] = 'नयाँ प्रयोगकर्तालाई पूर्वनिर्धारित समूह नखुलाएमा (%s) मा समावेश गराइनेछ ।';
+$lang['note_pass'] = 'प्रवेश शव्द क्षेत्र खाली राखेमा प्रवेश शव्द स्वत: निर्माण हुनेछ र प्रयोगकर्तालाई जानकारी पठइने छ ।';
+$lang['add_ok'] = 'प्रोगकर्ता सफलतापूर्वक थपियो';
+$lang['add_fail'] = 'प्रयोगकर्ता थप्ने कार्य असफल';
+$lang['notify_ok'] = 'जानकारी पत्र पठाइयो';
+$lang['notify_fail'] = 'जानकारी पत्र पठाउन सकिएन ';
diff --git a/lib/plugins/usermanager/lang/ne/list.txt b/lib/plugins/usermanager/lang/ne/list.txt
new file mode 100644
index 000000000..ece94b388
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ne/list.txt
@@ -0,0 +1 @@
+===== प्रयोगकर्ता सुची ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/nl/add.txt b/lib/plugins/usermanager/lang/nl/add.txt
new file mode 100644
index 000000000..992d9f300
--- /dev/null
+++ b/lib/plugins/usermanager/lang/nl/add.txt
@@ -0,0 +1 @@
+===== Nieuwe gebruiker ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/nl/delete.txt b/lib/plugins/usermanager/lang/nl/delete.txt
new file mode 100644
index 000000000..ad26e058f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/nl/delete.txt
@@ -0,0 +1 @@
+===== Verwijder gebruiker ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/nl/edit.txt b/lib/plugins/usermanager/lang/nl/edit.txt
new file mode 100644
index 000000000..0d58e48f3
--- /dev/null
+++ b/lib/plugins/usermanager/lang/nl/edit.txt
@@ -0,0 +1 @@
+===== Gebruiker wijzigen ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/nl/intro.txt b/lib/plugins/usermanager/lang/nl/intro.txt
new file mode 100644
index 000000000..7df09dbab
--- /dev/null
+++ b/lib/plugins/usermanager/lang/nl/intro.txt
@@ -0,0 +1 @@
+==== Gebruikersmanager ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/nl/lang.php b/lib/plugins/usermanager/lang/nl/lang.php
new file mode 100644
index 000000000..b00ab22e0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/nl/lang.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Dutch language file
+ *
+ * @author Wouter Schoot <wouter@schoot.org>
+ * @author John de Graaff <john@de-graaff.net>
+ * @author Niels Schoot <niels.schoot@quintiq.com>
+ * @author Dion Nicolaas <dion@nicolaas.net>
+ * @author Danny Rotsaert <danny.rotsaert@edpnet.be>
+ * @author Marijn Hofstra hofstra.m@gmail.com
+ * @author Matthias Carchon webmaster@c-mattic.be
+ * @author Marijn Hofstra <hofstra.m@gmail.com>
+ * @author Timon Van Overveldt <timonvo@gmail.com>
+ * @author Jeroen
+ * @author Ricardo Guijt <ricardoguijt@gmail.com>
+ */
+$lang['menu'] = 'Gebruikersmanager';
+$lang['noauth'] = '(gebruikersauthenticatie niet beschikbaar)';
+$lang['nosupport'] = '(gebruikersmanagement niet ondersteund)';
+$lang['badauth'] = 'ongeldige authenticatiemethode';
+$lang['user_id'] = 'Gebruiker';
+$lang['user_pass'] = 'Wachtwoord';
+$lang['user_name'] = 'Volledige naam';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Groepen';
+$lang['field'] = 'Veld';
+$lang['value'] = 'Waarde';
+$lang['add'] = 'Toevoegen';
+$lang['delete'] = 'Verwijder';
+$lang['delete_selected'] = 'Verwijder geselecteerden';
+$lang['edit'] = 'Wijzigen';
+$lang['edit_prompt'] = 'Wijzig deze gebruiker';
+$lang['modify'] = 'Wijzigingen opslaan';
+$lang['search'] = 'Zoek';
+$lang['search_prompt'] = 'Voer zoekopdracht uit';
+$lang['clear'] = 'Verwijder zoekfilter';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Weergegeven gebruikers %1$d-%2$d van %3$d gevonden. %4$d gebruikers in totaal.';
+$lang['nonefound'] = 'Geen gebruikers gevonden. %d gebruikers in totaal.';
+$lang['delete_ok'] = '%d gebruikers verwijderd';
+$lang['delete_fail'] = '%d kon niet worden verwijderd.';
+$lang['update_ok'] = 'Gebruiker succesvol gewijzigd';
+$lang['update_fail'] = 'Gebruiker wijzigen mislukt';
+$lang['update_exists'] = 'Gebruikersnaam veranderen mislukt, de opgegeven gebruikersnaam (%s) bestaat reeds (overige aanpassingen worden wel doorgevoerd).';
+$lang['start'] = 'start';
+$lang['prev'] = 'vorige';
+$lang['next'] = 'volgende';
+$lang['last'] = 'laatste';
+$lang['edit_usermissing'] = 'Geselecteerde gebruiker niet gevonden, de opgegeven gebruikersnaam kan verwijderd zijn of elders aangepast.';
+$lang['user_notify'] = 'Gebruiker notificeren';
+$lang['note_notify'] = 'Notificatie-e-mails worden alleen verstuurd wanneer de gebruiker een nieuw wachtwoord wordt toegekend.';
+$lang['note_group'] = 'Nieuwe gebruikers zullen aan de standaard groep (%s) worden toegevoegd als er geen groep opgegeven is.';
+$lang['note_pass'] = 'Het wachtwoord wordt automatisch gegenereerd als het veld wordt leeggelaten en gebruikersnotificaties aanstaan.';
+$lang['add_ok'] = 'Gebruiker succesvol toegevoegd';
+$lang['add_fail'] = 'Gebruiker kon niet worden toegevoegd';
+$lang['notify_ok'] = 'Notificatie-e-mail verzonden';
+$lang['notify_fail'] = 'Notificatie-e-mail kon niet worden verzonden';
diff --git a/lib/plugins/usermanager/lang/nl/list.txt b/lib/plugins/usermanager/lang/nl/list.txt
new file mode 100644
index 000000000..a9aac845d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/nl/list.txt
@@ -0,0 +1 @@
+===== Gebruikerslijst ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/no/add.txt b/lib/plugins/usermanager/lang/no/add.txt
new file mode 100644
index 000000000..4fb9cf271
--- /dev/null
+++ b/lib/plugins/usermanager/lang/no/add.txt
@@ -0,0 +1 @@
+===== Legg til bruker ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/no/delete.txt b/lib/plugins/usermanager/lang/no/delete.txt
new file mode 100644
index 000000000..55010182f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/no/delete.txt
@@ -0,0 +1 @@
+===== Slett bruker ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/no/edit.txt b/lib/plugins/usermanager/lang/no/edit.txt
new file mode 100644
index 000000000..3dff0c92e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/no/edit.txt
@@ -0,0 +1 @@
+===== Rediger bruker ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/no/intro.txt b/lib/plugins/usermanager/lang/no/intro.txt
new file mode 100644
index 000000000..c9e1e5b8c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/no/intro.txt
@@ -0,0 +1 @@
+===== Behandle brukere ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/no/lang.php b/lib/plugins/usermanager/lang/no/lang.php
new file mode 100644
index 000000000..7124e4811
--- /dev/null
+++ b/lib/plugins/usermanager/lang/no/lang.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Norwegianlanguage file
+ *
+ * @author Thomas Nygreen <nygreen@gmail.com>
+ * @author Arild Burud <arildb@met.no>
+ * @author Torkill Bruland <torkar-b@online.no>
+ * @author Rune M. Andersen <rune.andersen@gmail.com>
+ * @author Jakob Vad Nielsen (me@jakobnielsen.net)
+ * @author Kjell Tore Næsgaard <kjell.t.nasgaard@ntnu.no>
+ * @author Knut Staring <knutst@gmail.com>
+ * @author Lisa Ditlefsen <lisa@vervesearch.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author Rune Rasmussen syntaxerror.no@gmail.com
+ * @author Jon Bøe <jonmagneboe@hotmail.com>
+ * @author Egil Hansen <egil@rosetta.no>
+ */
+$lang['menu'] = 'Behandle brukere';
+$lang['noauth'] = '(autentisering av brukere ikke tilgjengelig)';
+$lang['nosupport'] = '(behandling av brukere støttes ikke)';
+$lang['badauth'] = 'ugyldig autentiseringsmekanisme';
+$lang['user_id'] = 'Bruker';
+$lang['user_pass'] = 'Passord';
+$lang['user_name'] = 'Fullt navn';
+$lang['user_mail'] = 'E-post';
+$lang['user_groups'] = 'Grupper';
+$lang['field'] = 'Felt';
+$lang['value'] = 'Verdi';
+$lang['add'] = 'Legg til';
+$lang['delete'] = 'Slett';
+$lang['delete_selected'] = 'Slett valgte';
+$lang['edit'] = 'Rediger';
+$lang['edit_prompt'] = 'Rediger denne brukeren';
+$lang['modify'] = 'Lagre endringer';
+$lang['search'] = 'Søk';
+$lang['search_prompt'] = 'Start søk';
+$lang['clear'] = 'Tilbakestill søkefilter';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Viser brukere %1$d-%2$d av %3$d. %4$d users total.';
+$lang['nonefound'] = 'Ingen brukere funnet. %d brukere totalt.';
+$lang['delete_ok'] = '%d brukere slettet.';
+$lang['delete_fail'] = '%d kunne ikke slettes.';
+$lang['update_ok'] = 'Brukeren ble oppdatert';
+$lang['update_fail'] = 'Oppdatering av brukeren feilet';
+$lang['update_exists'] = 'Endring av brukernavn feilet. Det oppgitte brukernavnet (%s) eksisterer allerede (alle andre endringer vil bli gjort).';
+$lang['start'] = 'første';
+$lang['prev'] = 'forrige';
+$lang['next'] = 'neste';
+$lang['last'] = 'siste';
+$lang['edit_usermissing'] = 'Fant ikke valgte brukere. Det oppgitte brukernavnet kan ha blitt slettet eller endret et annet sted.';
+$lang['user_notify'] = 'Varsle bruker';
+$lang['note_notify'] = 'E-post med varsling blir bare sendt hvis brukeren blir gitt nytt passord.';
+$lang['note_group'] = 'Nye brukere vil bli lagt til standardgruppen (%s) hvis ingen gruppe oppgis.';
+$lang['note_pass'] = 'Passordet vil bli autogenerert dersom feltet er tomt og varsle bruker er valgt.';
+$lang['add_ok'] = 'Brukeren ble lagt til';
+$lang['add_fail'] = 'Brukeren kunne ikke legges til';
+$lang['notify_ok'] = 'Varsling sendt';
+$lang['notify_fail'] = 'Varsling kunne ikke sendes';
diff --git a/lib/plugins/usermanager/lang/no/list.txt b/lib/plugins/usermanager/lang/no/list.txt
new file mode 100644
index 000000000..40de64b01
--- /dev/null
+++ b/lib/plugins/usermanager/lang/no/list.txt
@@ -0,0 +1 @@
+===== Brukerliste ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pl/add.txt b/lib/plugins/usermanager/lang/pl/add.txt
new file mode 100644
index 000000000..a33f3baa7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pl/add.txt
@@ -0,0 +1 @@
+===== Dodawanie użytkownika =====
diff --git a/lib/plugins/usermanager/lang/pl/delete.txt b/lib/plugins/usermanager/lang/pl/delete.txt
new file mode 100644
index 000000000..72dd338f3
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pl/delete.txt
@@ -0,0 +1 @@
+===== Usuwanie użytkownika =====
diff --git a/lib/plugins/usermanager/lang/pl/edit.txt b/lib/plugins/usermanager/lang/pl/edit.txt
new file mode 100644
index 000000000..3c9d89835
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pl/edit.txt
@@ -0,0 +1 @@
+===== Edycja użytkownika =====
diff --git a/lib/plugins/usermanager/lang/pl/intro.txt b/lib/plugins/usermanager/lang/pl/intro.txt
new file mode 100644
index 000000000..da1cfeac0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pl/intro.txt
@@ -0,0 +1 @@
+====== Menadżer użytkowników ======
diff --git a/lib/plugins/usermanager/lang/pl/lang.php b/lib/plugins/usermanager/lang/pl/lang.php
new file mode 100644
index 000000000..5bbf84370
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pl/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * polish language file
+ *
+ * @author Grzegorz Żur <grzegorz.zur@gmail.com>
+ * @author Mariusz Kujawski <marinespl@gmail.com>
+ * @author Maciej Kurczewski <pipijajko@gmail.com>
+ * @author Sławomir Boczek <slawkens@gmail.com>
+ * @author sleshek@wp.pl
+ * @author Leszek Stachowski <shazarre@gmail.com>
+ * @author maros <dobrimaros@yahoo.pl>
+ * @author Grzegorz Widła <dzesdzes@gmail.com>
+ * @author Łukasz Chmaj <teachmeter@gmail.com>
+ * @author Begina Felicysym <begina.felicysym@wp.eu>
+ */
+$lang['menu'] = 'Menadżer użytkowników';
+$lang['noauth'] = '(uwierzytelnienie użytkownika niemożliwe)';
+$lang['nosupport'] = '(zarządzanie użytkownikami niemożliwe)';
+$lang['badauth'] = 'błędny mechanizm uwierzytelniania';
+$lang['user_id'] = 'Nazwa użytkownika';
+$lang['user_pass'] = 'Hasło';
+$lang['user_name'] = 'Użytkownik';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Grupy';
+$lang['field'] = 'Pole';
+$lang['value'] = 'Wartość';
+$lang['add'] = 'Dodaj';
+$lang['delete'] = 'Usuń';
+$lang['delete_selected'] = 'Usuń zaznaczone';
+$lang['edit'] = 'Edytuj';
+$lang['edit_prompt'] = 'Edytuj użytkownika';
+$lang['modify'] = 'Zapisz zmiany';
+$lang['search'] = 'Szukaj';
+$lang['search_prompt'] = 'Rozpocznij przeszukiwanie';
+$lang['clear'] = 'Resetuj filtr przeszukiwania';
+$lang['filter'] = 'Filtr';
+$lang['summary'] = 'Użytkownicy %1$d-%2$d z %3$d znalezionych. Całkowita ilość użytkowników %4$d.';
+$lang['nonefound'] = 'Nie znaleziono użytkowników. Całkowita ilość użytkowników %d.';
+$lang['delete_ok'] = 'Usunięto %d użytkowników.';
+$lang['delete_fail'] = 'Błąd przy usuwaniu %d użytkowników.';
+$lang['update_ok'] = 'Dane użytkownika zostały zmienione!';
+$lang['update_fail'] = 'Błąd przy zmianie danych użytkownika!';
+$lang['update_exists'] = 'Błąd przy zmianie nazwy użytkownika, użytkownik o tej nazwie (%s) już istnieje (inne zmiany zostały wprowadzone).';
+$lang['start'] = 'początek';
+$lang['prev'] = 'poprzedni';
+$lang['next'] = 'następny';
+$lang['last'] = 'ostatni';
+$lang['edit_usermissing'] = 'Nie znaleziono wybranego użytkownika, nazwa użytkownika mogła zostać zmieniona lub usunięta.';
+$lang['user_notify'] = 'Powiadamianie użytkownika';
+$lang['note_notify'] = 'Powiadomienia wysyłane są tylko jeżeli zmieniono hasło użytkownika.';
+$lang['note_group'] = 'Nowy użytkownik zostanie dodany do grupy domyślnej (%s) jeśli nie podano innej grupy.';
+$lang['note_pass'] = 'Jeśli pole będzie puste i powiadamianie użytkownika jest włączone, hasło zostanie automatyczne wygenerowane.';
+$lang['add_ok'] = 'Dodano użytkownika';
+$lang['add_fail'] = 'Dodawanie użytkownika nie powiodło się';
+$lang['notify_ok'] = 'Powiadomienie zostało wysłane';
+$lang['notify_fail'] = 'Wysyłanie powiadomienia nie powiodło się';
diff --git a/lib/plugins/usermanager/lang/pl/list.txt b/lib/plugins/usermanager/lang/pl/list.txt
new file mode 100644
index 000000000..57da2e605
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pl/list.txt
@@ -0,0 +1 @@
+===== Lista użytkowników =====
diff --git a/lib/plugins/usermanager/lang/pt-br/add.txt b/lib/plugins/usermanager/lang/pt-br/add.txt
new file mode 100644
index 000000000..759ed688b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt-br/add.txt
@@ -0,0 +1 @@
+===== Adicionar usuário ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt-br/delete.txt b/lib/plugins/usermanager/lang/pt-br/delete.txt
new file mode 100644
index 000000000..9d18d58ff
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt-br/delete.txt
@@ -0,0 +1 @@
+===== Excluir usuário ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt-br/edit.txt b/lib/plugins/usermanager/lang/pt-br/edit.txt
new file mode 100644
index 000000000..a1be1c8b7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt-br/edit.txt
@@ -0,0 +1 @@
+===== Editar usuário ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt-br/intro.txt b/lib/plugins/usermanager/lang/pt-br/intro.txt
new file mode 100644
index 000000000..5f3399653
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt-br/intro.txt
@@ -0,0 +1 @@
+====== Gerenciamento de Usuários ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt-br/lang.php b/lib/plugins/usermanager/lang/pt-br/lang.php
new file mode 100644
index 000000000..285231f35
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt-br/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Lucien Raven <lucienraven@yahoo.com.br>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Flávio Veras <flaviove@gmail.com>
+ * @author Jeferson Propheta <jeferson.propheta@gmail.com>
+ * @author jair.henrique@gmail.com
+ * @author Luis Dantas <luis@dantas.com>
+ * @author Frederico Guimarães <frederico@teia.bio.br>
+ * @author Jair Henrique <jair.henrique@gmail.com>
+ * @author Luis Dantas <luisdantas@gmail.com>
+ * @author Sergio Motta sergio@cisne.com.br
+ * @author Isaias Masiero Filho <masiero@masiero.org>
+ * @author Balaco Baco <balacobaco@imap.cc>
+ */
+$lang['menu'] = 'Gerenciamento de Usuários';
+$lang['noauth'] = '(o gerenciamento de usuários não está disponível)';
+$lang['nosupport'] = '(o gerenciamento de usuários não é suportado)';
+$lang['badauth'] = 'mecanismo de autenticação inválido';
+$lang['user_id'] = 'Usuário';
+$lang['user_pass'] = 'Senha';
+$lang['user_name'] = 'Nome real';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Grupos';
+$lang['field'] = 'Campo';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Adicionar';
+$lang['delete'] = 'Excluir';
+$lang['delete_selected'] = 'Excluir a seleção';
+$lang['edit'] = 'Editar';
+$lang['edit_prompt'] = 'Editar esse usuário';
+$lang['modify'] = 'Salvar as alterações';
+$lang['search'] = 'Pesquisar';
+$lang['search_prompt'] = 'Executar a pesquisa';
+$lang['clear'] = 'Limpar o filtro de pesquisa';
+$lang['filter'] = 'Filtro';
+$lang['summary'] = 'Exibindo usuários %1$d-%2$d de %3$d encontrados. %4$d usuários no total.';
+$lang['nonefound'] = 'Nenhum usuário encontrado. %d usuários no total.';
+$lang['delete_ok'] = '%d usuários excluídos';
+$lang['delete_fail'] = 'Erro na exclusão de %d usuários.';
+$lang['update_ok'] = 'Usuário atualizado com sucesso';
+$lang['update_fail'] = 'Não foi possível atualizar o usuário';
+$lang['update_exists'] = 'Não foi possível mudar o nome do usuário. O nome especificado (%s) já existe (as outras mudanças serão aplicadas).';
+$lang['start'] = 'primeira';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'próxima';
+$lang['last'] = 'última';
+$lang['edit_usermissing'] = 'O usuário selecionado não foi encontrado, ele foi excluído ou teve o seu nome modificado.';
+$lang['user_notify'] = 'Notificar o usuário';
+$lang['note_notify'] = 'E-mails de notificação são enviados apenas se o usuário digitar uma nova senha.';
+$lang['note_group'] = 'Novos usuários serão adicionados ao grupo padrão (%s), caso nenhum grupo seja especificado.';
+$lang['note_pass'] = 'A senha será gerada automaticamente se o campo for deixado em branco e a notificação de usuário estiver habilitada.';
+$lang['add_ok'] = 'O usuário foi adicionado com sucesso';
+$lang['add_fail'] = 'O usuário não foi adicionado';
+$lang['notify_ok'] = 'O e-mail de notificação foi enviado';
+$lang['notify_fail'] = 'Não foi possível enviar o e-mail de notificação';
diff --git a/lib/plugins/usermanager/lang/pt-br/list.txt b/lib/plugins/usermanager/lang/pt-br/list.txt
new file mode 100644
index 000000000..e5f79fb8d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt-br/list.txt
@@ -0,0 +1 @@
+===== Lista de usuários ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt/add.txt b/lib/plugins/usermanager/lang/pt/add.txt
new file mode 100644
index 000000000..a4c2672c7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt/add.txt
@@ -0,0 +1 @@
+===== Adicionar Utilizador ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt/delete.txt b/lib/plugins/usermanager/lang/pt/delete.txt
new file mode 100644
index 000000000..95bffc1e3
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt/delete.txt
@@ -0,0 +1 @@
+===== Remover Utilizador ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt/edit.txt b/lib/plugins/usermanager/lang/pt/edit.txt
new file mode 100644
index 000000000..176798454
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt/edit.txt
@@ -0,0 +1 @@
+===== Editar Utilizador ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt/intro.txt b/lib/plugins/usermanager/lang/pt/intro.txt
new file mode 100644
index 000000000..27985ded6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt/intro.txt
@@ -0,0 +1 @@
+===== Gerir Utilizadores ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt/lang.php b/lib/plugins/usermanager/lang/pt/lang.php
new file mode 100644
index 000000000..6d0d85e38
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt/lang.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Portugueselanguage file
+ *
+ * @author José Monteiro <Jose.Monteiro@DoWeDo-IT.com>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Fil <fil@meteopt.com>
+ * @author André Neves <drakferion@gmail.com>
+ * @author José Campos zecarlosdecampos@gmail.com
+ */
+$lang['menu'] = 'Gestor de Perfis';
+$lang['noauth'] = '(autenticação indisponível)';
+$lang['nosupport'] = '(gestão de utilizadores não suportada)';
+$lang['badauth'] = 'Mecanismo de autenticação inválido';
+$lang['user_id'] = 'Utilizador';
+$lang['user_pass'] = 'Senha';
+$lang['user_name'] = 'Nome Real';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Grupos';
+$lang['field'] = 'Campo';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Adicionar';
+$lang['delete'] = 'Remover';
+$lang['delete_selected'] = 'Remover Seleccionado(s)';
+$lang['edit'] = 'Editar';
+$lang['edit_prompt'] = 'Editar utilizador';
+$lang['modify'] = 'Gravar Alterações';
+$lang['search'] = 'Pesquisar';
+$lang['search_prompt'] = 'Pesquisar';
+$lang['clear'] = 'Limpar Filtro de Pesquisa';
+$lang['filter'] = 'Filtro';
+$lang['summary'] = 'Apresentar utilizadores %1$d-%2$d de %3$d encontrados. %4$d inscritos.';
+$lang['nonefound'] = 'Nenhum utilizador encontrado. %d inscritos.';
+$lang['delete_ok'] = '%d utilizadores removidos';
+$lang['delete_fail'] = '%d remoções falhadas.';
+$lang['update_ok'] = 'Utilizador actualizado';
+$lang['update_fail'] = 'Utilizador não actualizado';
+$lang['update_exists'] = 'Falhou a alteração do nome, porque o utilizador (%s) já existe (as restantes alterações serão aplicadas).';
+$lang['start'] = 'primeiro';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'seguinte';
+$lang['last'] = 'último';
+$lang['edit_usermissing'] = 'Utilizador seleccionado não encontrado. Terá já sido removido ou alterado entretanto?';
+$lang['user_notify'] = 'Notificar utilizador';
+$lang['note_notify'] = 'Notificações só são enviadas se for atribuída uma nova senha ao utilizador.';
+$lang['note_group'] = 'Os novos utilizadores são adicionados ao grupo por omissão (%s) se não for especificado nenhum grupo.';
+$lang['note_pass'] = 'A password será automáticamente gerada se o campo esquerdo estiver vazio e a notificação de utilizador estiver activada.';
+$lang['add_ok'] = 'Utilizador adicionado.';
+$lang['add_fail'] = 'Utilizador não adicionado.';
+$lang['notify_ok'] = 'Mensagem de notificação enviada.';
+$lang['notify_fail'] = 'Não foi possível enviar mensagem de notificação';
diff --git a/lib/plugins/usermanager/lang/pt/list.txt b/lib/plugins/usermanager/lang/pt/list.txt
new file mode 100644
index 000000000..01a0460aa
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt/list.txt
@@ -0,0 +1 @@
+===== Lista de Utilizadores ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ro/add.txt b/lib/plugins/usermanager/lang/ro/add.txt
new file mode 100644
index 000000000..9a5c45eef
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ro/add.txt
@@ -0,0 +1 @@
+===== Adaugă utilizator ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ro/delete.txt b/lib/plugins/usermanager/lang/ro/delete.txt
new file mode 100644
index 000000000..ea65fa984
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ro/delete.txt
@@ -0,0 +1 @@
+===== Şterge utilizator ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ro/edit.txt b/lib/plugins/usermanager/lang/ro/edit.txt
new file mode 100644
index 000000000..b7f8a4213
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ro/edit.txt
@@ -0,0 +1 @@
+===== Editează utilizator ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ro/intro.txt b/lib/plugins/usermanager/lang/ro/intro.txt
new file mode 100644
index 000000000..f3c66266d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ro/intro.txt
@@ -0,0 +1 @@
+===== Manager Utilizatori ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ro/lang.php b/lib/plugins/usermanager/lang/ro/lang.php
new file mode 100644
index 000000000..b8c1f24fc
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ro/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Romanian language file
+ *
+ * @author Sergiu Baltariu <s_baltariu@yahoo.com>
+ * @author s_baltariu@yahoo.com
+ * @author Emanuel-Emeric Andrasi <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrași <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andraşi <em.andrasi@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrasi <em.andrasi@mandrivausers.ro>
+ * @author Marius OLAR <olarmariusalex@gmail.com>
+ * @author Emanuel-Emeric Andrași <em.andrasi@mandrivausers.ro>
+ */
+$lang['menu'] = 'Manager Utilizatori';
+$lang['noauth'] = '(autentificarea utilizatorilor nu este disponibilă)';
+$lang['nosupport'] = '(menegementul utilizatorilor nu e suportat)';
+$lang['badauth'] = 'mecanism de autentificare invalid';
+$lang['user_id'] = 'Utilizator';
+$lang['user_pass'] = 'Parolă';
+$lang['user_name'] = 'Nume Real';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Grupuri';
+$lang['field'] = 'Câmp';
+$lang['value'] = 'Valoare';
+$lang['add'] = 'Adaugă';
+$lang['delete'] = 'Şterge';
+$lang['delete_selected'] = 'Şterge selecţia';
+$lang['edit'] = 'Editează';
+$lang['edit_prompt'] = 'Editează acest utilizator';
+$lang['modify'] = 'Salvează Modificările';
+$lang['search'] = 'Caută';
+$lang['search_prompt'] = 'Se caută';
+$lang['clear'] = 'Resetează Filtrul de Căutare';
+$lang['filter'] = 'Filtru';
+$lang['summary'] = 'Afişarea utilizatorilor %1$d-%2$d din %3$d găsită. %4$d utilizatori în total.';
+$lang['nonefound'] = 'Nici un utilizator nu a fost găsit. %d utilizatori în total.';
+$lang['delete_ok'] = '%d utilizatori şterşi';
+$lang['delete_fail'] = '%d eşuat la ştergere.';
+$lang['update_ok'] = 'Utilizatorul a fost actualizat cu succes';
+$lang['update_fail'] = 'Actualizarea utilizatorului a eşuat';
+$lang['update_exists'] = 'Modificarea numelui de utilizator a eşuat. Numele de utilizator specificat (%s) există deja (orice altă modificare se va aplica)';
+$lang['start'] = 'început';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'urmator';
+$lang['last'] = 'sfârşit';
+$lang['edit_usermissing'] = 'Utilizatorul selectat nu a fost găsit. E posibil ca numele de utilizator specificat să fi fost şters sau modificat în altă parte.';
+$lang['user_notify'] = 'Notificare utilizator';
+$lang['note_notify'] = 'Emailurile de notificare sunt trimise numai dacă utilizatorului îi este dată o nouă parolă.';
+$lang['note_group'] = 'Noii utilizatori vor fi adăugaţi la grupul implicit (%s) dacă nu se specifică grupul.';
+$lang['note_pass'] = 'Parola va fi regenerată automat dacă câmpul este lăsat gol şi notificarea utilizatorului este activată.';
+$lang['add_ok'] = 'Utilizator adăugat cu succes';
+$lang['add_fail'] = 'Adăugarea utilizatorului a eşuat';
+$lang['notify_ok'] = 'Emailul de notificare a fost trimis';
+$lang['notify_fail'] = 'Emailul de notificare nu a putut fi trimis';
diff --git a/lib/plugins/usermanager/lang/ro/list.txt b/lib/plugins/usermanager/lang/ro/list.txt
new file mode 100644
index 000000000..6c0563444
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ro/list.txt
@@ -0,0 +1 @@
+===== Listă utilizatori ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ru/add.txt b/lib/plugins/usermanager/lang/ru/add.txt
new file mode 100644
index 000000000..3cb4264e7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ru/add.txt
@@ -0,0 +1 @@
+===== Добавить пользователя =====
diff --git a/lib/plugins/usermanager/lang/ru/delete.txt b/lib/plugins/usermanager/lang/ru/delete.txt
new file mode 100644
index 000000000..80f874e05
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ru/delete.txt
@@ -0,0 +1 @@
+===== Удалить пользователя =====
diff --git a/lib/plugins/usermanager/lang/ru/edit.txt b/lib/plugins/usermanager/lang/ru/edit.txt
new file mode 100644
index 000000000..d447c4005
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ru/edit.txt
@@ -0,0 +1 @@
+===== Редактировать пользователя =====
diff --git a/lib/plugins/usermanager/lang/ru/intro.txt b/lib/plugins/usermanager/lang/ru/intro.txt
new file mode 100644
index 000000000..3a3e2607d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ru/intro.txt
@@ -0,0 +1 @@
+====== Управление пользователями ======
diff --git a/lib/plugins/usermanager/lang/ru/lang.php b/lib/plugins/usermanager/lang/ru/lang.php
new file mode 100644
index 000000000..456ba5b29
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ru/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Russian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Denis Simakov <akinoame1@gmail.com>
+ * @author Andrew Pleshakov <beotiger@mail.ru>
+ * @author Змей Этерийский evil_snake@eternion.ru
+ * @author Hikaru Nakajima <jisatsu@mail.ru>
+ * @author Alexei Tereschenko <alexeitlex@yahoo.com>
+ * @author Irina Ponomareva irinaponomareva@webperfectionist.com
+ * @author Alexander Sorkin <kibizoid@gmail.com>
+ * @author Kirill Krasnov <krasnovforum@gmail.com>
+ * @author Vlad Tsybenko <vlad.development@gmail.com>
+ * @author Aleksey Osadchiy <rfc@nm.ru>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Ladyko Andrey <fylh@succexy.spb.ru>
+ * @author Eugene <windy.wanderer@gmail.com>
+ */
+$lang['menu'] = 'Управление пользователями';
+$lang['noauth'] = '(авторизация пользователей недоступна)';
+$lang['nosupport'] = '(управление пользователями не поддерживается)';
+$lang['badauth'] = 'некорректный механизм аутентификации';
+$lang['user_id'] = 'Логин';
+$lang['user_pass'] = 'Пароль';
+$lang['user_name'] = 'Полное имя';
+$lang['user_mail'] = 'Эл. адрес';
+$lang['user_groups'] = 'Группы';
+$lang['field'] = 'Поле';
+$lang['value'] = 'Значение';
+$lang['add'] = 'Добавить';
+$lang['delete'] = 'Удалить';
+$lang['delete_selected'] = 'Удалить выбранные';
+$lang['edit'] = 'Редактировать';
+$lang['edit_prompt'] = 'Редактировать этого пользователя';
+$lang['modify'] = 'Сохранить изменения';
+$lang['search'] = 'Поиск';
+$lang['search_prompt'] = 'Искать';
+$lang['clear'] = 'Сброс фильтра поиска';
+$lang['filter'] = 'Фильтр';
+$lang['summary'] = 'Показаны пользователи %1$d-%2$d из %3$d найденных. Всего пользователей: %4$d.';
+$lang['nonefound'] = 'Не найдено ни одного пользователя. Всего пользователей: %d.';
+$lang['delete_ok'] = 'Удалено пользователей: %d';
+$lang['delete_fail'] = 'Не удалось удалить %d.';
+$lang['update_ok'] = 'Пользователь успешно обновлён';
+$lang['update_fail'] = 'Не удалось обновить пользователя';
+$lang['update_exists'] = 'Не удалось изменить имя пользователя, такой пользователь (%s) уже существует (все остальные изменения будут применены).';
+$lang['start'] = 'в начало';
+$lang['prev'] = 'назад';
+$lang['next'] = 'вперёд';
+$lang['last'] = 'в конец';
+$lang['edit_usermissing'] = 'Выбранный пользователь не найден. Возможно, указанный логин был удалён или изменён извне.';
+$lang['user_notify'] = 'Сообщить пользователю';
+$lang['note_notify'] = 'Письма с уведомлением высылаются только в случае получения нового пароля.';
+$lang['note_group'] = 'Если группа не указана, новые пользователи будут добавлены в группу по умолчанию (%s).';
+$lang['note_pass'] = 'Пароль будет сгенерирован автоматически, если поле оставлено пустым и включено уведомление пользователя.';
+$lang['add_ok'] = 'Пользователь успешно добавлен';
+$lang['add_fail'] = 'Не удалось добавить пользователя';
+$lang['notify_ok'] = 'Письмо с уведомлением отправлено';
+$lang['notify_fail'] = 'Не удалось отправить письмо с уведомлением';
diff --git a/lib/plugins/usermanager/lang/ru/list.txt b/lib/plugins/usermanager/lang/ru/list.txt
new file mode 100644
index 000000000..26c0cbead
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ru/list.txt
@@ -0,0 +1 @@
+===== Список пользователей =====
diff --git a/lib/plugins/usermanager/lang/sk/add.txt b/lib/plugins/usermanager/lang/sk/add.txt
new file mode 100644
index 000000000..e2e106089
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sk/add.txt
@@ -0,0 +1,2 @@
+===== Pridanie užívateľa =====
+
diff --git a/lib/plugins/usermanager/lang/sk/delete.txt b/lib/plugins/usermanager/lang/sk/delete.txt
new file mode 100644
index 000000000..c7d6a3cc2
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sk/delete.txt
@@ -0,0 +1,2 @@
+===== Zmazanie užívateľa =====
+
diff --git a/lib/plugins/usermanager/lang/sk/edit.txt b/lib/plugins/usermanager/lang/sk/edit.txt
new file mode 100644
index 000000000..28af5b53c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sk/edit.txt
@@ -0,0 +1,2 @@
+===== Zmena užívateľa =====
+
diff --git a/lib/plugins/usermanager/lang/sk/intro.txt b/lib/plugins/usermanager/lang/sk/intro.txt
new file mode 100644
index 000000000..0a626de52
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sk/intro.txt
@@ -0,0 +1,2 @@
+====== Správa používateľov ======
+
diff --git a/lib/plugins/usermanager/lang/sk/lang.php b/lib/plugins/usermanager/lang/sk/lang.php
new file mode 100644
index 000000000..54ed374c6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sk/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Slovak language file
+ *
+ * @author Ondrej Végh <ov@vsieti.sk>
+ * @author Michal Mesko <michal.mesko@gmail.com>
+ * @author exusik@gmail.com
+ * @author Martin Michalek <michalek.dev@gmail.com>
+ */
+$lang['menu'] = 'Správa používateľov';
+$lang['noauth'] = '(autentifikácia užívateľov nie je dostupná)';
+$lang['nosupport'] = '(správa užívateľov nie je podporovaná)';
+$lang['badauth'] = 'neplatný autorizačný mechanizmus';
+$lang['user_id'] = 'Užívateľ';
+$lang['user_pass'] = 'Heslo';
+$lang['user_name'] = 'Skutočné meno';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Skupiny';
+$lang['field'] = 'Pole';
+$lang['value'] = 'Hodnota';
+$lang['add'] = 'Pridať';
+$lang['delete'] = 'Zmazať';
+$lang['delete_selected'] = 'Zmazať vybrané';
+$lang['edit'] = 'Zmeniť';
+$lang['edit_prompt'] = 'Zmeniť tohoto užívateľa';
+$lang['modify'] = 'Uložiť zmeny';
+$lang['search'] = 'Hľadať';
+$lang['search_prompt'] = 'Vykonať vyhľadávanie';
+$lang['clear'] = 'Vynulovať vyhľadávací filter';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Zobrazenie užívateľov %1$d-%2$d z %3$d nájdených. %4$d užívateľov celkom.';
+$lang['nonefound'] = 'Žiadni užívatelia nenájdení. %d užívateľov celkom.';
+$lang['delete_ok'] = '%d užívateľov zmazaných';
+$lang['delete_fail'] = '%d chýb vymazania.';
+$lang['update_ok'] = 'Užívateľ úspešne zmenený';
+$lang['update_fail'] = 'Chyba zmeny užívateľa';
+$lang['update_exists'] = 'Chyba zmeny užívateľa, užívateľské meno (%s) už existuje (iné zmeny budú zaznamenané).';
+$lang['start'] = 'prvé';
+$lang['prev'] = 'predošlé';
+$lang['next'] = 'ďalšie';
+$lang['last'] = 'posledné';
+$lang['edit_usermissing'] = 'Vybraný užívateľ nebol nájdený, mohol byť zmazaný alebo zmenený iným spôsobom.';
+$lang['user_notify'] = 'Upozorniť užívateľa';
+$lang['note_notify'] = 'Notifikačné e-maily iba vtedy, ak dostane užívateľ nové heslo';
+$lang['note_group'] = 'Noví užívatelia budú pridaní do východzej skupiny (%s), ak nie je pre nich špecifikovaná iná skupina.';
+$lang['note_pass'] = 'Heslo bude vygenerované automaticky, ak bude pole prázdne a je zapnutá notifikácia používateľa.';
+$lang['add_ok'] = 'Používateľ úspešne pridaný';
+$lang['add_fail'] = 'Pridávanie užívateľa nebolo úspešné';
+$lang['notify_ok'] = 'Notifikačný e-mail bol poslaný';
+$lang['notify_fail'] = 'Notifikačný e-mail nemohol byť poslaný';
diff --git a/lib/plugins/usermanager/lang/sk/list.txt b/lib/plugins/usermanager/lang/sk/list.txt
new file mode 100644
index 000000000..6f15331e9
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sk/list.txt
@@ -0,0 +1,2 @@
+===== Zoznam užívateľov =====
+
diff --git a/lib/plugins/usermanager/lang/sl/add.txt b/lib/plugins/usermanager/lang/sl/add.txt
new file mode 100644
index 000000000..c1d8913b4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sl/add.txt
@@ -0,0 +1 @@
+===== Dodajanje uporabnika ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sl/delete.txt b/lib/plugins/usermanager/lang/sl/delete.txt
new file mode 100644
index 000000000..1fd4fffe1
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sl/delete.txt
@@ -0,0 +1 @@
+===== Izbris uporabnika ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sl/edit.txt b/lib/plugins/usermanager/lang/sl/edit.txt
new file mode 100644
index 000000000..e80bc8585
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sl/edit.txt
@@ -0,0 +1 @@
+===== Urejanje uporabnikov ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sl/intro.txt b/lib/plugins/usermanager/lang/sl/intro.txt
new file mode 100644
index 000000000..a4729a8a5
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sl/intro.txt
@@ -0,0 +1 @@
+====== Upravljanje uporabnikov ======
diff --git a/lib/plugins/usermanager/lang/sl/lang.php b/lib/plugins/usermanager/lang/sl/lang.php
new file mode 100644
index 000000000..96acfd0af
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sl/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Slovenian language file
+ *
+ * @author Dejan Levec <webphp@gmail.com>
+ * @author Boštjan Seničar <senicar@gmail.com>
+ * @author Gregor Skumavc (grega.skumavc@gmail.com)
+ * @author Matej Urbančič (mateju@svn.gnome.org)
+ */
+$lang['menu'] = 'Upravljanje uporabnikov';
+$lang['noauth'] = '(overjanje istovetnosti uporabnikov ni na voljo)';
+$lang['nosupport'] = '(upravljanje računov uporabnikov ni podprto)';
+$lang['badauth'] = 'neveljaven način overjanja';
+$lang['user_id'] = 'Uporabnik';
+$lang['user_pass'] = 'Geslo';
+$lang['user_name'] = 'Pravo ime';
+$lang['user_mail'] = 'Elektronski naslov';
+$lang['user_groups'] = 'Skupine';
+$lang['field'] = 'Polje';
+$lang['value'] = 'Vrednost';
+$lang['add'] = 'Dodaj';
+$lang['delete'] = 'Izbriši';
+$lang['delete_selected'] = 'Izbriši izbrano';
+$lang['edit'] = 'Uredi';
+$lang['edit_prompt'] = 'Uredi tega uporabnika';
+$lang['modify'] = 'Shrani spremembe';
+$lang['search'] = 'Iskanje';
+$lang['search_prompt'] = 'Poišči';
+$lang['clear'] = 'Počisti filter iskanja';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Izpisani so uporabniki %1$d-%2$d od skupno %3$d. Vseh uporabnikov je %4$d.';
+$lang['nonefound'] = 'Ni najdenih uporabnikov. Vseh uporabnikov je %d.';
+$lang['delete_ok'] = '%d uporabnikov je izbrisanih';
+$lang['delete_fail'] = '%d ni bilo mogoče izbrisati';
+$lang['update_ok'] = 'Uporabniški račun je uspešno posodobljen';
+$lang['update_fail'] = 'Posodobitev uporabniškega računa je spodletela';
+$lang['update_exists'] = 'Spreminjanje imena uporabnika je spodletelo. Navedeno uporabniško ime (%s) že obstaja (vse ostale spremembe bodo uveljavljene).';
+$lang['start'] = 'Začetni';
+$lang['prev'] = 'Predhodni';
+$lang['next'] = 'Naslednji';
+$lang['last'] = 'Končni';
+$lang['edit_usermissing'] = 'Izbranega uporabnika ni mogoče najti. Navedeno uporabniško ime je morda izbrisano ali spremenjeno.';
+$lang['user_notify'] = 'Obvesti uporabnika';
+$lang['note_notify'] = 'Obvestilna sporočila so poslana le, če uporabnik prejme novo geslo za dostop do strani.';
+$lang['note_group'] = 'Nov uporabnik bo dodan k privzeti skupini (%s), v kolikor ni navedene druge skupine.';
+$lang['note_pass'] = 'Geslo bo ustvarjeno samodejno, v kolikor je polje izpuščeno in je omogočeno obveščanje uporabnika.';
+$lang['add_ok'] = 'Uporabnik je uspešno dodan';
+$lang['add_fail'] = 'Dodajanje uporabnika je spodletelo';
+$lang['notify_ok'] = 'Obvestilno sporočilo je poslano.';
+$lang['notify_fail'] = 'Obvestilnega sporočila ni mogoče poslati.';
diff --git a/lib/plugins/usermanager/lang/sl/list.txt b/lib/plugins/usermanager/lang/sl/list.txt
new file mode 100644
index 000000000..1aa8b7a7c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sl/list.txt
@@ -0,0 +1 @@
+===== Seznam uporabnikov ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sq/add.txt b/lib/plugins/usermanager/lang/sq/add.txt
new file mode 100644
index 000000000..4c66aaf3e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sq/add.txt
@@ -0,0 +1 @@
+===== Shto Përdorues ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sq/delete.txt b/lib/plugins/usermanager/lang/sq/delete.txt
new file mode 100644
index 000000000..34cb49173
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sq/delete.txt
@@ -0,0 +1 @@
+===== Fshi përdorues ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sq/edit.txt b/lib/plugins/usermanager/lang/sq/edit.txt
new file mode 100644
index 000000000..63131038f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sq/edit.txt
@@ -0,0 +1 @@
+===== Redakto Përdorues ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sq/intro.txt b/lib/plugins/usermanager/lang/sq/intro.txt
new file mode 100644
index 000000000..e1ebea60c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sq/intro.txt
@@ -0,0 +1 @@
+===== Menaxhuesi i Përdoruesit ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sq/lang.php b/lib/plugins/usermanager/lang/sq/lang.php
new file mode 100644
index 000000000..bddf54d5b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sq/lang.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Albanian language file
+ *
+ * @author Leonard Elezi leonard.elezi@depinfo.info
+ */
+$lang['menu'] = 'Menaxhuesi Përdoruesve';
+$lang['noauth'] = '(autentikimi i përdoruesve nuk është i disponueshëm)';
+$lang['nosupport'] = '(menaxhimi i përdoruesve nuk suportohet)';
+$lang['badauth'] = '(mekanizëm i pavlefshëm autentikimi)';
+$lang['user_id'] = 'Përdoruesi';
+$lang['user_pass'] = 'Fjalëkalimi
+';
+$lang['user_name'] = 'Emri i Vërtetë';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Grupe';
+$lang['field'] = 'Fusha';
+$lang['value'] = 'Vlera';
+$lang['add'] = 'Shto';
+$lang['delete'] = 'Fshi';
+$lang['delete_selected'] = 'Fshi të Përzgjedhurën';
+$lang['edit'] = 'Redakto';
+$lang['edit_prompt'] = 'Redakto këtë përdorues';
+$lang['modify'] = 'Ruaj Ndryshimet';
+$lang['search'] = 'Kërko';
+$lang['search_prompt'] = 'Kryej kërkim';
+$lang['clear'] = 'Rivendos Filter Kërkimi';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Duke treguar përdoruesit %1$d-%2$d nga %3$d të gjetur. %4$d përdorues në total.';
+$lang['nonefound'] = 'Asnjë përdorues nuk u gjet. %d përdorues në total.';
+$lang['delete_ok'] = '%d përdorues u fshinë.';
+$lang['delete_fail'] = '%d dështuan të fshihen.';
+$lang['update_ok'] = 'Përdoruesi u përditësia me sukses.';
+$lang['update_fail'] = 'Përditësimi i përdoruesit dështoi.';
+$lang['update_exists'] = 'Ndryshimi i emrit të përdoruesit dështoi, emri i përdoruesit i specifikuar (%s) ekziston tashmë (çdo ndryshim tjetër do të zbatohet).';
+$lang['start'] = 'Fillim';
+$lang['prev'] = 'Mëpara';
+$lang['next'] = 'Tjetra';
+$lang['last'] = 'Fundi';
+$lang['edit_usermissing'] = 'Përdoruesi i përzgjedhur nuk u gjet, emri i specifikuar i përdoruesit mund të jetë fshirë ose ndryshuar diku tjetër.';
+$lang['user_notify'] = 'Lajmëro përdoruesin';
+$lang['note_notify'] = 'Email-et e lajmërimit dërgohen vetëm nëse përdoruesit i jepet një fjalëkalim i ri.';
+$lang['note_group'] = 'Përdorues të rinj do të shtohen në grupin default (%s) nëse asnjë grup nuk specifikohet.';
+$lang['note_pass'] = 'Fjalëkalimi do të autogjenerohet nëse fusha lihet bosh dhe lajmërimi i përdoruesit është i aktivizuar.';
+$lang['add_ok'] = 'Përdoruesi u shtua me sukses.';
+$lang['add_fail'] = 'Shtimi i përdoruesit dështoi.';
+$lang['notify_ok'] = 'Email-i lajmërimit u dërgua.';
+$lang['notify_fail'] = 'Email-i lajmërimit nuk mundi të dërgohej.';
diff --git a/lib/plugins/usermanager/lang/sq/list.txt b/lib/plugins/usermanager/lang/sq/list.txt
new file mode 100644
index 000000000..68fc2e7c6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sq/list.txt
@@ -0,0 +1 @@
+===== Lista Përdoruesve ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sr/add.txt b/lib/plugins/usermanager/lang/sr/add.txt
new file mode 100644
index 000000000..1de9a50e4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sr/add.txt
@@ -0,0 +1 @@
+===== Додај корисника ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sr/delete.txt b/lib/plugins/usermanager/lang/sr/delete.txt
new file mode 100644
index 000000000..9b50365be
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sr/delete.txt
@@ -0,0 +1 @@
+===== Обриши корисника ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sr/edit.txt b/lib/plugins/usermanager/lang/sr/edit.txt
new file mode 100644
index 000000000..11e22e2f5
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sr/edit.txt
@@ -0,0 +1 @@
+===== Измени корисника ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sr/intro.txt b/lib/plugins/usermanager/lang/sr/intro.txt
new file mode 100644
index 000000000..6c6ac9a5c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sr/intro.txt
@@ -0,0 +1 @@
+====== Управљач корисницима ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sr/lang.php b/lib/plugins/usermanager/lang/sr/lang.php
new file mode 100644
index 000000000..5f2669b58
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sr/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Serbian language file
+ *
+ * @author Иван Петровић petrovicivan@ubuntusrbija.org
+ * @author Ivan Petrovic <petrovicivan@ubuntusrbija.org>
+ * @author Miroslav Šolti <solti.miroslav@gmail.com>
+ */
+$lang['menu'] = 'Управљач корисницима';
+$lang['noauth'] = '(корисничка провера није доступна)';
+$lang['nosupport'] = '(уптављање корисницима није подржано)';
+$lang['badauth'] = 'неисправан механизам провере';
+$lang['user_id'] = 'Корисник';
+$lang['user_pass'] = 'Лозинка';
+$lang['user_name'] = 'Име и презиме';
+$lang['user_mail'] = 'Е-адреса';
+$lang['user_groups'] = 'Групе';
+$lang['field'] = 'Поље';
+$lang['value'] = 'Вредност';
+$lang['add'] = 'Додај';
+$lang['delete'] = 'Обриши';
+$lang['delete_selected'] = 'Обриши одабране';
+$lang['edit'] = 'Измени';
+$lang['edit_prompt'] = 'Измени корисника';
+$lang['modify'] = 'Сачувај измене';
+$lang['search'] = 'Претрага';
+$lang['search_prompt'] = 'Изведи претрагу';
+$lang['clear'] = 'Поништи филтер претраге';
+$lang['filter'] = 'Филтер';
+$lang['summary'] = 'Приказ %1$d-%2$d од %3$d пронађена корисника. Укупно има %4$d корисника.';
+$lang['nonefound'] = 'Није пронађен корисник. Укупно има %d корисника.';
+$lang['delete_ok'] = '%d корисника је обрисано';
+$lang['delete_fail'] = '%d брисања није успело.';
+$lang['update_ok'] = 'Кориснички налог је ажуриран';
+$lang['update_fail'] = 'Кориснички налог није ажуриран';
+$lang['update_exists'] = 'Измена корисничког имена није успела, наведени корисник (%s) већ постоји (остале измене ће бити примењене).';
+$lang['start'] = 'почетак';
+$lang['prev'] = 'претходна';
+$lang['next'] = 'следећа';
+$lang['last'] = 'крај';
+$lang['edit_usermissing'] = 'Одабрани корисник не постоји, наведено корисничко име је можда обрисано или је измењено негде другде.';
+$lang['user_notify'] = 'Обавести корисника';
+$lang['note_notify'] = 'Потврдна порука ће бити послата једино ако је кориснику додељена нова лозинка.';
+$lang['note_group'] = 'Нови корисници ће бити додељени подразумеваној групи (%s) ако није другачије назначено.';
+$lang['note_pass'] = 'Ако сте оставили поље празно и укључили обавештавање корисника лозинка ће бити аутоматски генерисана.';
+$lang['add_ok'] = 'Корисник је успешно додат';
+$lang['add_fail'] = 'Додавање корисника није успело';
+$lang['notify_ok'] = 'Порука са обавештењен је послата';
+$lang['notify_fail'] = 'Порука са обавештењен није послата';
diff --git a/lib/plugins/usermanager/lang/sr/list.txt b/lib/plugins/usermanager/lang/sr/list.txt
new file mode 100644
index 000000000..948444245
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sr/list.txt
@@ -0,0 +1 @@
+===== Списак корисника ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sv/add.txt b/lib/plugins/usermanager/lang/sv/add.txt
new file mode 100644
index 000000000..2ff1ee640
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sv/add.txt
@@ -0,0 +1 @@
+===== Lägg till användare =====
diff --git a/lib/plugins/usermanager/lang/sv/delete.txt b/lib/plugins/usermanager/lang/sv/delete.txt
new file mode 100644
index 000000000..5664a5906
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sv/delete.txt
@@ -0,0 +1 @@
+===== Radera användare =====
diff --git a/lib/plugins/usermanager/lang/sv/edit.txt b/lib/plugins/usermanager/lang/sv/edit.txt
new file mode 100644
index 000000000..f1a7f4a22
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sv/edit.txt
@@ -0,0 +1 @@
+===== Redigera användare =====
diff --git a/lib/plugins/usermanager/lang/sv/intro.txt b/lib/plugins/usermanager/lang/sv/intro.txt
new file mode 100644
index 000000000..bd13b8157
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sv/intro.txt
@@ -0,0 +1 @@
+====== Hantera användare ======
diff --git a/lib/plugins/usermanager/lang/sv/lang.php b/lib/plugins/usermanager/lang/sv/lang.php
new file mode 100644
index 000000000..bd747927e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sv/lang.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Swedish language file
+ *
+ * @author Per Foreby <per@foreby.se>
+ * @author Nicklas Henriksson <nicklas[at]nihe.se>
+ * @author Håkan Sandell <hakan.sandell[at]mydata.se>
+ * @author Dennis Karlsson
+ * @author Tormod Otter Johansson <tormod@latast.se>
+ * @author emil@sys.nu
+ * @author Pontus Bergendahl <pontus.bergendahl@gmail.com>
+ * @author Tormod Johansson tormod.otter.johansson@gmail.com
+ * @author Emil Lind <emil@sys.nu>
+ * @author Bogge Bogge <bogge@bogge.com>
+ * @author Peter Åström <eaustreum@gmail.com>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ * @author mikael@mallander.net
+ */
+$lang['menu'] = 'Hantera användare';
+$lang['noauth'] = '(användarautentisering ej tillgänlig)';
+$lang['nosupport'] = '(användarhantering stödjs ej)';
+$lang['badauth'] = 'ogiltig autentiseringsmekanism';
+$lang['user_id'] = 'Användare';
+$lang['user_pass'] = 'Lösenord';
+$lang['user_name'] = 'Namn';
+$lang['user_mail'] = 'E-post';
+$lang['user_groups'] = 'Grupper';
+$lang['field'] = 'Fält';
+$lang['value'] = 'Värde';
+$lang['add'] = 'Lägg till';
+$lang['delete'] = 'Radera';
+$lang['delete_selected'] = 'Radera markerade';
+$lang['edit'] = 'Redigera';
+$lang['edit_prompt'] = 'Redigera användaren';
+$lang['modify'] = 'Spara ändringar';
+$lang['search'] = 'Sök';
+$lang['search_prompt'] = 'Utför sökning';
+$lang['clear'] = 'Återställ sökfilter';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Visar användare %1$d-%2$d av %3$d funna. %4$d användare totalt.';
+$lang['nonefound'] = 'Inga användare hittades. %d användare totalt.';
+$lang['delete_ok'] = '%d användare raderade';
+$lang['delete_fail'] = '%d kunde inte raderas.';
+$lang['update_ok'] = 'Användaren uppdaterad';
+$lang['update_fail'] = 'Användaruppdatering misslyckades';
+$lang['update_exists'] = 'Kunde inte ändra användarnamn,, det angivna användarnamnet (%s) finns redan (andra ändringar kommer att utföras).';
+$lang['start'] = 'start';
+$lang['prev'] = 'föregående';
+$lang['next'] = 'nästa';
+$lang['last'] = 'sista';
+$lang['edit_usermissing'] = 'Vald användare hittades inte. Den angivna användaren kan ha blivit raderad, eller ändrats någon annanstans.';
+$lang['user_notify'] = 'Meddela användaren';
+$lang['note_notify'] = 'E-postmeddelanden skickas bara om användaren har fått ett nytt lösenord.';
+$lang['note_group'] = 'Nya användare läggs till i standardgruppen (%s) om inga grupper anges.';
+$lang['note_pass'] = 'Lösenordet kommer att autogenereras om fältet är tomt och e-postmeddelanden till användaren är påslaget.';
+$lang['add_ok'] = 'Användaren tillagd';
+$lang['add_fail'] = 'Användare kunde inte läggas till';
+$lang['notify_ok'] = 'E-postmeddelande skickat';
+$lang['notify_fail'] = 'E-postmeddelande kunde inte skickas';
diff --git a/lib/plugins/usermanager/lang/sv/list.txt b/lib/plugins/usermanager/lang/sv/list.txt
new file mode 100644
index 000000000..e07c45277
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sv/list.txt
@@ -0,0 +1 @@
+===== Användarlista =====
diff --git a/lib/plugins/usermanager/lang/th/add.txt b/lib/plugins/usermanager/lang/th/add.txt
new file mode 100644
index 000000000..6a5f09855
--- /dev/null
+++ b/lib/plugins/usermanager/lang/th/add.txt
@@ -0,0 +1 @@
+====== เพิ่มผู้ใช้ ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/th/delete.txt b/lib/plugins/usermanager/lang/th/delete.txt
new file mode 100644
index 000000000..4dbc82bf9
--- /dev/null
+++ b/lib/plugins/usermanager/lang/th/delete.txt
@@ -0,0 +1 @@
+====== ลบผู้ใช้ ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/th/edit.txt b/lib/plugins/usermanager/lang/th/edit.txt
new file mode 100644
index 000000000..c36e8ddf8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/th/edit.txt
@@ -0,0 +1 @@
+====== แก้ไขผู้ใช้ ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/th/intro.txt b/lib/plugins/usermanager/lang/th/intro.txt
new file mode 100644
index 000000000..0f6a0c3b6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/th/intro.txt
@@ -0,0 +1 @@
+====== ตัวจัดการผู้ใช้ ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/th/lang.php b/lib/plugins/usermanager/lang/th/lang.php
new file mode 100644
index 000000000..eb88d7b91
--- /dev/null
+++ b/lib/plugins/usermanager/lang/th/lang.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Thai language file
+ *
+ * @author Komgrit Niyomrath <n.komgrit@gmail.com>
+ * @author Kittithat Arnontavilas mrtomyum@gmail.com
+ * @author Kittithat Arnontavilas <mrtomyum@gmail.com>
+ * @author Thanasak Sompaisansin <jombthep@gmail.com>
+ */
+$lang['menu'] = 'ตัวจัดการบัญชีผู้ใช้';
+$lang['user_id'] = 'ผู้ใช้';
+$lang['user_pass'] = 'รหัสผ่าน';
+$lang['user_name'] = 'ชื่อจริง';
+$lang['user_mail'] = 'อีเมล';
+$lang['user_groups'] = 'กลุ่ม';
+$lang['field'] = 'ฟิลด์';
+$lang['value'] = 'ค่า';
+$lang['add'] = 'เพิ่ม';
+$lang['delete'] = 'ลบ';
+$lang['delete_selected'] = 'ลบที่เลือก';
+$lang['edit'] = 'แก้ไข';
+$lang['edit_prompt'] = 'แก้ไขผู้ใช้คนนี้';
+$lang['modify'] = 'บันทึกการแก้ไข';
+$lang['search'] = 'สืบค้น';
+$lang['search_prompt'] = 'ทำการสืบค้น';
+$lang['clear'] = 'รีเซ็ทตัวกรองคำค้น';
+$lang['filter'] = 'ตัวกรอง';
+$lang['summary'] = 'แสดงผู้ใช้ %1$d-%2$d จากที่พบ %3$d คน, จากทั้งหมด %4$d คน';
+$lang['nonefound'] = 'ไม่พบผู้ใช้ จากทั้งหมด %d คน';
+$lang['delete_ok'] = 'ลบชื่อผู้ใช้ %d คน';
+$lang['delete_fail'] = 'ไม่สามารถลบได้ %d คน';
+$lang['update_ok'] = 'ปรับปรุงข้อมูลผู้ใช้ สำเร็จ';
+$lang['update_fail'] = 'ปรับปรุงข้อมูลผู้ใช้ **ไม่สำเร็จ**';
+$lang['update_exists'] = 'ไม่สามารถเปลี่นชื่อผู้ใช้ได้ ชื่อผู้ใช้ที่ระบุ (%s) มีอยู่แล้ว (การเปลี่นนแปลงอื่นๆ ยังคงทำได้)';
+$lang['start'] = 'เริ่ม';
+$lang['prev'] = 'ก่อนหน้า';
+$lang['next'] = 'ถัดไป';
+$lang['last'] = 'สุดท้าย';
+$lang['edit_usermissing'] = 'หาผู้ใช้ที่เลือกไม่พบ, ชื่อผุ้ใช้ที่ระบุอาจจะถูกลบ หรือเปลี่ยนเป็นอย่างอื่น';
+$lang['user_notify'] = 'แจ้งเตือนผู้ใช้';
+$lang['note_notify'] = 'จดหมายแจ้งเตือนถูกส่งก็ต่อเมื่อผู้ใช้ได้รับมอบรหัสผ่านใหม่';
+$lang['note_group'] = 'ผู้ใช้ใหม่จะถูกเพิ่มเข้าไปยังกลุ่มปริยาย (%s) หากมิได้ระบุกลุ่มเอาไว้';
+$lang['note_pass'] = 'รหัสผ่านจะถูกสร้างโดยอัตโนมัติ ถ้าเว้นว่างช่องกรอก และเปิดการแจ้งเตือนผู้ใช้เอาไว้';
+$lang['add_ok'] = 'การเพิ่มผู้ใช้สำเร็จ';
+$lang['add_fail'] = 'การเพิ่มผู้ใช้ล้มเหลว';
+$lang['notify_ok'] = 'ส่งจดหมายแจ้งเตือนไปแล้ว';
+$lang['notify_fail'] = 'ไม่สามารถส่งจดหมายแจ้งเตือน';
diff --git a/lib/plugins/usermanager/lang/th/list.txt b/lib/plugins/usermanager/lang/th/list.txt
new file mode 100644
index 000000000..fdf65b555
--- /dev/null
+++ b/lib/plugins/usermanager/lang/th/list.txt
@@ -0,0 +1 @@
+====== รายชื่อผู้ใช้ ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/tr/add.txt b/lib/plugins/usermanager/lang/tr/add.txt
new file mode 100644
index 000000000..beedc0be0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/tr/add.txt
@@ -0,0 +1 @@
+===== Kullanıcı ekleme ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/tr/delete.txt b/lib/plugins/usermanager/lang/tr/delete.txt
new file mode 100644
index 000000000..adb8e91e4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/tr/delete.txt
@@ -0,0 +1 @@
+===== Kullanıcı silme ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/tr/edit.txt b/lib/plugins/usermanager/lang/tr/edit.txt
new file mode 100644
index 000000000..d9f3b7125
--- /dev/null
+++ b/lib/plugins/usermanager/lang/tr/edit.txt
@@ -0,0 +1 @@
+===== Kullanıcı Düzenleme ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/tr/intro.txt b/lib/plugins/usermanager/lang/tr/intro.txt
new file mode 100644
index 000000000..1edcb2ce0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/tr/intro.txt
@@ -0,0 +1 @@
+====== Kullanıcı Yöneticisi ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/tr/lang.php b/lib/plugins/usermanager/lang/tr/lang.php
new file mode 100644
index 000000000..b9c9cfc52
--- /dev/null
+++ b/lib/plugins/usermanager/lang/tr/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Turkish language file
+ *
+ * @author Aydın Coşkuner <aydinweb@gmail.com>
+ * @author Cihan Kahveci <kahvecicihan@gmail.com>
+ * @author Yavuz Selim <yavuzselim@gmail.com>
+ * @author Caleb Maclennan <caleb@alerque.com>
+ */
+$lang['menu'] = 'Kullanıcı Yönetimi';
+$lang['noauth'] = '(kullanıcı onaylaması yoktur)';
+$lang['nosupport'] = '(kullanıcı yönetimi desteklenmemektedir)';
+$lang['badauth'] = 'yanlış onaylama metodu';
+$lang['user_id'] = 'Kullanıcı';
+$lang['user_pass'] = 'Şifre';
+$lang['user_name'] = 'Gerçek İsim';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Gruplar';
+$lang['field'] = 'Alan';
+$lang['value'] = 'Değer';
+$lang['add'] = 'Ekle';
+$lang['delete'] = 'Sil';
+$lang['delete_selected'] = 'Seçilenleri Sil';
+$lang['edit'] = 'Düzenle';
+$lang['edit_prompt'] = 'Bu kullanıcıyı düzenle';
+$lang['modify'] = 'Değişiklikleri kaydet';
+$lang['search'] = 'Arama';
+$lang['search_prompt'] = 'Aramayı Gerçekleştir';
+$lang['clear'] = 'Arama ayarlarını sıfırla';
+$lang['filter'] = 'Filtre';
+$lang['summary'] = 'Bulunan %3$d kullanıcının %1$d-%2$d gösterilmektedir. Toplam %4$d kullanıcı bulunmaktadır.';
+$lang['nonefound'] = 'Hiç kullanıcı bulunamadı. Toplam %d kullanıcı bulunmaktadır.';
+$lang['delete_ok'] = '%d kullanıcılar silindi';
+$lang['delete_fail'] = '%d silinemedi.';
+$lang['update_ok'] = 'Kullanıcı başarı ile güncelleştirildi';
+$lang['update_fail'] = 'Kullanıcı güncelleştirilemedi';
+$lang['update_exists'] = 'Kullanıcı adı değiştirilemedi. Belirtilen kullanıcı adı (%s) zaten bulunmaktadır (yapılan diğer değişiklikler uygulanacaktır).';
+$lang['start'] = 'başla';
+$lang['prev'] = 'önceki';
+$lang['next'] = 'sonraki';
+$lang['last'] = 'sonuncu';
+$lang['edit_usermissing'] = 'Seçili kullanıcılar bulunamadı, belirtilen kullanıcı silinmiş ya da değiştirilmiş olabilir.';
+$lang['user_notify'] = 'Kullanıcıyı bilgilendir';
+$lang['note_notify'] = 'Bilgilendirme e-postaları sadece kullanıcıya yeni bir parola verildiğinde gönderilmektedir.';
+$lang['note_group'] = 'Yeni kullanıcılar bir grup belirtilmezse varsayılan (%s) gruba eklenecektir.';
+$lang['note_pass'] = 'Eğer alan boş bırakılırsa parola otomatik oluşturulacaktır ve kullanıcı bilgilendirme etkinleştirilecektir. ';
+$lang['add_ok'] = 'Kullanıcı başarı ile eklendi';
+$lang['add_fail'] = 'Kullanıcı ekleme başarısız';
+$lang['notify_ok'] = 'Bildirim emaili gönderildi';
+$lang['notify_fail'] = 'Bildirim emaili gönderilemedi';
diff --git a/lib/plugins/usermanager/lang/tr/list.txt b/lib/plugins/usermanager/lang/tr/list.txt
new file mode 100644
index 000000000..2314eb22f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/tr/list.txt
@@ -0,0 +1 @@
+===== Kullanıcı Listesi ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/uk/add.txt b/lib/plugins/usermanager/lang/uk/add.txt
new file mode 100644
index 000000000..bc3469714
--- /dev/null
+++ b/lib/plugins/usermanager/lang/uk/add.txt
@@ -0,0 +1 @@
+===== Додати користувача =====
diff --git a/lib/plugins/usermanager/lang/uk/delete.txt b/lib/plugins/usermanager/lang/uk/delete.txt
new file mode 100644
index 000000000..739340b19
--- /dev/null
+++ b/lib/plugins/usermanager/lang/uk/delete.txt
@@ -0,0 +1 @@
+===== Видалення користувача =====
diff --git a/lib/plugins/usermanager/lang/uk/edit.txt b/lib/plugins/usermanager/lang/uk/edit.txt
new file mode 100644
index 000000000..efc84be89
--- /dev/null
+++ b/lib/plugins/usermanager/lang/uk/edit.txt
@@ -0,0 +1 @@
+===== Редагувати користувача =====
diff --git a/lib/plugins/usermanager/lang/uk/intro.txt b/lib/plugins/usermanager/lang/uk/intro.txt
new file mode 100644
index 000000000..b658affe5
--- /dev/null
+++ b/lib/plugins/usermanager/lang/uk/intro.txt
@@ -0,0 +1 @@
+====== Керування користувачами ======
diff --git a/lib/plugins/usermanager/lang/uk/lang.php b/lib/plugins/usermanager/lang/uk/lang.php
new file mode 100644
index 000000000..027c94b44
--- /dev/null
+++ b/lib/plugins/usermanager/lang/uk/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * ukrainian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Oleksiy Voronin <ovoronin@gmail.com>
+ * @author serg_stetsuk@ukr.net
+ * @author okunia@gmail.com
+ * @author Oleksandr Kunytsia <okunia@gmail.com>
+ * @author Uko uko@uar.net
+ * @author Ulrikhe Lukoie <lukoie@gmail>.com
+ */
+$lang['menu'] = 'Керування користувачами';
+$lang['noauth'] = '(автентифікація користувачів не доступна)';
+$lang['nosupport'] = '(керування користувачами не підтримується)';
+$lang['badauth'] = 'невірний механізм автентифікації';
+$lang['user_id'] = 'Ім’я користувача';
+$lang['user_pass'] = 'Пароль';
+$lang['user_name'] = 'Повне ім’я';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Групи';
+$lang['field'] = 'Поле';
+$lang['value'] = 'Значення';
+$lang['add'] = 'Додати';
+$lang['delete'] = 'Видалити';
+$lang['delete_selected'] = 'Видалити вибраних';
+$lang['edit'] = 'Змінити';
+$lang['edit_prompt'] = 'Змінити цього користувача';
+$lang['modify'] = 'Зберегти зміни';
+$lang['search'] = 'Пошук';
+$lang['search_prompt'] = 'Шукати';
+$lang['clear'] = 'Очистити фільтр пошуку';
+$lang['filter'] = 'Фільтр';
+$lang['summary'] = 'Показано користувачі %1$d-%2$d з %3$d знайдених. Всього користувачів: %4$d.';
+$lang['nonefound'] = 'Не знайдено жодного користувача. Всього користувачів: %d.';
+$lang['delete_ok'] = 'Видалено користувачів: %d';
+$lang['delete_fail'] = 'Не вдалося видалити %d.';
+$lang['update_ok'] = 'Дані користувача оновлено';
+$lang['update_fail'] = 'Не вдалося оновити дані користувача';
+$lang['update_exists'] = 'Не вдалося змінити ім’я користувача, такий користувач (%s) вже існує (всі інші зміни будуть застосовані).';
+$lang['start'] = 'на початок';
+$lang['prev'] = 'назад';
+$lang['next'] = 'вперед';
+$lang['last'] = 'в кінець';
+$lang['edit_usermissing'] = 'Обраного користувача не знайдено, можливо його було вилучено або змінено ще десь.';
+$lang['user_notify'] = 'Повідомити користувача';
+$lang['note_notify'] = 'Листи з повідомленнями відсилаються лише у випадку видачі нового пароля користувачу.';
+$lang['note_group'] = 'Якщо не визначено групи, то нові користувачі будуть автоматично додані до групи за замовчуванням (%s).';
+$lang['note_pass'] = 'Пароль буде згенеровано автоматично, якщо поле пароля не заповнено і увімкнено прапорець "повідомити користувача".';
+$lang['add_ok'] = 'Користувача додано';
+$lang['add_fail'] = 'Неможливо додати користувача';
+$lang['notify_ok'] = 'Листа з повідомленням надіслано';
+$lang['notify_fail'] = 'Неможливо вислати листа з повідомленням';
diff --git a/lib/plugins/usermanager/lang/uk/list.txt b/lib/plugins/usermanager/lang/uk/list.txt
new file mode 100644
index 000000000..76013a9b7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/uk/list.txt
@@ -0,0 +1 @@
+===== Список користувачів =====
diff --git a/lib/plugins/usermanager/lang/zh-tw/add.txt b/lib/plugins/usermanager/lang/zh-tw/add.txt
new file mode 100644
index 000000000..6e25f1719
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh-tw/add.txt
@@ -0,0 +1 @@
+===== 增加帳號 =====
diff --git a/lib/plugins/usermanager/lang/zh-tw/delete.txt b/lib/plugins/usermanager/lang/zh-tw/delete.txt
new file mode 100644
index 000000000..1a29ba349
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh-tw/delete.txt
@@ -0,0 +1 @@
+===== 刪除帳號 =====
diff --git a/lib/plugins/usermanager/lang/zh-tw/edit.txt b/lib/plugins/usermanager/lang/zh-tw/edit.txt
new file mode 100644
index 000000000..ec1c5d5ec
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh-tw/edit.txt
@@ -0,0 +1 @@
+===== 修改帳號 =====
diff --git a/lib/plugins/usermanager/lang/zh-tw/intro.txt b/lib/plugins/usermanager/lang/zh-tw/intro.txt
new file mode 100644
index 000000000..8f9488d7d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh-tw/intro.txt
@@ -0,0 +1 @@
+====== 帳號管理員 ======
diff --git a/lib/plugins/usermanager/lang/zh-tw/lang.php b/lib/plugins/usermanager/lang/zh-tw/lang.php
new file mode 100644
index 000000000..5cb20aae8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh-tw/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * English language file
+ *
+ * @author chinsan <chinsan.tw@gmail.com>
+ * @author Li-Jiun Huang <ljhuang.tw@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-simptrad.html
+ * @author Wayne San <waynesan@zerozone.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmai.com>
+ * @author Cheng-Wei Chien <e.cwchien@gmail.com>
+ * @author Danny Lin <danny0838@pchome.com.tw>
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '帳號管理員';
+$lang['noauth'] = '(帳號認證尚未開放)';
+$lang['nosupport'] = '(尚不支援帳號管理)';
+$lang['badauth'] = '錯誤的認證機制';
+$lang['user_id'] = '帳號';
+$lang['user_pass'] = '密碼';
+$lang['user_name'] = '真實姓名';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = '群組';
+$lang['field'] = '欄位';
+$lang['value'] = '設定值';
+$lang['add'] = '增加';
+$lang['delete'] = '刪除';
+$lang['delete_selected'] = '刪除所選的';
+$lang['edit'] = '修改';
+$lang['edit_prompt'] = '修改該帳號';
+$lang['modify'] = '儲存變更';
+$lang['search'] = '搜尋';
+$lang['search_prompt'] = '開始搜尋';
+$lang['clear'] = '重設篩選條件';
+$lang['filter'] = '篩選條件(Filter)';
+$lang['summary'] = '顯示帳號 %1$d-%2$d,共 %3$d 筆符合。共有 %4$d 個帳號。';
+$lang['nonefound'] = '找不到帳號。共有 %d 個帳號。';
+$lang['delete_ok'] = '已刪除 %d 個帳號';
+$lang['delete_fail'] = '%d 個帳號刪除失敗';
+$lang['update_ok'] = '成功更新該帳號';
+$lang['update_fail'] = '更新該帳號時失敗';
+$lang['update_exists'] = '變更帳號名稱 (%s) 失敗,因為有同名帳號存在(其他修改已套用)。';
+$lang['start'] = '開始';
+$lang['prev'] = '上一頁';
+$lang['next'] = '下一頁';
+$lang['last'] = '最後一頁';
+$lang['edit_usermissing'] = '找不到選取的帳號,可能已被刪除或改為其他名稱。';
+$lang['user_notify'] = '通知使用者';
+$lang['note_notify'] = '通知信只會在指定使用者新密碼時寄送。';
+$lang['note_group'] = '如果沒有指定群組,新使用者將會被加入到預設群組(%s)當中。';
+$lang['note_pass'] = '如果沒有輸入這個欄位而且有勾選通知使用者,則會自動產生一組密碼。';
+$lang['add_ok'] = '新增使用者成功';
+$lang['add_fail'] = '新增使用者失敗';
+$lang['notify_ok'] = '通知信已寄出';
+$lang['notify_fail'] = '通知信無法寄出';
diff --git a/lib/plugins/usermanager/lang/zh-tw/list.txt b/lib/plugins/usermanager/lang/zh-tw/list.txt
new file mode 100644
index 000000000..1e539bd41
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh-tw/list.txt
@@ -0,0 +1 @@
+===== 帳號清單 =====
diff --git a/lib/plugins/usermanager/lang/zh/add.txt b/lib/plugins/usermanager/lang/zh/add.txt
new file mode 100644
index 000000000..fd3b1e581
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh/add.txt
@@ -0,0 +1 @@
+===== 添加用户 =====
diff --git a/lib/plugins/usermanager/lang/zh/delete.txt b/lib/plugins/usermanager/lang/zh/delete.txt
new file mode 100644
index 000000000..dc6b7fcc7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh/delete.txt
@@ -0,0 +1 @@
+===== 删除用户 =====
diff --git a/lib/plugins/usermanager/lang/zh/edit.txt b/lib/plugins/usermanager/lang/zh/edit.txt
new file mode 100644
index 000000000..83b72dff7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh/edit.txt
@@ -0,0 +1 @@
+===== 编辑用户 =====
diff --git a/lib/plugins/usermanager/lang/zh/intro.txt b/lib/plugins/usermanager/lang/zh/intro.txt
new file mode 100644
index 000000000..5f254be72
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh/intro.txt
@@ -0,0 +1 @@
+====== 用户管理器 ======
diff --git a/lib/plugins/usermanager/lang/zh/lang.php b/lib/plugins/usermanager/lang/zh/lang.php
new file mode 100644
index 000000000..e7a228229
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh/lang.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * English language file
+ *
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-tradsimp.html
+ * @author George Sheraton guxd@163.com
+ * @author Simon zhan <simonzhan@21cn.com>
+ * @author mr.jinyi@gmail.com
+ * @author ben <ben@livetom.com>
+ * @author lainme <lainme993@gmail.com>
+ * @author caii <zhoucaiqi@gmail.com>
+ * @author Hiphen Lee <jacob.b.leung@gmail.com>
+ * @author caii, patent agent in China <zhoucaiqi@gmail.com>
+ * @author lainme993@gmail.com
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '用户管理器';
+$lang['noauth'] = '(用户认证不可用)';
+$lang['nosupport'] = '(用户管理不支持)';
+$lang['badauth'] = '非法的认证结构';
+$lang['user_id'] = '用户名';
+$lang['user_pass'] = '密码';
+$lang['user_name'] = '真实姓名';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = '组 *';
+$lang['field'] = '栏目';
+$lang['value'] = '值';
+$lang['add'] = '添加';
+$lang['delete'] = '删除';
+$lang['delete_selected'] = '删除选中的';
+$lang['edit'] = '编辑';
+$lang['edit_prompt'] = '编辑该用户';
+$lang['modify'] = '保存更改';
+$lang['search'] = '搜索';
+$lang['search_prompt'] = '进行搜索';
+$lang['clear'] = '重置搜索过滤器';
+$lang['filter'] = '过滤器';
+$lang['summary'] = '找到 %3$d 名用户,显示其中第 %1$d 至 %2$d 位用户。数据库中共有 %4$d 名用户。';
+$lang['nonefound'] = '没有找到用户。数据库中共有 %d 名用户。';
+$lang['delete_ok'] = '用户 %d 已删除';
+$lang['delete_fail'] = '用户 %d 删除失败。';
+$lang['update_ok'] = '用户更新成功';
+$lang['update_fail'] = '用户更新失败';
+$lang['update_exists'] = '用户名更改失败,您指定的用户名(%s)已存在(其他更改将立即生效)。';
+$lang['start'] = '第一页';
+$lang['prev'] = '前一页';
+$lang['next'] = '后一页';
+$lang['last'] = '最后一页';
+$lang['edit_usermissing'] = '您指定的用户没有找到,可能用户已被删除或用户名已更改。';
+$lang['user_notify'] = '通知用户';
+$lang['note_notify'] = '通知邮件只有在用户获得新密码时才会发送。';
+$lang['note_group'] = '* 如果没有指定组,新用户将被添加到默认的组(%s)中。';
+$lang['note_pass'] = '如果输入框留空则自动生成口令,并会通知用户。';
+$lang['add_ok'] = '用户添加成功';
+$lang['add_fail'] = '用户添加失败';
+$lang['notify_ok'] = '通知邮件已发送';
+$lang['notify_fail'] = '通知邮件无法发送';
diff --git a/lib/plugins/usermanager/lang/zh/list.txt b/lib/plugins/usermanager/lang/zh/list.txt
new file mode 100644
index 000000000..e62a85bd0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh/list.txt
@@ -0,0 +1 @@
+===== 用户列表 =====
diff --git a/lib/plugins/usermanager/plugin.info.txt b/lib/plugins/usermanager/plugin.info.txt
new file mode 100644
index 000000000..7ec5fafd5
--- /dev/null
+++ b/lib/plugins/usermanager/plugin.info.txt
@@ -0,0 +1,6 @@
+author Chris Smith
+email chris@jalakai.co.uk
+date 2008-09-17
+name User Manager
+desc Manage users
+url http://dokuwiki.org/plugin:usermanager
diff --git a/lib/plugins/usermanager/script.js b/lib/plugins/usermanager/script.js
new file mode 100644
index 000000000..de013242b
--- /dev/null
+++ b/lib/plugins/usermanager/script.js
@@ -0,0 +1,8 @@
+/**
+ * Add JavaScript confirmation to the User Delete button
+ */
+jQuery(function(){
+ jQuery('#usrmgr__del').click(function(){
+ return confirm(LANG.del_confirm);
+ });
+});
diff --git a/lib/plugins/usermanager/style.css b/lib/plugins/usermanager/style.css
new file mode 100644
index 000000000..ff8e5d9d1
--- /dev/null
+++ b/lib/plugins/usermanager/style.css
@@ -0,0 +1,20 @@
+/* User Manager specific styles */
+#user__manager tr.disabled {
+ color: #6f6f6f;
+ background: #e4e4e4;
+}
+#user__manager tr.user_info {
+ vertical-align: top;
+}
+#user__manager div.edit_user {
+ width: 46%;
+ float: left;
+}
+#user__manager table {
+ margin-bottom: 1em;
+}
+#user__manager input.button[disabled] {
+ color: #ccc!important;
+ border-color: #ccc!important;
+}
+/* IE won't understand but doesn't require it */
diff --git a/lib/scripts/behaviour.js b/lib/scripts/behaviour.js
new file mode 100644
index 000000000..cffdde042
--- /dev/null
+++ b/lib/scripts/behaviour.js
@@ -0,0 +1,180 @@
+/**
+ * Automatic behaviours
+ *
+ * This class wraps various JavaScript functionalities that are triggered
+ * automatically whenever a certain object is in the DOM or a certain CSS
+ * class was found
+ */
+var dw_behaviour = {
+
+ init: function(){
+ dw_behaviour.focusMarker();
+ dw_behaviour.scrollToMarker();
+ dw_behaviour.removeHighlightOnClick();
+ dw_behaviour.quickSelect();
+ dw_behaviour.checkWindowsShares();
+ dw_behaviour.subscription();
+
+ dw_behaviour.revisionBoxHandler();
+ jQuery('#page__revisions input[type=checkbox]').live('click',
+ dw_behaviour.revisionBoxHandler
+ );
+ },
+
+ /**
+ * Looks for an element with the ID scroll__here at scrolls to it
+ */
+ scrollToMarker: function(){
+ var $obj = jQuery('#scroll__here');
+ if($obj.length) {
+ $obj[0].scrollIntoView();
+ }
+ },
+
+ /**
+ * Looks for an element with the ID focus__this at sets focus to it
+ */
+ focusMarker: function(){
+ jQuery('#focus__this').focus();
+ },
+
+ /**
+ * Remove all search highlighting when clicking on a highlighted term
+ *
+ * @FIXME would be nice to have it fade out
+ */
+ removeHighlightOnClick: function(){
+ jQuery('span.search_hit').click(
+ function(e){
+ jQuery(e.target).removeClass('search_hit');
+ }
+ );
+ },
+
+ /**
+ * Autosubmit quick select forms
+ *
+ * When a <select> tag has the class "quickselect", this script will
+ * automatically submit its parent form when the select value changes.
+ * It also hides the submit button of the form.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ quickSelect: function(){
+ jQuery('select.quickselect')
+ .change(function(e){ e.target.form.submit(); })
+ .closest('form').find('input[type=submit]').not('.show').hide();
+ },
+
+ /**
+ * Display error for Windows Shares on browsers other than IE
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ */
+ checkWindowsShares: function() {
+ if(!LANG.nosmblinks || typeof(document.all) !== 'undefined') {
+ // No warning requested or none necessary
+ return;
+ }
+
+ jQuery('a.windows').live('click', function(){
+ alert(LANG.nosmblinks.replace(/\\n/,"\n"));
+ });
+ },
+
+ /**
+ * Hide list subscription style if target is a page
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ subscription: function(){
+ var $form, $list, $digest;
+
+ $form = jQuery('#subscribe__form');
+ if (0 === $form.length) return;
+
+ $list = $form.find("input[name='sub_style'][value='list']");
+ $digest = $form.find("input[name='sub_style'][value='digest']");
+
+ $form.find("input[name='sub_target']")
+ .click(
+ function () {
+ var $this = jQuery(this), show_list;
+ if (!$this.prop('checked')) {
+ return;
+ }
+
+ show_list = $this.val().match(/:$/);
+ $list.parent().dw_toggle(show_list);
+ if (!show_list && $list.prop('checked')) {
+ $digest.prop('checked', 'checked');
+ }
+ }
+ )
+ .filter(':checked')
+ .click();
+ },
+
+ /**
+ * disable multiple revisions checkboxes if two are checked
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ revisionBoxHandler: function(){
+ var $checked = jQuery('#page__revisions input[type=checkbox]:checked');
+ var $all = jQuery('#page__revisions input[type=checkbox]');
+
+ if($checked.length < 2){
+ $all.attr('disabled',false);
+ jQuery('#page__revisions input[type=submit]').attr('disabled',true);
+ }else{
+ $all.attr('disabled',true);
+ jQuery('#page__revisions input[type=submit]').attr('disabled',false);
+ for(var i=0; i<$checked.length; i++){
+ $checked[i].disabled = false;
+ if(i>1){
+ $checked[i].checked = false;
+ }
+ }
+ }
+ }
+
+};
+
+/**
+ * Hides elements with a slide animation
+ *
+ * @param fn optional callback to run after hiding
+ * @author Adrian Lang <mail@adrianlang.de>
+ */
+jQuery.fn.dw_hide = function(fn) {
+ return this.slideUp('fast', fn);
+};
+
+/**
+ * Unhides elements with a slide animation
+ *
+ * @param fn optional callback to run after hiding
+ * @author Adrian Lang <mail@adrianlang.de>
+ */
+jQuery.fn.dw_show = function(fn) {
+ return this.slideDown('fast', fn);
+};
+
+/**
+ * Toggles visibility of an element using a slide element
+ *
+ * @param bool the current state of the element (optional)
+ */
+jQuery.fn.dw_toggle = function(bool, fn) {
+ return this.each(function() {
+ var $this = jQuery(this);
+ if (typeof bool === 'undefined') {
+ bool = $this.is(':hidden');
+ }
+ $this[bool ? "dw_show" : "dw_hide" ](fn);
+ });
+};
+
+jQuery(dw_behaviour.init);
diff --git a/lib/scripts/compatibility.js b/lib/scripts/compatibility.js
new file mode 100644
index 000000000..385e45854
--- /dev/null
+++ b/lib/scripts/compatibility.js
@@ -0,0 +1,414 @@
+/**
+ * Mark a JavaScript function as deprecated
+ *
+ * This will print a warning to the JavaScript console (if available) in
+ * Firebug and Chrome and a stack trace (if available) to easily locate the
+ * problematic function call.
+ *
+ * @param msg optional message to print
+ */
+function DEPRECATED(msg){
+ if(!window.console) return;
+ if(!msg) msg = '';
+
+ var func;
+ if(arguments.callee) func = arguments.callee.caller.name;
+ if(func) func = ' '+func+'()';
+ var line = 'DEPRECATED function call'+func+'. '+msg;
+
+ if(console.warn){
+ console.warn(line);
+ }else{
+ console.log(line);
+ }
+
+ if(console.trace) console.trace();
+}
+
+/**
+ * Construct a wrapper function for deprecated function names
+ *
+ * This function returns a wrapper function which just calls DEPRECATED
+ * and the new function.
+ *
+ * @param func The new function
+ * @param context Optional; The context (`this`) of the call
+ */
+function DEPRECATED_WRAP(func, context) {
+ return function () {
+ DEPRECATED();
+ return func.apply(context || this, arguments);
+ };
+}
+
+/**
+ * Handy shortcut to document.getElementById
+ *
+ * This function was taken from the prototype library
+ *
+ * @link http://prototype.conio.net/
+ */
+function $() {
+ DEPRECATED('Please use the jQuery() function instead.');
+
+ var elements = new Array();
+
+ for (var i = 0; i < arguments.length; i++) {
+ var element = arguments[i];
+ if (typeof element == 'string')
+ element = document.getElementById(element);
+
+ if (arguments.length == 1)
+ return element;
+
+ elements.push(element);
+ }
+
+ return elements;
+}
+
+
+
+
+var index = {
+ throbber_delay: dw_index.throbber_delay,
+ toggle: DEPRECATED_WRAP(dw_index.toggle, dw_index),
+ treeattach: DEPRECATED_WRAP(dw_index.treeattach, dw_index)
+};
+
+var ajax_quicksearch = {
+ init: DEPRECATED_WRAP(dw_qsearch.init, dw_qsearch),
+ clear_results: DEPRECATED_WRAP(dw_qsearch.clear_results, dw_qsearch),
+ onCompletion: DEPRECATED_WRAP(dw_qsearch.onCompletion, dw_qsearch)
+};
+
+var linkwiz = {
+ init: DEPRECATED_WRAP(dw_linkwiz.init, dw_linkwiz),
+ onEntry: DEPRECATED_WRAP(dw_linkwiz.onEntry, dw_linkwiz),
+ getResult: DEPRECATED_WRAP(dw_linkwiz.getResult, dw_linkwiz),
+ select: DEPRECATED_WRAP(dw_linkwiz.select, dw_linkwiz),
+ deselect: DEPRECATED_WRAP(dw_linkwiz.deselect, dw_linkwiz),
+ onResultClick: DEPRECATED_WRAP(dw_linkwiz.onResultClick, dw_linkwiz),
+ resultClick: DEPRECATED_WRAP(dw_linkwiz.resultClick, dw_linkwiz),
+ insertLink: DEPRECATED_WRAP(dw_linkwiz.insertLink, dw_linkwiz),
+ autocomplete: DEPRECATED_WRAP(dw_linkwiz.autocomplete, dw_linkwiz),
+ autocomplete_exec: DEPRECATED_WRAP(dw_linkwiz.autocomplete_exec, dw_linkwiz),
+ show: DEPRECATED_WRAP(dw_linkwiz.show, dw_linkwiz),
+ hide: DEPRECATED_WRAP(dw_linkwiz.hide, dw_linkwiz),
+ toggle: DEPRECATED_WRAP(dw_linkwiz.toggle, dw_linkwiz)
+};
+
+var locktimer = {
+ init: DEPRECATED_WRAP(dw_locktimer.init, dw_locktimer),
+ reset: DEPRECATED_WRAP(dw_locktimer.reset, dw_locktimer),
+ warning: DEPRECATED_WRAP(dw_locktimer.warning, dw_locktimer),
+ clear: DEPRECATED_WRAP(dw_locktimer.clear, dw_locktimer),
+ refresh: DEPRECATED_WRAP(dw_locktimer.refresh, dw_locktimer),
+ refreshed: DEPRECATED_WRAP(dw_locktimer.refreshed, dw_locktimer)
+};
+
+var media_manager = {
+ // treeattach, selectorattach, confirmattach are munched together into
+ // dw_mediamanager.init
+ attachoptions: DEPRECATED_WRAP(dw_mediamanager.attachoptions, dw_mediamanager),
+ togglekeepopen: function (event, cb) {
+ DEPRECATED('Use dw_mediamanager.toggleOption instead');
+ return dw_mediamanager.toggleOption.call(cb, 'keepopen');
+ },
+ togglehide: function (event, cb) {
+ DEPRECATED('Use dw_mediamanager.toggleOption instead');
+ return dw_mediamanager.toggleOption.call(cb, 'hide');
+ },
+ updatehide: DEPRECATED_WRAP(dw_mediamanager.updatehide, dw_mediamanager),
+ select: function (event, link) {
+ DEPRECATED('Use dw_mediamanager.select instead');
+ return dw_mediamanager.select.call(link, event);
+ },
+ initpopup: DEPRECATED_WRAP(dw_mediamanager.initpopup, dw_mediamanager),
+ insert: DEPRECATED_WRAP(dw_mediamanager.insert, dw_mediamanager),
+ list: function (event, link) {
+ DEPRECATED('Use dw_mediamanager.list instead');
+ return dw_mediamanager.list.call(link, event);
+ },
+ // toggle is handled by dw_tree
+ suggest: DEPRECATED_WRAP(dw_mediamanager.suggest, dw_mediamanager),
+ initFlashUpload: DEPRECATED_WRAP(dw_mediamanager.initFlashUpload, dw_mediamanager),
+ closePopup: function () {
+ DEPRECATED();
+ dw_mediamanager.$popup.dialog('close');
+ },
+ setalign: function (event, cb) {
+ DEPRECATED('Use dw_mediamanager.setOpt instead');
+ return dw_mediamanager.setOpt.call(this, 'align', event);
+ },
+ setlink: function (event, cb) {
+ DEPRECATED('Use dw_mediamanager.setOpt instead');
+ return dw_mediamanager.setOpt.call(this, 'link', event);
+ },
+ setsize: function (event, cb) {
+ DEPRECATED('Use dw_mediamanager.setOpt instead');
+ return dw_mediamanager.setOpt.call(this, 'size', event);
+ },
+ outSet: function (id) {
+ DEPRECATED();
+ return jQuery(id).removeClass('selected');
+ },
+ inSet: function (id) {
+ DEPRECATED();
+ return jQuery(id).addClass('selected');
+ }
+};
+
+initSizeCtl = DEPRECATED_WRAP(dw_editor.initSizeCtl);
+sizeCtl = DEPRECATED_WRAP(dw_editor.sizeCtl);
+toggleWrap = DEPRECATED_WRAP(dw_editor.toggleWrap);
+setWrap = DEPRECATED_WRAP(dw_editor.setWrap);
+
+function findPosX(object){
+ DEPRECATED('Use jQuery.position() instead');
+ return jQuery(object).position().left;
+}
+
+function findPosY(object){
+ DEPRECATED('Use jQuery.position() instead');
+ return jQuery(object).position().top;
+}
+
+function getElementsByClass(searchClass,node,tag){
+ DEPRECATED('Use jQuery() instead');
+ if(node == null) node = document;
+ if(typeof tag === 'undefined') tag = '';
+ return jQuery(node).find(tag+'.'+searchClass).toArray();
+}
+
+function prependChild(parent,element) {
+ DEPRECATED('Use jQuery.prepend() instead');
+ jQuery(parent).prepend(element);
+}
+
+function addEvent(element, type, handler) {
+ DEPRECATED('Use jQuery.bind() instead. Note that jQuery’s behaviour' +
+ ' when a handler returns false differs from addEvent’s');
+ jQuery(element).bind(type,{},function (e) {
+ // returning false in an addEvent event handler did not prevent
+ // bubbling but just canceled handlers on this node and prevented
+ // default behavior, so wrap the handler call and mimic that behavior.
+ //
+ // Refer to jQuery.event.handle().
+ var ret = handler.apply(this, Array.prototype.slice.call(arguments, 0));
+ if (typeof ret !== 'undefined') {
+ if ( ret !== false ) {
+ return ret;
+ }
+ // What jQuery does.
+ e.result = ret;
+ e.preventDefault();
+ // Not what jQuery does. This would be: event.stopPropagation();
+ // Hack it so that immediate propagation (other event handlers on
+ // this element) appears stopped without stopping the actual
+ // propagation (bubbling)
+ e.isImmediatePropagationStopped = function () { return true; };
+ }
+ });
+}
+
+function removeEvent(element, type, handler) {
+ DEPRECATED('Use jQuery.unbind() instead.');
+ jQuery(element).unbind(type,handler);
+}
+
+function addInitEvent(func) {
+ DEPRECATED('Use jQuery(<function>) instead');
+ jQuery(func);
+}
+
+
+function jsEscape(text){
+ DEPRECATED('Insert text through jQuery.text() instead of escaping on your own');
+ var re=new RegExp("\\\\","g");
+ text=text.replace(re,"\\\\");
+ re=new RegExp("'","g");
+ text=text.replace(re,"\\'");
+ re=new RegExp('"',"g");
+ text=text.replace(re,'&quot;');
+ re=new RegExp("\\\\\\\\n","g");
+ text=text.replace(re,"\\n");
+ return text;
+}
+
+/**
+ * Simple function to check if a global var is defined
+ *
+ * @author Kae Verens
+ * @link http://verens.com/archives/2005/07/25/isset-for-javascript/#comment-2835
+ */
+function isset(varname){
+ DEPRECATED("Use `typeof var !== 'undefined'` instead");
+ return(typeof(window[varname])!='undefined');
+}
+
+/**
+ * Checks if property is undefined
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isUndefined (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'undefined'` instead");
+ return (typeof prop == 'undefined');
+}
+
+/**
+ * Checks if property is function
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isFunction (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'function'` instead");
+ return (typeof prop == 'function');
+}
+/**
+ * Checks if property is string
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isString (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'string'` instead");
+ return (typeof prop == 'string');
+}
+
+/**
+ * Checks if property is number
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isNumber (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'number'` instead");
+ return (typeof prop == 'number');
+}
+
+/**
+ * Checks if property is the calculable number
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isNumeric (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'number' && !isNaN(var) && isFinite(var)` instead");
+ return isNumber(prop)&&!isNaN(prop)&&isFinite(prop);
+}
+
+/**
+ * Checks if property is array
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isArray (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `var instanceof Array` instead");
+ return (prop instanceof Array);
+}
+
+/**
+ * Checks if property is regexp
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isRegExp (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `var instanceof RegExp` instead");
+ return (prop instanceof RegExp);
+}
+
+/**
+ * Checks if property is a boolean value
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isBoolean (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'boolean'` instead");
+ return ('boolean' == typeof prop);
+}
+
+/**
+ * Checks if property is a scalar value (value that could be used as the hash key)
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isScalar (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'string' || (typeof var === 'number' &&" +
+ " !isNaN(var) && isFinite(var))` instead");
+ return isNumeric(prop)||isString(prop);
+}
+
+/**
+ * Checks if property is empty
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isEmpty (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED();
+ var i;
+ if (isBoolean(prop)) {
+ return false;
+ } else if (isRegExp(prop) && new RegExp("").toString() == prop.toString()) {
+ return true;
+ } else if (isString(prop) || isNumber(prop)) {
+ return !prop;
+ } else if (Boolean(prop) && false != prop) {
+ for (i in prop) {
+ if(prop.hasOwnProperty(i)) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+/**
+ * Get the computed style of a node.
+ *
+ * @link https://acidmartin.wordpress.com/2008/08/26/style-get-any-css-property-value-of-an-object/
+ * @link http://svn.dojotoolkit.org/src/dojo/trunk/_base/html.js
+ */
+function gcs(node){
+ DEPRECATED('Use jQuery(node).style() instead');
+ if(node.currentStyle){
+ return node.currentStyle;
+ }else{
+ return node.ownerDocument.defaultView.getComputedStyle(node, null);
+ }
+}
+
+/**
+ * Until 2011-05-25 "Rincewind", a code intended to fix some Safari issue
+ * always declared the global _timer. plugin:sortablejs relies on _timer
+ * being declared.
+ */
+var _timer;
diff --git a/lib/scripts/cookie.js b/lib/scripts/cookie.js
new file mode 100644
index 000000000..3ad67bfa4
--- /dev/null
+++ b/lib/scripts/cookie.js
@@ -0,0 +1,64 @@
+/**
+* Handles the cookie used by several JavaScript functions
+*
+* Only a single cookie is written and read. You may only save
+* simple name-value pairs - no complex types!
+*
+* You should only use the getValue and setValue methods
+*
+* @author Andreas Gohr <andi@splitbrain.org>
+* @author Michal Rezler <m.rezler@centrum.cz>
+*/
+var DokuCookie = {
+ data: {},
+ name: 'DOKU_PREFS',
+
+ /**
+ * Save a value to the cookie
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ setValue: function(key,val){
+ var text = [],
+ _this = this;
+ this.init();
+ this.data[key] = val;
+
+ //save the whole data array
+ jQuery.each(_this.data, function (key, val) {
+ if (_this.data.hasOwnProperty(key)) {
+ text.push(encodeURIComponent(key)+'#'+encodeURIComponent(val));
+ }
+ });
+ jQuery.cookie(this.name, text.join('#'), {expires: 365, path: DOKU_BASE});
+ },
+
+ /**
+ * Get a Value from the Cookie
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ getValue: function(key){
+ this.init();
+ return this.data[key];
+ },
+
+ /**
+ * Loads the current set cookie
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ init: function(){
+ var text, parts, i;
+ if(!jQuery.isEmptyObject(this.data)) {
+ return;
+ }
+ text = jQuery.cookie(this.name);
+ if(text){
+ parts = text.split('#');
+ for(i = 0; i < parts.length; i += 2){
+ this.data[decodeURIComponent(parts[i])] = decodeURIComponent(parts[i+1]);
+ }
+ }
+ }
+};
diff --git a/lib/scripts/delay.js b/lib/scripts/delay.js
new file mode 100644
index 000000000..edd53def3
--- /dev/null
+++ b/lib/scripts/delay.js
@@ -0,0 +1,70 @@
+/**
+ * Manage delayed and timed actions
+ *
+ * @license GPL2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+
+/**
+ * Provide a global callback for window.setTimeout
+ *
+ * To get a timeout for non-global functions, just call
+ * delay.add(func, timeout).
+ */
+var timer = {
+ _cur_id: 0,
+ _handlers: {},
+
+ execDispatch: function (id) {
+ timer._handlers[id]();
+ },
+
+ add: function (func, timeout) {
+ var id = ++timer._cur_id;
+ timer._handlers[id] = func;
+ return window.setTimeout('timer.execDispatch(' + id + ')', timeout);
+ }
+};
+
+/**
+ * Provide a delayed start
+ *
+ * To call a function with a delay, just create a new Delay(func, timeout) and
+ * call that object’s method “start”.
+ */
+function Delay (func, timeout) {
+ this.func = func;
+ if (timeout) {
+ this.timeout = timeout;
+ }
+}
+
+Delay.prototype = {
+ func: null,
+ timeout: 500,
+
+ delTimer: function () {
+ if (this.timer !== null) {
+ window.clearTimeout(this.timer);
+ this.timer = null;
+ }
+ },
+
+ start: function () {
+ DEPRECATED('don\'t use the Delay object, use window.timeout with a callback instead');
+ this.delTimer();
+ var _this = this;
+ this.timer = timer.add(function () { _this.exec.call(_this); },
+ this.timeout);
+
+ this._data = {
+ _this: arguments[0],
+ _params: Array.prototype.slice.call(arguments, 2)
+ };
+ },
+
+ exec: function () {
+ this.delTimer();
+ this.func.call(this._data._this, this._data._params);
+ }
+};
diff --git a/lib/scripts/drag.js b/lib/scripts/drag.js
new file mode 100644
index 000000000..dd252d95d
--- /dev/null
+++ b/lib/scripts/drag.js
@@ -0,0 +1,87 @@
+/**
+ * Makes a DOM object draggable
+ *
+ * If you just want to move objects around, use drag.attach. For full
+ * customization, drag can be used as a javascript prototype, it is
+ * inheritance-aware.
+ *
+ * @deprecated
+ * @link http://nofunc.org/Drag_Drop/
+ */
+var drag = {
+ obj: null,
+ handle: null,
+ oX: 0, // object X position
+ oY: 0, // object Y position
+ eX: 0, // event X delta
+ eY: 0, // event Y delta
+
+ /**
+ * Attaches the needed handlers to the given object
+ *
+ * This can be called for multiple objects, the right one is later
+ * determined from the event itself. The handle is optional
+ *
+ * @param DOMObject obj The object that should be draggable
+ * @param DOMObject handle A handle on which the obj can be dragged
+ */
+ attach: function (obj,handle) {
+ DEPRECATED('Use jQuery.draggable() instead.');
+ if(handle){
+ handle.dragobject = obj;
+ }else{
+ handle = obj;
+ }
+ var _this = this;
+ addEvent($(handle),'mousedown',function (e) {return _this.start(e); });
+ },
+
+ /**
+ * Starts the dragging operation
+ */
+ start: function (e){
+ this.handle = e.target;
+ if(this.handle.dragobject){
+ this.obj = this.handle.dragobject;
+ }else{
+ this.obj = this.handle;
+ }
+
+ this.handle.className += ' ondrag';
+ this.obj.className += ' ondrag';
+
+ this.oX = parseInt(this.obj.style.left);
+ this.oY = parseInt(this.obj.style.top);
+ this.eX = e.pageX;
+ this.eY = e.pageY;
+
+ var _this = this;
+ this.mousehandlers = [function (e) {return _this.drag(e);}, function (e) {return _this.stop(e);}];
+ addEvent(document,'mousemove', this.mousehandlers[0]);
+ addEvent(document,'mouseup', this.mousehandlers[1]);
+
+ return false;
+ },
+
+ /**
+ * Ends the dragging operation
+ */
+ stop: function(){
+ this.handle.className = this.handle.className.replace(/ ?ondrag/,'');
+ this.obj.className = this.obj.className.replace(/ ?ondrag/,'');
+ removeEvent(document,'mousemove', this.mousehandlers[0]);
+ removeEvent(document,'mouseup', this.mousehandlers[1]);
+ this.obj = null;
+ this.handle = null;
+ },
+
+ /**
+ * Moves the object during the dragging operation
+ */
+ drag: function(e) {
+ if(this.obj) {
+ this.obj.style.top = (e.pageY+this.oY-this.eY+'px');
+ this.obj.style.left = (e.pageX+this.oX-this.eX+'px');
+ }
+ }
+};
diff --git a/lib/scripts/edit.js b/lib/scripts/edit.js
new file mode 100644
index 000000000..33a8f61b5
--- /dev/null
+++ b/lib/scripts/edit.js
@@ -0,0 +1,268 @@
+/**
+ * Functions for text editing (toolbar stuff)
+ *
+ * @todo most of the stuff in here should be revamped and then moved to toolbar.js
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+/**
+ * Creates a toolbar button through the DOM
+ *
+ * Style the buttons through the toolbutton class
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michal Rezler <m.rezler@centrum.cz>
+ */
+function createToolButton(icon,label,key,id,classname){
+ var $btn = jQuery(document.createElement('button')),
+ $ico = jQuery(document.createElement('img'));
+
+ // prepare the basic button stuff
+ $btn.addClass('toolbutton');
+ if(classname){
+ $btn.addClass(classname);
+ }
+
+ $btn.attr('title', label);
+ if(key){
+ $btn.attr('title', label + ' ['+key.toUpperCase()+']')
+ .attr('accessKey', key);
+ }
+
+ // set IDs if given
+ if(id){
+ $btn.attr('id', id);
+ $ico.attr('id', id+'_ico');
+ }
+
+ // create the icon and add it to the button
+ if(icon.substr(0,1) !== '/'){
+ icon = DOKU_BASE + 'lib/images/toolbar/' + icon;
+ }
+ $ico.attr('src', icon);
+ $btn.append($ico);
+
+ // we have to return a DOM object (for compatibility reasons)
+ return $btn[0];
+}
+
+/**
+ * Creates a picker window for inserting text
+ *
+ * The given list can be an associative array with text,icon pairs
+ * or a simple list of text. Style the picker window through the picker
+ * class or the picker buttons with the pickerbutton class. Picker
+ * windows are appended to the body and created invisible.
+ *
+ * @param string id the ID to assign to the picker
+ * @param array props the properties for the picker
+ * @param string edid the ID of the textarea
+ * @rteurn DOMobject the created picker
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function createPicker(id,props,edid){
+ // create the wrapping div
+ var $picker = jQuery(document.createElement('div'));
+
+ $picker.addClass('picker a11y');
+ if(props['class']){
+ $picker.addClass(props['class']);
+ }
+
+ $picker.attr('id', id).css('position', 'absolute');
+
+ function $makebutton(title) {
+ var $btn = jQuery(document.createElement('button'))
+ .addClass('pickerbutton').attr('title', title)
+ .bind('click', bind(pickerInsert, title, edid))
+ .appendTo($picker);
+ return $btn;
+ }
+
+ jQuery.each(props.list, function (key, item) {
+ if (!props.list.hasOwnProperty(key)) {
+ return;
+ }
+
+ if(isNaN(key)){
+ // associative array -> treat as text => image pairs
+ if (item.substr(0,1) !== '/') {
+ item = DOKU_BASE+'lib/images/'+props.icobase+'/'+item;
+ }
+ jQuery(document.createElement('img'))
+ .attr('src', item)
+ .appendTo($makebutton(key));
+ }else if (typeof item == 'string'){
+ // a list of text -> treat as text picker
+ $makebutton(item).text(item);
+ }else{
+ // a list of lists -> treat it as subtoolbar
+ initToolbar($picker,edid,props.list);
+ return false; // all buttons handled already
+ }
+
+ });
+ jQuery('body').append($picker);
+
+ // we have to return a DOM object (for compatibility reasons)
+ return $picker[0];
+}
+
+/**
+ * Called by picker buttons to insert Text and close the picker again
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function pickerInsert(text,edid){
+ insertAtCarret(edid,text);
+ pickerClose();
+}
+
+/**
+ * Add button action for signature button
+ *
+ * @param DOMElement btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @return boolean If button should be appended
+ * @author Gabriel Birke <birke@d-scribe.de>
+ */
+function addBtnActionSignature($btn, props, edid) {
+ if(typeof SIG != 'undefined' && SIG != ''){
+ $btn.bind('click', bind(insertAtCarret,edid,SIG));
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Determine the current section level while editing
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+function currentHeadlineLevel(textboxId){
+ var field = jQuery('#' + textboxId)[0],
+ s = false,
+ opts = [field.value.substr(0,getSelection(field).start)];
+ if (field.form.prefix) {
+ // we need to look in prefix context
+ opts.push(field.form.prefix.value);
+ }
+
+ jQuery.each(opts, function (_, opt) {
+ // Check whether there is a headline in the given string
+ var str = "\n" + opt,
+ lasthl = str.lastIndexOf("\n==");
+ if (lasthl !== -1) {
+ s = str.substr(lasthl+1,6);
+ return false;
+ }
+ });
+ if (s === false) {
+ return 0;
+ }
+ return 7 - s.match(/^={2,6}/)[0].length;
+}
+
+
+/**
+ * global var used for not saved yet warning
+ */
+window.textChanged = false;
+
+/**
+ * Delete the draft before leaving the page
+ */
+function deleteDraft() {
+ if (is_opera || window.keepDraft) {
+ return;
+ }
+
+ var $dwform = jQuery('#dw__editform');
+
+ if($dwform.length === 0) {
+ return;
+ }
+
+ // remove a possibly saved draft using ajax
+ jQuery.post(DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'draftdel',
+ id: $dwform.find('input[name=id]').val()
+ }
+ );
+}
+
+/**
+ * Activate "not saved" dialog, add draft deletion to page unload,
+ * add handlers to monitor changes
+ *
+ * Sets focus to the editbox as well
+ */
+jQuery(function () {
+ var $editform = jQuery('#dw__editform');
+ if ($editform.length == 0) {
+ return;
+ }
+
+ var $edit_text = jQuery('#wiki__text');
+ if ($edit_text.length > 0) {
+ if($edit_text.attr('readOnly')) {
+ return;
+ }
+
+ // set focus and place cursor at the start
+ var sel = getSelection($edit_text[0]);
+ sel.start = 0;
+ sel.end = 0;
+ setSelection(sel);
+ $edit_text.focus();
+ }
+
+ var checkfunc = function() {
+ textChanged = true; //global var
+ summaryCheck();
+ };
+
+ $editform.change(checkfunc);
+ $editform.keydown(checkfunc);
+
+ window.onbeforeunload = function(){
+ if(window.textChanged) {
+ return LANG.notsavedyet;
+ }
+ };
+ window.onunload = deleteDraft;
+
+ // reset change memory var on submit
+ jQuery('#edbtn__save').click(
+ function() {
+ window.onbeforeunload = '';
+ textChanged = false;
+ }
+ );
+ jQuery('#edbtn__preview').click(
+ function() {
+ window.onbeforeunload = '';
+ textChanged = false;
+ window.keepDraft = true; // needed to keep draft on page unload
+ }
+ );
+
+ var $summary = jQuery('#edit__summary');
+ $summary.change(summaryCheck);
+ $summary.keyup(summaryCheck);
+
+ if (textChanged) summaryCheck();
+});
+
+/**
+ * Checks if a summary was entered - if not the style is changed
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function summaryCheck(){
+ var $sum = jQuery('#edit__summary'),
+ missing = $sum.val() === '';
+ $sum.toggleClass('missing', missing).toggleClass('edit', !missing);
+}
diff --git a/lib/scripts/editor.js b/lib/scripts/editor.js
new file mode 100644
index 000000000..042e34608
--- /dev/null
+++ b/lib/scripts/editor.js
@@ -0,0 +1,204 @@
+/**
+ * The DokuWiki editor features
+ *
+ * These are the advanced features of the editor. It does NOT contain any
+ * code for the toolbar buttons and it functions. See toolbar.js for that.
+ */
+
+var dw_editor = {
+
+ /**
+ * initialize the default editor functionality
+ *
+ * All other functions can also be called separately for non-default
+ * textareas
+ */
+ init: function(){
+ var $editor = jQuery('#wiki__text');
+ if($editor.length === 0) {
+ return;
+ }
+
+ dw_editor.initSizeCtl('#size__ctl',$editor);
+
+ if($editor.attr('readOnly')) {
+ return;
+ }
+
+ // in Firefox, keypress doesn't send the correct keycodes,
+ // in Opera, the default of keydown can't be prevented
+ if (jQuery.browser.opera) {
+ $editor.keypress(dw_editor.keyHandler);
+ } else {
+ $editor.keydown(dw_editor.keyHandler);
+ }
+
+ },
+
+ /**
+ * Add the edit window size and wrap controls
+ *
+ * Initial values are read from cookie if it exists
+ *
+ * @param selector ctlarea the div to place the controls
+ * @param selector editor the textarea to control
+ */
+ initSizeCtl: function(ctlarea,editor){
+ var $ctl = jQuery(ctlarea),
+ $textarea = jQuery(editor);
+
+ if($ctl.length === 0 || $textarea.length === 0) {
+ return;
+ }
+
+ $textarea.css('height', DokuCookie.getValue('sizeCtl') || '300px');
+
+ var wrp = DokuCookie.getValue('wrapCtl');
+ if(wrp){
+ dw_editor.setWrap($textarea[0], wrp);
+ } // else use default value
+
+ jQuery.each([
+ ['larger', function(){dw_editor.sizeCtl(editor,100);}],
+ ['smaller', function(){dw_editor.sizeCtl(editor,-100);}],
+ ['wrap', function(){dw_editor.toggleWrap(editor);}]
+ ], function (_, img) {
+ jQuery(document.createElement('IMG'))
+ .attr('src', DOKU_BASE+'lib/images/' + img[0] + '.gif')
+ .click(img[1])
+ .appendTo($ctl);
+ });
+ },
+
+ /**
+ * This sets the vertical size of the editbox and adjusts the cookie
+ *
+ * @param selector editor the textarea to control
+ * @param int val the relative value to resize in pixel
+ */
+ sizeCtl: function(editor,val){
+ var $textarea = jQuery(editor),
+ height = parseInt($textarea.css('height')) + val;
+ $textarea.css('height', height+'px');
+ DokuCookie.setValue('sizeCtl',$textarea.css('height'));
+ },
+
+ /**
+ * Toggle the wrapping mode of the editor textarea and adjusts the
+ * cookie
+ *
+ * @param selector editor the textarea to control
+ */
+ toggleWrap: function(editor){
+ var $textarea = jQuery(editor),
+ wrap = $textarea.attr('wrap');
+ dw_editor.setWrap($textarea[0],
+ (wrap && wrap.toLowerCase() == 'off') ? 'soft' : 'off');
+ DokuCookie.setValue('wrapCtl',$textarea.attr('wrap'));
+ },
+
+ /**
+ * Set the wrapping mode of a textarea
+ *
+ * @author Fluffy Convict <fluffyconvict@hotmail.com>
+ * @author <shutdown@flashmail.com>
+ * @link http://news.hping.org/comp.lang.javascript.archive/12265.html
+ * @link https://bugzilla.mozilla.org/show_bug.cgi?id=41464
+ * @param DomObject textarea
+ * @param string wrapAttrValue
+ */
+ setWrap: function(textarea, wrapAttrValue){
+ textarea.setAttribute('wrap', wrapAttrValue);
+
+ // Fix display for mozilla
+ var parNod = textarea.parentNode;
+ var nxtSib = textarea.nextSibling;
+ parNod.removeChild(textarea);
+ parNod.insertBefore(textarea, nxtSib);
+ },
+
+ /**
+ * Make intended formattings easier to handle
+ *
+ * Listens to all key inputs and handle indentions
+ * of lists and code blocks
+ *
+ * Currently handles space, backspce and enter presses
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @fixme handle tabs
+ * @param event e - the key press event object
+ */
+ keyHandler: function(e){
+ if(jQuery.inArray(e.keyCode,[8, 13, 32]) === -1) {
+ return;
+ }
+ var selection = getSelection(this);
+ if(selection.getLength() > 0) {
+ return; //there was text selected, keep standard behavior
+ }
+ var search = "\n"+this.value.substr(0,selection.start);
+ var linestart = Math.max(search.lastIndexOf("\n"),
+ search.lastIndexOf("\r")); //IE workaround
+ search = search.substr(linestart);
+
+ if(e.keyCode == 13){ // Enter
+ // keep current indention for lists and code
+ var match = search.match(/(\n +([\*-] ?)?)/);
+ if(match){
+ var scroll = this.scrollHeight;
+ var match2 = search.match(/^\n +[\*-]\s*$/);
+ // Cancel list if the last item is empty (i. e. two times enter)
+ if (match2 && this.value.substr(selection.start).match(/^($|\r?\n)/)) {
+ this.value = this.value.substr(0, linestart) + "\n" +
+ this.value.substr(selection.start);
+ selection.start = linestart + 1;
+ selection.end = linestart + 1;
+ setSelection(selection);
+ } else {
+ insertAtCarret(this.id,match[1]);
+ }
+ this.scrollTop += (this.scrollHeight - scroll);
+ e.preventDefault(); // prevent enter key
+ return false;
+ }
+ }else if(e.keyCode == 8){ // Backspace
+ // unindent lists
+ var match = search.match(/(\n +)([*-] ?)$/);
+ if(match){
+ var spaces = match[1].length-1;
+
+ if(spaces > 3){ // unindent one level
+ this.value = this.value.substr(0,linestart)+
+ this.value.substr(linestart+2);
+ selection.start = selection.start - 2;
+ selection.end = selection.start;
+ }else{ // delete list point
+ this.value = this.value.substr(0,linestart)+
+ this.value.substr(selection.start);
+ selection.start = linestart;
+ selection.end = linestart;
+ }
+ setSelection(selection);
+ e.preventDefault(); // prevent backspace
+ return false;
+ }
+ }else if(e.keyCode == 32){ // Space
+ // intend list item
+ var match = search.match(/(\n +)([*-] )$/);
+ if(match){
+ this.value = this.value.substr(0,linestart)+' '+
+ this.value.substr(linestart);
+ selection.start = selection.start + 2;
+ selection.end = selection.start;
+ setSelection(selection);
+ e.preventDefault(); // prevent space
+ return false;
+ }
+ }
+ }
+
+
+};
+
+jQuery(dw_editor.init);
diff --git a/lib/scripts/fileuploader.js b/lib/scripts/fileuploader.js
new file mode 100644
index 000000000..e75b8d3a5
--- /dev/null
+++ b/lib/scripts/fileuploader.js
@@ -0,0 +1,1247 @@
+/**
+ * http://github.com/valums/file-uploader
+ *
+ * Multiple file upload component with progress-bar, drag-and-drop.
+ * © 2010 Andrew Valums ( andrew(at)valums.com )
+ *
+ * Licensed under GNU GPL 2 or later and GNU LGPL 2 or later, see license.txt.
+ */
+
+//
+// Helper functions
+//
+
+var qq = qq || {};
+
+/**
+ * Adds all missing properties from second obj to first obj
+ */
+qq.extend = function(first, second){
+ for (var prop in second){
+ first[prop] = second[prop];
+ }
+};
+
+/**
+ * Searches for a given element in the array, returns -1 if it is not present.
+ * @param {Number} [from] The index at which to begin the search
+ */
+qq.indexOf = function(arr, elt, from){
+ if (arr.indexOf) return arr.indexOf(elt, from);
+
+ from = from || 0;
+ var len = arr.length;
+
+ if (from < 0) from += len;
+
+ for (; from < len; from++){
+ if (from in arr && arr[from] === elt){
+ return from;
+ }
+ }
+ return -1;
+};
+
+qq.getUniqueId = (function(){
+ var id = 0;
+ return function(){ return id++; };
+})();
+
+//
+// Events
+
+qq.attach = function(element, type, fn){
+ if (element.addEventListener){
+ element.addEventListener(type, fn, false);
+ } else if (element.attachEvent){
+ element.attachEvent('on' + type, fn);
+ }
+};
+qq.detach = function(element, type, fn){
+ if (element.removeEventListener){
+ element.removeEventListener(type, fn, false);
+ } else if (element.attachEvent){
+ element.detachEvent('on' + type, fn);
+ }
+};
+
+qq.preventDefault = function(e){
+ if (e.preventDefault){
+ e.preventDefault();
+ } else{
+ e.returnValue = false;
+ }
+};
+
+//
+// Node manipulations
+
+/**
+ * Insert node a before node b.
+ */
+qq.insertBefore = function(a, b){
+ b.parentNode.insertBefore(a, b);
+};
+qq.remove = function(element){
+ element.parentNode.removeChild(element);
+};
+
+qq.contains = function(parent, descendant){
+ // compareposition returns false in this case
+ if (parent == descendant) return true;
+
+ if (parent.contains){
+ return parent.contains(descendant);
+ } else {
+ return !!(descendant.compareDocumentPosition(parent) & 8);
+ }
+};
+
+/**
+ * Creates and returns element from html string
+ * Uses innerHTML to create an element
+ */
+qq.toElement = (function(){
+ var div = document.createElement('div');
+ return function(html){
+ div.innerHTML = html;
+ var element = div.firstChild;
+ div.removeChild(element);
+ return element;
+ };
+})();
+
+//
+// Node properties and attributes
+
+/**
+ * Sets styles for an element.
+ * Fixes opacity in IE6-8.
+ */
+qq.css = function(element, styles){
+ if (styles.opacity != null){
+ if (typeof element.style.opacity != 'string' && typeof(element.filters) != 'undefined'){
+ styles.filter = 'alpha(opacity=' + Math.round(100 * styles.opacity) + ')';
+ }
+ }
+ qq.extend(element.style, styles);
+};
+qq.hasClass = function(element, name){
+ var re = new RegExp('(^| )' + name + '( |$)');
+ return re.test(element.className);
+};
+qq.addClass = function(element, name){
+ if (!qq.hasClass(element, name)){
+ element.className += ' ' + name;
+ }
+};
+qq.removeClass = function(element, name){
+ var re = new RegExp('(^| )' + name + '( |$)');
+ element.className = element.className.replace(re, ' ').replace(/^\s+|\s+$/g, "");
+};
+qq.setText = function(element, text){
+ element.innerText = text;
+ element.textContent = text;
+};
+
+//
+// Selecting elements
+
+qq.children = function(element){
+ var children = [],
+ child = element.firstChild;
+
+ while (child){
+ if (child.nodeType == 1){
+ children.push(child);
+ }
+ child = child.nextSibling;
+ }
+
+ return children;
+};
+
+qq.getByClass = function(element, className){
+ if (element.querySelectorAll){
+ return element.querySelectorAll('.' + className);
+ }
+
+ var result = [];
+ var candidates = element.getElementsByTagName("*");
+ var len = candidates.length;
+
+ for (var i = 0; i < len; i++){
+ if (qq.hasClass(candidates[i], className)){
+ result.push(candidates[i]);
+ }
+ }
+ return result;
+};
+
+/**
+ * obj2url() takes a json-object as argument and generates
+ * a querystring. pretty much like jQuery.param()
+ *
+ * how to use:
+ *
+ * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`
+ *
+ * will result in:
+ *
+ * `http://any.url/upload?otherParam=value&a=b&c=d`
+ *
+ * @param Object JSON-Object
+ * @param String current querystring-part
+ * @return String encoded querystring
+ */
+qq.obj2url = function(obj, temp, prefixDone){
+ var uristrings = [],
+ prefix = '&',
+ add = function(nextObj, i){
+ var nextTemp = temp
+ ? (/\[\]$/.test(temp)) // prevent double-encoding
+ ? temp
+ : temp+'['+i+']'
+ : i;
+ if ((nextTemp != 'undefined') && (i != 'undefined')) {
+ uristrings.push(
+ (typeof nextObj === 'object')
+ ? qq.obj2url(nextObj, nextTemp, true)
+ : (Object.prototype.toString.call(nextObj) === '[object Function]')
+ ? encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj())
+ : encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj)
+ );
+ }
+ };
+
+ if (!prefixDone && temp) {
+ prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? '' : '&' : '?';
+ uristrings.push(temp);
+ uristrings.push(qq.obj2url(obj));
+ } else if ((Object.prototype.toString.call(obj) === '[object Array]') && (typeof obj != 'undefined') ) {
+ // we wont use a for-in-loop on an array (performance)
+ for (var i = 0, len = obj.length; i < len; ++i){
+ add(obj[i], i);
+ }
+ } else if ((typeof obj != 'undefined') && (obj !== null) && (typeof obj === "object")){
+ // for anything else but a scalar, we will use for-in-loop
+ for (var i in obj){
+ add(obj[i], i);
+ }
+ } else {
+ uristrings.push(encodeURIComponent(temp) + '=' + encodeURIComponent(obj));
+ }
+
+ return uristrings.join(prefix)
+ .replace(/^&/, '')
+ .replace(/%20/g, '+');
+};
+
+//
+//
+// Uploader Classes
+//
+//
+
+var qq = qq || {};
+
+/**
+ * Creates upload button, validates upload, but doesn't create file list or dd.
+ */
+qq.FileUploaderBasic = function(o){
+ this._options = {
+ // set to true to see the server response
+ debug: false,
+ action: '/server/upload',
+ params: {},
+ button: null,
+ multiple: true,
+ maxConnections: 3,
+ // validation
+ allowedExtensions: [],
+ sizeLimit: 0,
+ minSizeLimit: 0,
+ // events
+ // return false to cancel submit
+ onSubmit: function(id, fileName){},
+ onProgress: function(id, fileName, loaded, total){},
+ onComplete: function(id, fileName, responseJSON){},
+ onCancel: function(id, fileName){},
+ // messages
+ messages: {
+ typeError: "{file} has invalid extension. Only {extensions} are allowed.",
+ sizeError: "{file} is too large, maximum file size is {sizeLimit}.",
+ minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.",
+ emptyError: "{file} is empty, please select files again without it.",
+ onLeave: "The files are being uploaded, if you leave now the upload will be cancelled."
+ },
+ showMessage: function(message){
+ alert(message);
+ }
+ };
+ qq.extend(this._options, o);
+
+ // number of files being uploaded
+ this._filesInProgress = 0;
+ this._handler = this._createUploadHandler();
+
+ if (this._options.button){
+ this._button = this._createUploadButton(this._options.button);
+ }
+
+ this._preventLeaveInProgress();
+};
+
+qq.FileUploaderBasic.prototype = {
+ setParams: function(params){
+ this._options.params = params;
+ },
+ getInProgress: function(){
+ return this._filesInProgress;
+ },
+ _createUploadButton: function(element){
+ var self = this;
+
+ return new qq.UploadButton({
+ element: element,
+ multiple: this._options.multiple && qq.UploadHandlerXhr.isSupported(),
+ onChange: function(input){
+ self._onInputChange(input);
+ }
+ });
+ },
+ _createUploadHandler: function(){
+ var self = this,
+ handlerClass;
+
+ if(qq.UploadHandlerXhr.isSupported()){
+ handlerClass = 'UploadHandlerXhr';
+ } else {
+ handlerClass = 'UploadHandlerForm';
+ }
+
+ var handler = new qq[handlerClass]({
+ debug: this._options.debug,
+ action: this._options.action,
+ maxConnections: this._options.maxConnections,
+ onProgress: function(id, fileName, loaded, total){
+ self._onProgress(id, fileName, loaded, total);
+ self._options.onProgress(id, fileName, loaded, total);
+ },
+ onComplete: function(id, fileName, result){
+ self._onComplete(id, fileName, result);
+ self._options.onComplete(id, fileName, result);
+ },
+ onCancel: function(id, fileName){
+ self._onCancel(id, fileName);
+ self._options.onCancel(id, fileName);
+ }
+ });
+
+ return handler;
+ },
+ _preventLeaveInProgress: function(){
+ var self = this;
+
+ qq.attach(window, 'beforeunload', function(e){
+ if (!self._filesInProgress){return;}
+
+ var e = e || window.event;
+ // for ie, ff
+ e.returnValue = self._options.messages.onLeave;
+ // for webkit
+ return self._options.messages.onLeave;
+ });
+ },
+ _onSubmit: function(id, fileName){
+ this._filesInProgress++;
+ },
+ _onProgress: function(id, fileName, loaded, total){
+ },
+ _onComplete: function(id, fileName, result){
+ this._filesInProgress--;
+ if (result.error){
+ this._options.showMessage(result.error);
+ }
+ },
+ _onCancel: function(id, fileName){
+ this._filesInProgress--;
+ },
+ _onInputChange: function(input){
+ if (this._handler instanceof qq.UploadHandlerXhr){
+ this._uploadFileList(input.files);
+ } else {
+ if (this._validateFile(input)){
+ this._uploadFile(input);
+ }
+ }
+ this._button.reset();
+ },
+ _uploadFileList: function(files){
+ for (var i=0; i<files.length; i++){
+ if ( !this._validateFile(files[i])){
+ return;
+ }
+ }
+
+ for (var i=0; i<files.length; i++){
+ this._uploadFile(files[i]);
+ }
+ },
+ _uploadFile: function(fileContainer){
+ var id = this._handler.add(fileContainer);
+ var fileName = this._handler.getName(id);
+
+ if (this._options.onSubmit(id, fileName) !== false){
+ this._onSubmit(id, fileName);
+ this._handler.upload(id, this._options.params);
+ }
+ },
+ _validateFile: function(file){
+ var name, size;
+
+ if (file.value){
+ // it is a file input
+ // get input value and remove path to normalize
+ name = file.value.replace(/.*(\/|\\)/, "");
+ } else {
+ // fix missing properties in Safari
+ name = file.fileName != null ? file.fileName : file.name;
+ size = file.fileSize != null ? file.fileSize : file.size;
+ }
+
+ if (! this._isAllowedExtension(name)){
+ this._error('typeError', name);
+ return false;
+
+ } else if (size === 0){
+ this._error('emptyError', name);
+ return false;
+
+ } else if (size && this._options.sizeLimit && size > this._options.sizeLimit){
+ this._error('sizeError', name);
+ return false;
+
+ } else if (size && size < this._options.minSizeLimit){
+ this._error('minSizeError', name);
+ return false;
+ }
+
+ return true;
+ },
+ _error: function(code, fileName){
+ var message = this._options.messages[code];
+ function r(name, replacement){ message = message.replace(name, replacement); }
+
+ r('{file}', this._formatFileName(fileName));
+ r('{extensions}', this._options.allowedExtensions.join(', '));
+ r('{sizeLimit}', this._formatSize(this._options.sizeLimit));
+ r('{minSizeLimit}', this._formatSize(this._options.minSizeLimit));
+
+ this._options.showMessage(message);
+ },
+ _formatFileName: function(name){
+ if (name.length > 33){
+ name = name.slice(0, 19) + '...' + name.slice(-13);
+ }
+ return name;
+ },
+ _isAllowedExtension: function(fileName){
+ var ext = (-1 !== fileName.indexOf('.')) ? fileName.replace(/.*[.]/, '').toLowerCase() : '';
+ var allowed = this._options.allowedExtensions;
+
+ if (!allowed.length){return true;}
+
+ for (var i=0; i<allowed.length; i++){
+ if (allowed[i].toLowerCase() == ext){ return true;}
+ }
+
+ return false;
+ },
+ _formatSize: function(bytes){
+ var i = -1;
+ do {
+ bytes = bytes / 1024;
+ i++;
+ } while (bytes > 99);
+
+ return Math.max(bytes, 0.1).toFixed(1) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];
+ }
+};
+
+
+/**
+ * Class that creates upload widget with drag-and-drop and file list
+ * @inherits qq.FileUploaderBasic
+ */
+qq.FileUploader = function(o){
+ // call parent constructor
+ qq.FileUploaderBasic.apply(this, arguments);
+
+ // additional options
+ qq.extend(this._options, {
+ element: null,
+ // if set, will be used instead of qq-upload-list in template
+ listElement: null,
+
+ template: '<div class="qq-uploader">' +
+ '<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
+ '<div class="qq-upload-button">Upload a file</div>' +
+ '<ul class="qq-upload-list"></ul>' +
+ '</div>',
+
+ // template for one item in file list
+ fileTemplate: '<li>' +
+ '<span class="qq-upload-file"></span>' +
+ '<span class="qq-upload-spinner"></span>' +
+ '<span class="qq-upload-size"></span>' +
+ '<a class="qq-upload-cancel" href="#">Cancel</a>' +
+ '<span class="qq-upload-failed-text">Failed</span>' +
+ '</li>',
+
+ classes: {
+ // used to get elements from templates
+ button: 'qq-upload-button',
+ drop: 'qq-upload-drop-area',
+ dropActive: 'qq-upload-drop-area-active',
+ list: 'qq-upload-list',
+
+ file: 'qq-upload-file',
+ spinner: 'qq-upload-spinner',
+ size: 'qq-upload-size',
+ cancel: 'qq-upload-cancel',
+
+ // added to list item when upload completes
+ // used in css to hide progress spinner
+ success: 'qq-upload-success',
+ fail: 'qq-upload-fail'
+ }
+ });
+ // overwrite options with user supplied
+ qq.extend(this._options, o);
+
+ this._element = this._options.element;
+ this._element.innerHTML = this._options.template;
+ this._listElement = this._options.listElement || this._find(this._element, 'list');
+
+ this._classes = this._options.classes;
+
+ this._button = this._createUploadButton(this._find(this._element, 'button'));
+
+ this._bindCancelEvent();
+ this._setupDragDrop();
+};
+
+// inherit from Basic Uploader
+qq.extend(qq.FileUploader.prototype, qq.FileUploaderBasic.prototype);
+
+qq.extend(qq.FileUploader.prototype, {
+ /**
+ * Gets one of the elements listed in this._options.classes
+ **/
+ _find: function(parent, type){
+ var element = qq.getByClass(parent, this._options.classes[type])[0];
+ if (!element){
+ throw new Error('element not found ' + type);
+ }
+
+ return element;
+ },
+ _setupDragDrop: function(){
+ var self = this,
+ dropArea = this._find(this._element, 'drop');
+
+ var dz = new qq.UploadDropZone({
+ element: dropArea,
+ onEnter: function(e){
+ qq.addClass(dropArea, self._classes.dropActive);
+ e.stopPropagation();
+ },
+ onLeave: function(e){
+ e.stopPropagation();
+ },
+ onLeaveNotDescendants: function(e){
+ qq.removeClass(dropArea, self._classes.dropActive);
+ },
+ onDrop: function(e){
+ dropArea.style.display = 'none';
+ qq.removeClass(dropArea, self._classes.dropActive);
+ self._uploadFileList(e.dataTransfer.files);
+ }
+ });
+
+ dropArea.style.display = 'none';
+
+ qq.attach(document, 'dragenter', function(e){
+ if (!dz._isValidFileDrag(e)) return;
+
+ dropArea.style.display = 'block';
+ });
+ qq.attach(document, 'dragleave', function(e){
+ if (!dz._isValidFileDrag(e)) return;
+
+ var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
+ // only fire when leaving document out
+ if ( ! relatedTarget || relatedTarget.nodeName == "HTML"){
+ dropArea.style.display = 'none';
+ }
+ });
+ },
+ _onSubmit: function(id, fileName){
+ qq.FileUploaderBasic.prototype._onSubmit.apply(this, arguments);
+ this._addToList(id, fileName);
+ },
+ _onProgress: function(id, fileName, loaded, total){
+ qq.FileUploaderBasic.prototype._onProgress.apply(this, arguments);
+
+ var item = this._getItemByFileId(id);
+ var size = this._find(item, 'size');
+ size.style.display = 'inline';
+
+ var text;
+ if (loaded != total){
+ text = Math.round(loaded / total * 100) + '% from ' + this._formatSize(total);
+ } else {
+ text = this._formatSize(total);
+ }
+
+ qq.setText(size, text);
+ },
+ _onComplete: function(id, fileName, result){
+ qq.FileUploaderBasic.prototype._onComplete.apply(this, arguments);
+
+ // mark completed
+ var item = this._getItemByFileId(id);
+ qq.remove(this._find(item, 'cancel'));
+ qq.remove(this._find(item, 'spinner'));
+
+ if (result.success){
+ qq.addClass(item, this._classes.success);
+ } else {
+ qq.addClass(item, this._classes.fail);
+ }
+ },
+ _addToList: function(id, fileName){
+ var item = qq.toElement(this._options.fileTemplate);
+ item.qqFileId = id;
+
+ var fileElement = this._find(item, 'file');
+ qq.setText(fileElement, this._formatFileName(fileName));
+ this._find(item, 'size').style.display = 'none';
+
+ this._listElement.appendChild(item);
+ },
+ _getItemByFileId: function(id){
+ var item = this._listElement.firstChild;
+
+ // there can't be txt nodes in dynamically created list
+ // and we can use nextSibling
+ while (item){
+ if (item.qqFileId == id) return item;
+ item = item.nextSibling;
+ }
+ },
+ /**
+ * delegate click event for cancel link
+ **/
+ _bindCancelEvent: function(){
+ var self = this,
+ list = this._listElement;
+
+ qq.attach(list, 'click', function(e){
+ e = e || window.event;
+ var target = e.target || e.srcElement;
+
+ if (qq.hasClass(target, self._classes.cancel)){
+ qq.preventDefault(e);
+
+ var item = target.parentNode;
+ self._handler.cancel(item.qqFileId);
+ qq.remove(item);
+ }
+ });
+ }
+});
+
+qq.UploadDropZone = function(o){
+ this._options = {
+ element: null,
+ onEnter: function(e){},
+ onLeave: function(e){},
+ // is not fired when leaving element by hovering descendants
+ onLeaveNotDescendants: function(e){},
+ onDrop: function(e){}
+ };
+ qq.extend(this._options, o);
+
+ this._element = this._options.element;
+
+ this._disableDropOutside();
+ this._attachEvents();
+};
+
+qq.UploadDropZone.prototype = {
+ _disableDropOutside: function(e){
+ // run only once for all instances
+ if (!qq.UploadDropZone.dropOutsideDisabled ){
+
+ qq.attach(document, 'dragover', function(e){
+ if (e.dataTransfer){
+ e.dataTransfer.dropEffect = 'none';
+ e.preventDefault();
+ }
+ });
+
+ qq.UploadDropZone.dropOutsideDisabled = true;
+ }
+ },
+ _attachEvents: function(){
+ var self = this;
+
+ qq.attach(self._element, 'dragover', function(e){
+ if (!self._isValidFileDrag(e)) return;
+
+ var effect = e.dataTransfer.effectAllowed;
+ if (effect == 'move' || effect == 'linkMove'){
+ e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed)
+ } else {
+ e.dataTransfer.dropEffect = 'copy'; // for Chrome
+ }
+
+ e.stopPropagation();
+ e.preventDefault();
+ });
+
+ qq.attach(self._element, 'dragenter', function(e){
+ if (!self._isValidFileDrag(e)) return;
+
+ self._options.onEnter(e);
+ });
+
+ qq.attach(self._element, 'dragleave', function(e){
+ if (!self._isValidFileDrag(e)) return;
+
+ self._options.onLeave(e);
+
+ var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
+ // do not fire when moving a mouse over a descendant
+ if (qq.contains(this, relatedTarget)) return;
+
+ self._options.onLeaveNotDescendants(e);
+ });
+
+ qq.attach(self._element, 'drop', function(e){
+ if (!self._isValidFileDrag(e)) return;
+
+ e.preventDefault();
+ self._options.onDrop(e);
+ });
+ },
+ _isValidFileDrag: function(e){
+ var dt = e.dataTransfer,
+ // do not check dt.types.contains in webkit, because it crashes safari 4
+ isWebkit = navigator.userAgent.indexOf("AppleWebKit") > -1;
+
+ // dt.effectAllowed is none in Safari 5
+ // dt.types.contains check is for firefox
+ return dt && dt.effectAllowed != 'none' &&
+ (dt.files || (!isWebkit && dt.types.contains && dt.types.contains('Files')));
+
+ }
+};
+
+qq.UploadButton = function(o){
+ this._options = {
+ element: null,
+ // if set to true adds multiple attribute to file input
+ multiple: false,
+ // name attribute of file input
+ name: 'file',
+ onChange: function(input){},
+ hoverClass: 'qq-upload-button-hover',
+ focusClass: 'qq-upload-button-focus'
+ };
+
+ qq.extend(this._options, o);
+
+ this._element = this._options.element;
+
+ // make button suitable container for input
+ qq.css(this._element, {
+ position: 'relative',
+ overflow: 'hidden',
+ // Make sure browse button is in the right side
+ // in Internet Explorer
+ direction: 'ltr'
+ });
+
+ this._input = this._createInput();
+};
+
+qq.UploadButton.prototype = {
+ /* returns file input element */
+ getInput: function(){
+ return this._input;
+ },
+ /* cleans/recreates the file input */
+ reset: function(){
+ if (this._input.parentNode){
+ qq.remove(this._input);
+ }
+
+ qq.removeClass(this._element, this._options.focusClass);
+ this._input = this._createInput();
+ },
+ _createInput: function(){
+ var input = document.createElement("input");
+
+ if (this._options.multiple){
+ input.setAttribute("multiple", "multiple");
+ }
+
+ input.setAttribute("type", "file");
+ input.setAttribute("name", this._options.name);
+
+ qq.css(input, {
+ position: 'absolute',
+ // in Opera only 'browse' button
+ // is clickable and it is located at
+ // the right side of the input
+ right: 0,
+ top: 0,
+ fontFamily: 'Arial',
+ // 4 persons reported this, the max values that worked for them were 243, 236, 236, 118
+ fontSize: '118px',
+ margin: 0,
+ padding: 0,
+ cursor: 'pointer',
+ opacity: 0
+ });
+
+ this._element.appendChild(input);
+
+ var self = this;
+ qq.attach(input, 'change', function(){
+ self._options.onChange(input);
+ });
+
+ qq.attach(input, 'mouseover', function(){
+ qq.addClass(self._element, self._options.hoverClass);
+ });
+ qq.attach(input, 'mouseout', function(){
+ qq.removeClass(self._element, self._options.hoverClass);
+ });
+ qq.attach(input, 'focus', function(){
+ qq.addClass(self._element, self._options.focusClass);
+ });
+ qq.attach(input, 'blur', function(){
+ qq.removeClass(self._element, self._options.focusClass);
+ });
+
+ // IE and Opera, unfortunately have 2 tab stops on file input
+ // which is unacceptable in our case, disable keyboard access
+ if (window.attachEvent){
+ // it is IE or Opera
+ input.setAttribute('tabIndex', "-1");
+ }
+
+ return input;
+ }
+};
+
+/**
+ * Class for uploading files, uploading itself is handled by child classes
+ */
+qq.UploadHandlerAbstract = function(o){
+ this._options = {
+ debug: false,
+ action: '/upload.php',
+ // maximum number of concurrent uploads
+ maxConnections: 999,
+ onProgress: function(id, fileName, loaded, total){},
+ onComplete: function(id, fileName, response){},
+ onCancel: function(id, fileName){}
+ };
+ qq.extend(this._options, o);
+
+ this._queue = [];
+ // params for files in queue
+ this._params = [];
+};
+qq.UploadHandlerAbstract.prototype = {
+ log: function(str){
+ if (this._options.debug && window.console) console.log('[uploader] ' + str);
+ },
+ /**
+ * Adds file or file input to the queue
+ * @returns id
+ **/
+ add: function(file){},
+ /**
+ * Sends the file identified by id and additional query params to the server
+ */
+ upload: function(id, params){
+ var len = this._queue.push(id);
+
+ var copy = {};
+ qq.extend(copy, params);
+ this._params[id] = copy;
+
+ // if too many active uploads, wait...
+ if (len <= this._options.maxConnections){
+ this._upload(id, this._params[id]);
+ }
+ },
+ /**
+ * Cancels file upload by id
+ */
+ cancel: function(id){
+ this._cancel(id);
+ this._dequeue(id);
+ },
+ /**
+ * Cancells all uploads
+ */
+ cancelAll: function(){
+ for (var i=0; i<this._queue.length; i++){
+ this._cancel(this._queue[i]);
+ }
+ this._queue = [];
+ },
+ /**
+ * Returns name of the file identified by id
+ */
+ getName: function(id){},
+ /**
+ * Returns size of the file identified by id
+ */
+ getSize: function(id){},
+ /**
+ * Returns id of files being uploaded or
+ * waiting for their turn
+ */
+ getQueue: function(){
+ return this._queue;
+ },
+ /**
+ * Actual upload method
+ */
+ _upload: function(id){},
+ /**
+ * Actual cancel method
+ */
+ _cancel: function(id){},
+ /**
+ * Removes element from queue, starts upload of next
+ */
+ _dequeue: function(id){
+ var i = qq.indexOf(this._queue, id);
+ this._queue.splice(i, 1);
+
+ var max = this._options.maxConnections;
+
+ if (this._queue.length >= max && i < max){
+ var nextId = this._queue[max-1];
+ this._upload(nextId, this._params[nextId]);
+ }
+ }
+};
+
+/**
+ * Class for uploading files using form and iframe
+ * @inherits qq.UploadHandlerAbstract
+ */
+qq.UploadHandlerForm = function(o){
+ qq.UploadHandlerAbstract.apply(this, arguments);
+
+ this._inputs = {};
+};
+// @inherits qq.UploadHandlerAbstract
+qq.extend(qq.UploadHandlerForm.prototype, qq.UploadHandlerAbstract.prototype);
+
+qq.extend(qq.UploadHandlerForm.prototype, {
+ add: function(fileInput){
+ fileInput.setAttribute('name', 'qqfile');
+ var id = 'qq-upload-handler-iframe' + qq.getUniqueId();
+
+ this._inputs[id] = fileInput;
+
+ // remove file input from DOM
+ if (fileInput.parentNode){
+ qq.remove(fileInput);
+ }
+
+ return id;
+ },
+ getName: function(id){
+ // get input value and remove path to normalize
+ return this._inputs[id].value.replace(/.*(\/|\\)/, "");
+ },
+ _cancel: function(id){
+ this._options.onCancel(id, this.getName(id));
+
+ delete this._inputs[id];
+
+ var iframe = document.getElementById(id);
+ if (iframe){
+ // to cancel request set src to something else
+ // we use src="javascript:false;" because it doesn't
+ // trigger ie6 prompt on https
+ iframe.setAttribute('src', 'javascript:false;');
+
+ qq.remove(iframe);
+ }
+ },
+ _upload: function(id, params){
+ var input = this._inputs[id];
+
+ if (!input){
+ throw new Error('file with passed id was not added, or already uploaded or cancelled');
+ }
+
+ var fileName = this.getName(id);
+
+ var iframe = this._createIframe(id);
+ var form = this._createForm(iframe, params);
+ form.appendChild(input);
+
+ var self = this;
+ this._attachLoadEvent(iframe, function(){
+ self.log('iframe loaded');
+
+ var response = self._getIframeContentJSON(iframe);
+
+ self._options.onComplete(id, fileName, response);
+ self._dequeue(id);
+
+ delete self._inputs[id];
+ // timeout added to fix busy state in FF3.6
+ setTimeout(function(){
+ qq.remove(iframe);
+ }, 1);
+ });
+
+ form.submit();
+ qq.remove(form);
+
+ return id;
+ },
+ _attachLoadEvent: function(iframe, callback){
+ qq.attach(iframe, 'load', function(){
+ // when we remove iframe from dom
+ // the request stops, but in IE load
+ // event fires
+ if (!iframe.parentNode){
+ return;
+ }
+
+ // fixing Opera 10.53
+ if (iframe.contentDocument &&
+ iframe.contentDocument.body &&
+ iframe.contentDocument.body.innerHTML == "false"){
+ // In Opera event is fired second time
+ // when body.innerHTML changed from false
+ // to server response approx. after 1 sec
+ // when we upload file with iframe
+ return;
+ }
+
+ callback();
+ });
+ },
+ /**
+ * Returns json object received by iframe from server.
+ */
+ _getIframeContentJSON: function(iframe){
+ // iframe.contentWindow.document - for IE<7
+ var doc = iframe.contentDocument ? iframe.contentDocument: iframe.contentWindow.document,
+ response;
+
+ this.log("converting iframe's innerHTML to JSON");
+ this.log("innerHTML = " + doc.body.innerHTML);
+
+ try {
+ response = eval("(" + doc.body.innerHTML + ")");
+ } catch(err){
+ response = {};
+ }
+
+ return response;
+ },
+ /**
+ * Creates iframe with unique name
+ */
+ _createIframe: function(id){
+ // We can't use following code as the name attribute
+ // won't be properly registered in IE6, and new window
+ // on form submit will open
+ // var iframe = document.createElement('iframe');
+ // iframe.setAttribute('name', id);
+
+ var iframe = qq.toElement('<iframe src="javascript:false;" name="' + id + '" />');
+ // src="javascript:false;" removes ie6 prompt on https
+
+ iframe.setAttribute('id', id);
+
+ iframe.style.display = 'none';
+ document.body.appendChild(iframe);
+
+ return iframe;
+ },
+ /**
+ * Creates form, that will be submitted to iframe
+ */
+ _createForm: function(iframe, params){
+ // We can't use the following code in IE6
+ // var form = document.createElement('form');
+ // form.setAttribute('method', 'post');
+ // form.setAttribute('enctype', 'multipart/form-data');
+ // Because in this case file won't be attached to request
+ var form = qq.toElement('<form method="post" enctype="multipart/form-data"></form>');
+
+ var queryString = qq.obj2url(params, this._options.action);
+
+ form.setAttribute('action', queryString);
+ form.setAttribute('target', iframe.name);
+ form.style.display = 'none';
+ document.body.appendChild(form);
+
+ return form;
+ }
+});
+
+/**
+ * Class for uploading files using xhr
+ * @inherits qq.UploadHandlerAbstract
+ */
+qq.UploadHandlerXhr = function(o){
+ qq.UploadHandlerAbstract.apply(this, arguments);
+
+ this._files = [];
+ this._xhrs = [];
+
+ // current loaded size in bytes for each file
+ this._loaded = [];
+};
+
+// static method
+qq.UploadHandlerXhr.isSupported = function(){
+ var input = document.createElement('input');
+ input.type = 'file';
+
+ return (
+ 'multiple' in input &&
+ typeof File != "undefined" &&
+ typeof (new XMLHttpRequest()).upload != "undefined" );
+};
+
+// @inherits qq.UploadHandlerAbstract
+qq.extend(qq.UploadHandlerXhr.prototype, qq.UploadHandlerAbstract.prototype);
+
+qq.extend(qq.UploadHandlerXhr.prototype, {
+ /**
+ * Adds file to the queue
+ * Returns id to use with upload, cancel
+ **/
+ add: function(file){
+ if (!(file instanceof File)){
+ throw new Error('Passed obj in not a File (in qq.UploadHandlerXhr)');
+ }
+
+ return this._files.push(file) - 1;
+ },
+ getName: function(id){
+ var file = this._files[id];
+ // fix missing name in Safari 4
+ return file.fileName != null ? file.fileName : file.name;
+ },
+ getSize: function(id){
+ var file = this._files[id];
+ return file.fileSize != null ? file.fileSize : file.size;
+ },
+ /**
+ * Returns uploaded bytes for file identified by id
+ */
+ getLoaded: function(id){
+ return this._loaded[id] || 0;
+ },
+ /**
+ * Sends the file identified by id and additional query params to the server
+ * @param {Object} params name-value string pairs
+ */
+ _upload: function(id, params){
+ var file = this._files[id],
+ name = this.getName(id),
+ size = this.getSize(id);
+
+ this._loaded[id] = 0;
+
+ var xhr = this._xhrs[id] = new XMLHttpRequest();
+ var self = this;
+
+ xhr.upload.onprogress = function(e){
+ if (e.lengthComputable){
+ self._loaded[id] = e.loaded;
+ self._options.onProgress(id, name, e.loaded, e.total);
+ }
+ };
+
+ xhr.onreadystatechange = function(){
+ if (xhr.readyState == 4){
+ self._onComplete(id, xhr);
+ }
+ };
+
+ // build query string
+ params = params || {};
+ params['qqfile'] = name;
+ var queryString = qq.obj2url(params, this._options.action);
+
+ xhr.open("POST", queryString, true);
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
+ xhr.setRequestHeader("Content-Type", "application/octet-stream");
+ xhr.send(file);
+ },
+ _onComplete: function(id, xhr){
+ // the request was aborted/cancelled
+ if (!this._files[id]) return;
+
+ var name = this.getName(id);
+ var size = this.getSize(id);
+
+ this._options.onProgress(id, name, size, size);
+
+ if (xhr.status == 200){
+ this.log("xhr - server response received");
+ this.log("responseText = " + xhr.responseText);
+
+ var response;
+
+ try {
+ response = eval("(" + xhr.responseText + ")");
+ } catch(err){
+ response = {};
+ }
+
+ this._options.onComplete(id, name, response);
+
+ } else {
+ this._options.onComplete(id, name, {});
+ }
+
+ this._files[id] = null;
+ this._xhrs[id] = null;
+ this._dequeue(id);
+ },
+ _cancel: function(id){
+ this._options.onCancel(id, this.getName(id));
+
+ this._files[id] = null;
+
+ if (this._xhrs[id]){
+ this._xhrs[id].abort();
+ this._xhrs[id] = null;
+ }
+ }
+}); \ No newline at end of file
diff --git a/lib/scripts/fileuploaderextended.js b/lib/scripts/fileuploaderextended.js
new file mode 100644
index 000000000..4abd63bef
--- /dev/null
+++ b/lib/scripts/fileuploaderextended.js
@@ -0,0 +1,344 @@
+qq.extend(qq.FileUploader.prototype, {
+ _createUploadHandler: function(){
+ var self = this,
+ handlerClass;
+
+ if(qq.UploadHandlerXhr.isSupported()){
+ handlerClass = 'UploadHandlerXhr';
+ //handlerClass = 'UploadHandlerForm';
+ } else {
+ handlerClass = 'UploadHandlerForm';
+ }
+
+ var handler = new qq[handlerClass]({
+ debug: this._options.debug,
+ action: this._options.action,
+ maxConnections: this._options.maxConnections,
+ onProgress: function(id, fileName, loaded, total){
+ self._onProgress(id, fileName, loaded, total);
+ self._options.onProgress(id, fileName, loaded, total);
+ },
+ onComplete: function(id, fileName, result){
+ self._onComplete(id, fileName, result);
+ self._options.onComplete(id, fileName, result);
+ },
+ onCancel: function(id, fileName){
+ self._onCancel(id, fileName);
+ self._options.onCancel(id, fileName);
+ },
+ onUpload: function(){
+ self._onUpload();
+ }
+ });
+
+ return handler;
+ },
+
+ _onUpload: function(){
+ this._handler.uploadAll(this._options.params);
+ },
+
+ _uploadFile: function(fileContainer){
+ var id = this._handler.add(fileContainer);
+ var fileName = this._handler.getName(id);
+
+ if (this._options.onSubmit(id, fileName) !== false){
+ this._onSubmit(id, fileName);
+ }
+ },
+
+ _addToList: function(id, fileName){
+ var item = qq.toElement(this._options.fileTemplate);
+ item.qqFileId = id;
+
+ var fileElement = this._find(item, 'file');
+ qq.setText(fileElement, fileName);
+ this._find(item, 'size').style.display = 'none';
+
+ // name suggestion (simplified cleanID)
+ var nameElement = this._find(item, 'nameInput');
+ fileName = fileName.toLowerCase();
+ fileName = fileName.replace(/([ !"#$%&\'()+,\/;<=>?@[\]^`{|}~:]+)/g, '_');
+ fileName = fileName.replace(/^_+/,'');
+ nameElement.value = fileName;
+ nameElement.id = 'mediamanager__upload_item'+id;
+
+ this._listElement.appendChild(item);
+ }
+
+});
+
+qq.FileUploaderExtended = function(o){
+ // call parent constructor
+ qq.FileUploaderBasic.apply(this, arguments);
+
+ qq.extend(this._options, {
+ element: null,
+ // if set, will be used instead of qq-upload-list in template
+ listElement: null,
+
+ template: '<div class="qq-uploader">' +
+ '<div class="qq-upload-drop-area"><span>' + LANG.media_drop + '</span></div>' +
+ '<div class="qq-upload-button">' + LANG.media_select + '</div>' +
+ '<ul class="qq-upload-list"></ul>' +
+ '<div class="qq-action-container">' +
+ ' <input class="qq-upload-action button" type="submit" value="' + LANG.media_upload_btn + '" id="mediamanager__upload_button">' +
+ ' <label class="qq-overwrite-check"><input type="checkbox" value="1" name="ow" class="dw__ow"> <span>' + LANG.media_overwrt + '</span></label>' +
+ '</div>' +
+ '</div>',
+
+ // template for one item in file list
+ fileTemplate: '<li>' +
+ '<span class="qq-upload-file hidden"></span>' +
+ ' <input class="qq-upload-name-input edit" type="text" value="" />' +
+ ' <span class="qq-upload-spinner hidden"></span>' +
+ ' <span class="qq-upload-size"></span>' +
+ ' <a class="qq-upload-cancel" href="#">' + LANG.media_cancel + '</a>' +
+ ' <span class="qq-upload-failed-text error">Failed</span>' +
+ '</li>',
+
+ classes: {
+ // used to get elements from templates
+ button: 'qq-upload-button',
+ drop: 'qq-upload-drop-area',
+ dropActive: 'qq-upload-drop-area-active',
+ list: 'qq-upload-list',
+ nameInput: 'qq-upload-name-input',
+ overwriteInput: 'qq-overwrite-check',
+ uploadButton: 'qq-upload-action',
+ file: 'qq-upload-file',
+
+ spinner: 'qq-upload-spinner',
+ size: 'qq-upload-size',
+ cancel: 'qq-upload-cancel',
+
+ // added to list item when upload completes
+ // used in css to hide progress spinner
+ success: 'qq-upload-success',
+ fail: 'qq-upload-fail',
+ failedText: 'qq-upload-failed-text'
+ }
+ });
+
+ qq.extend(this._options, o);
+
+ this._element = this._options.element;
+ this._element.innerHTML = this._options.template;
+ this._listElement = this._options.listElement || this._find(this._element, 'list');
+
+ this._classes = this._options.classes;
+
+ this._button = this._createUploadButton(this._find(this._element, 'button'));
+
+ this._bindCancelEvent();
+ this._bindUploadEvent();
+ this._setupDragDrop();
+};
+
+qq.extend(qq.FileUploaderExtended.prototype, qq.FileUploader.prototype);
+
+qq.extend(qq.FileUploaderExtended.prototype, {
+ _bindUploadEvent: function(){
+ var self = this,
+ list = this._listElement;
+
+ qq.attach(document.getElementById('mediamanager__upload_button'), 'click', function(e){
+ e = e || window.event;
+ var target = e.target || e.srcElement;
+ qq.preventDefault(e);
+ self._handler._options.onUpload();
+
+ jQuery(".qq-upload-name-input").each(function (i) {
+ jQuery(this).attr('disabled', 'disabled');
+ });
+ });
+ },
+
+ _onComplete: function(id, fileName, result){
+ this._filesInProgress--;
+
+ // mark completed
+ var item = this._getItemByFileId(id);
+ qq.remove(this._find(item, 'cancel'));
+ qq.remove(this._find(item, 'spinner'));
+
+ var nameInput = this._find(item, 'nameInput');
+ var fileElement = this._find(item, 'file');
+ qq.setText(fileElement, nameInput.value);
+ qq.removeClass(fileElement, 'hidden');
+ qq.remove(nameInput);
+ jQuery('.qq-upload-button, #mediamanager__upload_button').remove();
+ jQuery('.dw__ow').parent().hide();
+ jQuery('.qq-upload-drop-area').remove();
+
+ if (result.success){
+ qq.addClass(item, this._classes.success);
+ $link = '<a href="' + result.link + '" name="h_:' + result.id + '" class="select">' + nameInput.value + '</a>';
+ jQuery(fileElement).html($link);
+
+ } else {
+ qq.addClass(item, this._classes.fail);
+ var fail = this._find(item, 'failedText');
+ if (result.error) qq.setText(fail, result.error);
+ }
+
+ if (document.getElementById('media__content') && !document.getElementById('mediamanager__done_form')) {
+ var action = document.location.href;
+ var i = action.indexOf('?');
+ if (i) action = action.substr(0, i);
+ var button = '<form method="post" action="' + action + '" id="mediamanager__done_form"><div>';
+ button += '<input type="hidden" value="' + result.ns + '" name="ns">';
+ button += '<input class="button" type="submit" value="' + LANG.media_done_btn + '"></div></form>';
+ jQuery('#mediamanager__uploader').append(button);
+ }
+ }
+
+});
+
+qq.extend(qq.UploadHandlerForm.prototype, {
+ uploadAll: function(params){
+ this._uploadAll(params);
+ },
+
+ getName: function(id){
+ var file = this._inputs[id];
+ var name = document.getElementById('mediamanager__upload_item'+id);
+ if (name != null) {
+ return name.value;
+ } else {
+ if (file != null) {
+ // get input value and remove path to normalize
+ return file.value.replace(/.*(\/|\\)/, "");
+ } else {
+ return null;
+ }
+ }
+ },
+
+ _uploadAll: function(params){
+ jQuery(".qq-upload-spinner").each(function (i) {
+ jQuery(this).removeClass('hidden');
+ });
+ for (key in this._inputs) {
+ this.upload(key, params);
+ }
+
+ },
+
+ _upload: function(id, params){
+ var input = this._inputs[id];
+
+ if (!input){
+ throw new Error('file with passed id was not added, or already uploaded or cancelled');
+ }
+
+ var fileName = this.getName(id);
+
+ var iframe = this._createIframe(id);
+ var form = this._createForm(iframe, params);
+ form.appendChild(input);
+
+ var nameInput = qq.toElement('<input name="mediaid" value="' + fileName + '" type="text">');
+ form.appendChild(nameInput);
+
+ var checked = jQuery('.dw__ow').attr('checked');
+ var owCheckbox = jQuery('.dw__ow').clone();
+ owCheckbox.attr('checked', checked);
+ jQuery(form).append(owCheckbox);
+
+ var self = this;
+ this._attachLoadEvent(iframe, function(){
+ self.log('iframe loaded');
+
+ var response = self._getIframeContentJSON(iframe);
+
+ self._options.onComplete(id, fileName, response);
+ self._dequeue(id);
+
+ delete self._inputs[id];
+ // timeout added to fix busy state in FF3.6
+ setTimeout(function(){
+ qq.remove(iframe);
+ }, 1);
+ });
+
+ form.submit();
+ qq.remove(form);
+
+ return id;
+ }
+});
+
+qq.extend(qq.UploadHandlerXhr.prototype, {
+ uploadAll: function(params){
+ this._uploadAll(params);
+ },
+
+ getName: function(id){
+ var file = this._files[id];
+ var name = document.getElementById('mediamanager__upload_item'+id);
+ if (name != null) {
+ return name.value;
+ } else {
+ if (file != null) {
+ // fix missing name in Safari 4
+ return file.fileName != null ? file.fileName : file.name;
+ } else {
+ return null;
+ }
+ }
+ },
+
+ getSize: function(id){
+ var file = this._files[id];
+ if (file == null) return null;
+ return file.fileSize != null ? file.fileSize : file.size;
+ },
+
+ _upload: function(id, params){
+ var file = this._files[id],
+ name = this.getName(id),
+ size = this.getSize(id);
+ if (name == null || size == null) return;
+
+ this._loaded[id] = 0;
+
+ var xhr = this._xhrs[id] = new XMLHttpRequest();
+ var self = this;
+
+ xhr.upload.onprogress = function(e){
+ if (e.lengthComputable){
+ self._loaded[id] = e.loaded;
+ self._options.onProgress(id, name, e.loaded, e.total);
+ }
+ };
+
+ xhr.onreadystatechange = function(){
+ if (xhr.readyState == 4){
+ self._onComplete(id, xhr);
+ }
+ };
+
+ // build query string
+ params = params || {};
+ params['qqfile'] = name;
+ params['ow'] = jQuery('.dw__ow').attr('checked');
+ var queryString = qq.obj2url(params, this._options.action);
+
+ xhr.open("POST", queryString, true);
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
+ xhr.setRequestHeader("Content-Type", "application/octet-stream");
+ xhr.send(file);
+ },
+
+ _uploadAll: function(params){
+ jQuery(".qq-upload-spinner").each(function (i) {
+ jQuery(this).removeClass('hidden');
+ });
+ for (key in this._files) {
+ this.upload(key, params);
+ }
+
+ }
+});
diff --git a/lib/scripts/helpers.js b/lib/scripts/helpers.js
new file mode 100644
index 000000000..d6f36967d
--- /dev/null
+++ b/lib/scripts/helpers.js
@@ -0,0 +1,70 @@
+/**
+ * Various helper functions
+ */
+
+/**
+ * Very simplistic Flash plugin check, probably works for Flash 8 and higher only
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function hasFlash(version){
+ var ver = 0;
+ try{
+ if(navigator.plugins != null && navigator.plugins.length > 0){
+ ver = navigator.plugins["Shockwave Flash"].description.split(' ')[2].split('.')[0];
+ }else{
+ ver = (new ActiveXObject("ShockwaveFlash.ShockwaveFlash"))
+ .GetVariable("$version").split(' ')[1].split(',')[0];
+ }
+ }catch(e){ }
+
+ return ver >= version;
+}
+
+/**
+ * A PHP-style substr_replace
+ *
+ * Supports negative start and length and omitting length, but not
+ * str and replace arrays.
+ * See http://php.net/substr-replace for further documentation.
+ */
+function substr_replace(str, replace, start, length) {
+ var a2, b1;
+ a2 = (start < 0 ? str.length : 0) + start;
+ if (typeof length === 'undefined') {
+ length = str.length - a2;
+ } else if (length < 0 && start < 0 && length <= start) {
+ length = 0;
+ }
+ b1 = (length < 0 ? str.length : a2) + length;
+ return str.substring(0, a2) + replace + str.substring(b1);
+}
+
+/**
+ * Bind variables to a function call creating a closure
+ *
+ * Use this to circumvent variable scope problems when creating closures
+ * inside a loop
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @link http://www.cosmocode.de/en/blog/gohr/2009-10/15-javascript-fixing-the-closure-scope-in-loops
+ * @param functionref fnc - the function to be called
+ * @param mixed - any arguments to be passed to the function
+ * @returns functionref
+ */
+function bind(fnc/*, ... */) {
+ var Aps = Array.prototype.slice,
+ // Store passed arguments in this scope.
+ // Since arguments is no Array nor has an own slice method,
+ // we have to apply the slice method from the Array.prototype
+ static_args = Aps.call(arguments, 1);
+
+ // Return a function evaluating the passed function with the
+ // given args and optional arguments passed on invocation.
+ return function (/* ... */) {
+ // Same here, but we use Array.prototype.slice solely for
+ // converting arguments to an Array.
+ return fnc.apply(this,
+ static_args.concat(Aps.call(arguments, 0)));
+ };
+}
diff --git a/lib/scripts/hotkeys.js b/lib/scripts/hotkeys.js
new file mode 100644
index 000000000..bff28530d
--- /dev/null
+++ b/lib/scripts/hotkeys.js
@@ -0,0 +1,302 @@
+/**
+ * Some of these scripts were taken from TinyMCE (http://tinymce.moxiecode.com/) and were modified for DokuWiki
+ *
+ * Class handles accesskeys using javascript and also provides ability
+ * to register and use other hotkeys as well.
+ *
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ */
+function Hotkeys() {
+
+ this.shortcuts = new Array();
+
+ /**
+ * Set modifier keys, for instance:
+ * this.modifier = 'ctrl';
+ * this.modifier = 'ctrl+shift';
+ * this.modifier = 'ctrl+alt+shift';
+ * this.modifier = 'alt';
+ * this.modifier = 'alt+shift';
+ *
+ * overwritten in intitialize (see below)
+ */
+ this.modifier = 'ctrl+alt';
+
+ /**
+ * Initialization
+ *
+ * This function looks up all the accesskeys used in the current page
+ * (at anchor elements and input elements [type="submit"]) and registers
+ * appropriate shortcuts.
+ *
+ * Secondly, initialization registers listeners on document to catch all
+ * keyboard events.
+ *
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ */
+ this.initialize = function() {
+ var t = this;
+
+ //switch modifier key based on OS FS#1958
+ if(is_macos){
+ t.modifier = 'ctrl+alt';
+ }else{
+ t.modifier = 'alt';
+ }
+
+ /**
+ * Lookup all anchors with accesskey and register event - go to anchor
+ * target.
+ */
+ var anchors = document.getElementsByTagName("a");
+ t.each(anchors, function(a) {
+ if (a.accessKey != "") {
+ t.addShortcut(t.modifier + '+' + a.accessKey, function() {
+ location.href = a.href;
+ });
+ a.accessKey = '';
+ }
+ });
+
+ /**
+ * Lookup all input [type="submit"] with accesskey and register event -
+ * perform "click" on a button.
+ */
+ var inputs = document.getElementsByTagName("input");
+ t.each(inputs, function(i) {
+ if (i.type == "submit" && i.accessKey != "") {
+ t.addShortcut(t.modifier + '+' + i.accessKey, function() {
+ i.click();
+ });
+ i.accessKey = '';
+ }
+ });
+
+ /**
+ * Lookup all buttons with accesskey and register event -
+ * perform "click" on a button.
+ */
+ var buttons = document.getElementsByTagName("button");
+ t.each(buttons, function(b) {
+ if (b.accessKey != "") {
+ t.addShortcut(t.modifier + '+' + b.accessKey, function() {
+ b.click();
+ });
+ b.accessKey = '';
+ }
+ });
+
+ /**
+ * Register listeners on document to catch keyboard events.
+ */
+
+ addEvent(document,'keyup',function (e) {
+ return t.onkeyup.call(t,e);
+ });
+
+ addEvent(document,'keypress',function (e) {
+ return t.onkeypress.call(t,e);
+ });
+
+ addEvent(document,'keydown',function (e) {
+ return t.onkeydown.call(t,e);
+ });
+ };
+
+ /**
+ * Keyup processing function
+ * Function returns true if keyboard event has registered handler, and
+ * executes the handler function.
+ *
+ * @param e KeyboardEvent
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @return b boolean
+ */
+ this.onkeyup = function(e) {
+ var t = this;
+ var v = t.findShortcut(e);
+ if (v != null && v != false) {
+ v.func.call(t);
+ return false;
+ }
+ return true;
+ };
+
+ /**
+ * Keydown processing function
+ * Function returns true if keyboard event has registered handler
+ *
+ * @param e KeyboardEvent
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @return b boolean
+ */
+ this.onkeydown = function(e) {
+ var t = this;
+ var v = t.findShortcut(e);
+ if (v != null && v != false) {
+ return false;
+ }
+ return true;
+ };
+
+ /**
+ * Keypress processing function
+ * Function returns true if keyboard event has registered handler
+ *
+ * @param e KeyboardEvent
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @return b
+ */
+ this.onkeypress = function(e) {
+ var t = this;
+ var v = t.findShortcut(e);
+ if (v != null && v != false) {
+ return false;
+ }
+ return true;
+ };
+
+ /**
+ * Register new shortcut
+ *
+ * This function registers new shortcuts, each shortcut is defined by its
+ * modifier keys and a key (with + as delimiter). If shortcut is pressed
+ * cmd_function is performed.
+ *
+ * For example:
+ * pa = "ctrl+alt+p";
+ * pa = "shift+alt+s";
+ *
+ * Full example of method usage:
+ * hotkeys.addShortcut('ctrl+s',function() {
+ * document.getElementByID('form_1').submit();
+ * });
+ *
+ * @param pa String description of the shortcut (ctrl+a, ctrl+shift+p, .. )
+ * @param cmd_func Function to be called if shortcut is pressed
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ */
+ this.addShortcut = function(pa, cmd_func) {
+ var t = this;
+
+ var o = {
+ func : cmd_func,
+ alt : false,
+ ctrl : false,
+ shift : false
+ };
+
+ t.each(t.explode(pa, '+'), function(v) {
+ switch (v) {
+ case 'alt':
+ case 'ctrl':
+ case 'shift':
+ o[v] = true;
+ break;
+
+ default:
+ o.charCode = v.charCodeAt(0);
+ o.keyCode = v.toUpperCase().charCodeAt(0);
+ }
+ });
+
+ t.shortcuts.push((o.ctrl ? 'ctrl' : '') + ',' + (o.alt ? 'alt' : '') + ',' + (o.shift ? 'shift' : '') + ',' + o.keyCode, o);
+
+ return true;
+ };
+
+ /**
+ * @property isMac
+ */
+ this.isMac = is_macos;
+
+ /**
+ * Apply function cb on each element of o in the namespace of s
+ * @param o Array of objects
+ * @param cb Function to be called on each object
+ * @param s Namespace to be used during call of cb (default namespace is o)
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ */
+ this.each = function(o, cb, s) {
+ var n, l;
+
+ if (!o)
+ return 0;
+
+ s = s || o;
+
+ if (o.length !== undefined) {
+ // Indexed arrays, needed for Safari
+ for (n=0, l = o.length; n < l; n++) {
+ if (cb.call(s, o[n], n, o) === false)
+ return 0;
+ }
+ } else {
+ // Hashtables
+ for (n in o) {
+ if (o.hasOwnProperty(n)) {
+ if (cb.call(s, o[n], n, o) === false)
+ return 0;
+ }
+ }
+ }
+
+ return 1;
+ };
+
+ /**
+ * Explode string according to delimiter
+ * @param s String
+ * @param d Delimiter (default ',')
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @return a Array of tokens
+ */
+ this.explode = function(s, d) {
+ return s.split(d || ',');
+ };
+
+ /**
+ * Find if the shortcut was registered
+ *
+ * @param e KeyboardEvent
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @return v Shortcut structure or null if not found
+ */
+ this.findShortcut = function (e) {
+ var t = this;
+ var v = null;
+
+ /* No modifier key used - shortcut does not exist */
+ if (!e.altKey && !e.ctrlKey && !e.metaKey) {
+ return v;
+ }
+
+ t.each(t.shortcuts, function(o) {
+ if (o.ctrl != e.ctrlKey)
+ return;
+
+ if (o.alt != e.altKey)
+ return;
+
+ if (o.shift != e.shiftKey)
+ return;
+
+ if (e.keyCode == o.keyCode || (e.charCode && e.charCode == o.charCode)) {
+ v = o;
+ return;
+ }
+ });
+ return v;
+ };
+}
+
+/**
+ * Init function for hotkeys. Called from js.php, to ensure hotkyes are initialized after toolbar.
+ * Call of addInitEvent(initializeHotkeys) is unnecessary now.
+ *
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ */
+function initializeHotkeys() {
+ var hotkeys = new Hotkeys();
+ hotkeys.initialize();
+}
diff --git a/lib/scripts/index.html b/lib/scripts/index.html
new file mode 100644
index 000000000..d614603ac
--- /dev/null
+++ b/lib/scripts/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="refresh" content="0; URL=../../" />
+<meta name="robots" content="noindex" />
+<title>nothing here...</title>
+</head>
+<body>
+<!-- this is just here to prevent directory browsing -->
+</body>
+</html>
diff --git a/lib/scripts/index.js b/lib/scripts/index.js
new file mode 100644
index 000000000..4b67a0b12
--- /dev/null
+++ b/lib/scripts/index.js
@@ -0,0 +1,16 @@
+var dw_index = jQuery('#index__tree').dw_tree({deferInit: true,
+ load_data: function (show_sublist, $clicky) {
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ $clicky[0].search.substr(1) + '&call=index',
+ show_sublist, 'html'
+ );
+ }
+});
+jQuery(function () {
+ var $tree = jQuery('#index__tree');
+
+ dw_index.$obj = $tree;
+
+ dw_index.init();
+});
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_0_aaaaaa_40x100.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 000000000..5b5dab2ab
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_0_aaaaaa_40x100.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_75_ffffff_40x100.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644
index 000000000..ac8b229af
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_75_ffffff_40x100.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_55_fbf9ee_1x400.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_55_fbf9ee_1x400.png
new file mode 100644
index 000000000..ad3d6346e
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_55_fbf9ee_1x400.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_65_ffffff_1x400.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 000000000..42ccba269
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_65_ffffff_1x400.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_dadada_1x400.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_dadada_1x400.png
new file mode 100644
index 000000000..5a46b47cb
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_dadada_1x400.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_e6e6e6_1x400.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_e6e6e6_1x400.png
new file mode 100644
index 000000000..86c2baa65
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_e6e6e6_1x400.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_95_fef1ec_1x400.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100644
index 000000000..4443fdc1a
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_95_fef1ec_1x400.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png
new file mode 100644
index 000000000..7c9fa6c6e
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_222222_256x240.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_222222_256x240.png
new file mode 100644
index 000000000..b273ff111
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_222222_256x240.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_2e83ff_256x240.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_2e83ff_256x240.png
new file mode 100644
index 000000000..09d1cdc85
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_2e83ff_256x240.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_454545_256x240.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_454545_256x240.png
new file mode 100644
index 000000000..59bd45b90
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_454545_256x240.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_888888_256x240.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_888888_256x240.png
new file mode 100644
index 000000000..6d02426c1
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_888888_256x240.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_cd0a0a_256x240.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_cd0a0a_256x240.png
new file mode 100644
index 000000000..2ab019b73
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_cd0a0a_256x240.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/smoothness.css b/lib/scripts/jquery/jquery-ui-theme/smoothness.css
new file mode 100644
index 000000000..910d24b95
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/smoothness.css
@@ -0,0 +1,568 @@
+/*
+ * jQuery UI CSS Framework 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*
+ * jQuery UI CSS Framework 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ *
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
+ */
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-size: 1.1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-size: 1em; }
+.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
+.ui-widget-content a { color: #222222; }
+.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
+.ui-widget-header a { color: #222222; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
+.ui-widget :active { outline: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; }
+.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
+.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*
+ * jQuery UI Resizable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizable#theming
+ */
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; }
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
+ * jQuery UI Selectable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Selectable#theming
+ */
+.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
+/*
+ * jQuery UI Accordion 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Accordion#theming
+ */
+/* IE/Win - Fix animation bug - #4615 */
+.ui-accordion { width: 100%; }
+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
+.ui-accordion .ui-accordion-li-fix { display: inline; }
+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
+.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
+.ui-accordion .ui-accordion-content-active { display: block; }
+/*
+ * jQuery UI Autocomplete 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete#theming
+ */
+.ui-autocomplete { position: absolute; cursor: default; }
+
+/* workarounds */
+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
+
+/*
+ * jQuery UI Menu 1.8.16
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Menu#theming
+ */
+.ui-menu {
+ list-style:none;
+ padding: 2px;
+ margin: 0;
+ display:block;
+ float: left;
+}
+.ui-menu .ui-menu {
+ margin-top: -3px;
+}
+.ui-menu .ui-menu-item {
+ margin:0;
+ padding: 0;
+ zoom: 1;
+ float: left;
+ clear: left;
+ width: 100%;
+}
+.ui-menu .ui-menu-item a {
+ text-decoration:none;
+ display:block;
+ padding:.2em .4em;
+ line-height:1.5;
+ zoom:1;
+}
+.ui-menu .ui-menu-item a.ui-state-hover,
+.ui-menu .ui-menu-item a.ui-state-active {
+ font-weight: normal;
+ margin: -1px;
+}
+/*
+ * jQuery UI Button 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Button#theming
+ */
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; }
+button.ui-button-icons-only { width: 3.7em; }
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4; }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button { padding: .4em 1em; }
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+
+/* workarounds */
+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
+/*
+ * jQuery UI Dialog 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog#theming
+ */
+.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
+.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+/*
+ * jQuery UI Slider 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider#theming
+ */
+.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }/*
+ * jQuery UI Tabs 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Tabs#theming
+ */
+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; }
+/*
+ * jQuery UI Datepicker 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Datepicker#theming
+ */
+.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
+.ui-datepicker .ui-datepicker-prev { left:2px; }
+.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
+.ui-datepicker .ui-datepicker-next-hover { right:1px; }
+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
+.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi { width:auto; }
+.ui-datepicker-multi .ui-datepicker-group { float:left; }
+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
+.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
+
+/* RTL support */
+.ui-datepicker-rtl { direction: rtl; }
+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
+.ui-datepicker-cover {
+ display: none; /*sorry for IE5*/
+ display/**/: block; /*sorry for IE5*/
+ position: absolute; /*must have*/
+ z-index: -1; /*must have*/
+ filter: mask(); /*must have*/
+ top: -4px; /*must have*/
+ left: -4px; /*must have*/
+ width: 200px; /*must have*/
+ height: 200px; /*must have*/
+}/*
+ * jQuery UI Progressbar 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Progressbar#theming
+ */
+.ui-progressbar { height:2em; text-align: left; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file
diff --git a/lib/scripts/jquery/jquery-ui.js b/lib/scripts/jquery/jquery-ui.js
new file mode 100644
index 000000000..cd515f361
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui.js
@@ -0,0 +1,11767 @@
+/*!
+ * jQuery UI 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function( $, undefined ) {
+
+// prevent duplicate loading
+// this is only a problem because we proxy existing functions
+// and we don't want to double proxy them
+$.ui = $.ui || {};
+if ( $.ui.version ) {
+ return;
+}
+
+$.extend( $.ui, {
+ version: "1.8.16",
+
+ keyCode: {
+ ALT: 18,
+ BACKSPACE: 8,
+ CAPS_LOCK: 20,
+ COMMA: 188,
+ COMMAND: 91,
+ COMMAND_LEFT: 91, // COMMAND
+ COMMAND_RIGHT: 93,
+ CONTROL: 17,
+ DELETE: 46,
+ DOWN: 40,
+ END: 35,
+ ENTER: 13,
+ ESCAPE: 27,
+ HOME: 36,
+ INSERT: 45,
+ LEFT: 37,
+ MENU: 93, // COMMAND_RIGHT
+ NUMPAD_ADD: 107,
+ NUMPAD_DECIMAL: 110,
+ NUMPAD_DIVIDE: 111,
+ NUMPAD_ENTER: 108,
+ NUMPAD_MULTIPLY: 106,
+ NUMPAD_SUBTRACT: 109,
+ PAGE_DOWN: 34,
+ PAGE_UP: 33,
+ PERIOD: 190,
+ RIGHT: 39,
+ SHIFT: 16,
+ SPACE: 32,
+ TAB: 9,
+ UP: 38,
+ WINDOWS: 91 // COMMAND
+ }
+});
+
+// plugins
+$.fn.extend({
+ propAttr: $.fn.prop || $.fn.attr,
+
+ _focus: $.fn.focus,
+ focus: function( delay, fn ) {
+ return typeof delay === "number" ?
+ this.each(function() {
+ var elem = this;
+ setTimeout(function() {
+ $( elem ).focus();
+ if ( fn ) {
+ fn.call( elem );
+ }
+ }, delay );
+ }) :
+ this._focus.apply( this, arguments );
+ },
+
+ scrollParent: function() {
+ var scrollParent;
+ if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
+ scrollParent = this.parents().filter(function() {
+ return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+ }).eq(0);
+ } else {
+ scrollParent = this.parents().filter(function() {
+ return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+ }).eq(0);
+ }
+
+ return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
+ },
+
+ zIndex: function( zIndex ) {
+ if ( zIndex !== undefined ) {
+ return this.css( "zIndex", zIndex );
+ }
+
+ if ( this.length ) {
+ var elem = $( this[ 0 ] ), position, value;
+ while ( elem.length && elem[ 0 ] !== document ) {
+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
+ // This makes behavior of this function consistent across browsers
+ // WebKit always returns auto if the element is positioned
+ position = elem.css( "position" );
+ if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+ // IE returns 0 when zIndex is not specified
+ // other browsers return a string
+ // we ignore the case of nested elements with an explicit value of 0
+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+ value = parseInt( elem.css( "zIndex" ), 10 );
+ if ( !isNaN( value ) && value !== 0 ) {
+ return value;
+ }
+ }
+ elem = elem.parent();
+ }
+ }
+
+ return 0;
+ },
+
+ disableSelection: function() {
+ return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
+ ".ui-disableSelection", function( event ) {
+ event.preventDefault();
+ });
+ },
+
+ enableSelection: function() {
+ return this.unbind( ".ui-disableSelection" );
+ }
+});
+
+$.each( [ "Width", "Height" ], function( i, name ) {
+ var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
+ type = name.toLowerCase(),
+ orig = {
+ innerWidth: $.fn.innerWidth,
+ innerHeight: $.fn.innerHeight,
+ outerWidth: $.fn.outerWidth,
+ outerHeight: $.fn.outerHeight
+ };
+
+ function reduce( elem, size, border, margin ) {
+ $.each( side, function() {
+ size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
+ if ( border ) {
+ size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
+ }
+ if ( margin ) {
+ size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
+ }
+ });
+ return size;
+ }
+
+ $.fn[ "inner" + name ] = function( size ) {
+ if ( size === undefined ) {
+ return orig[ "inner" + name ].call( this );
+ }
+
+ return this.each(function() {
+ $( this ).css( type, reduce( this, size ) + "px" );
+ });
+ };
+
+ $.fn[ "outer" + name] = function( size, margin ) {
+ if ( typeof size !== "number" ) {
+ return orig[ "outer" + name ].call( this, size );
+ }
+
+ return this.each(function() {
+ $( this).css( type, reduce( this, size, true, margin ) + "px" );
+ });
+ };
+});
+
+// selectors
+function focusable( element, isTabIndexNotNaN ) {
+ var nodeName = element.nodeName.toLowerCase();
+ if ( "area" === nodeName ) {
+ var map = element.parentNode,
+ mapName = map.name,
+ img;
+ if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
+ return false;
+ }
+ img = $( "img[usemap=#" + mapName + "]" )[0];
+ return !!img && visible( img );
+ }
+ return ( /input|select|textarea|button|object/.test( nodeName )
+ ? !element.disabled
+ : "a" == nodeName
+ ? element.href || isTabIndexNotNaN
+ : isTabIndexNotNaN)
+ // the element and all of its ancestors must be visible
+ && visible( element );
+}
+
+function visible( element ) {
+ return !$( element ).parents().andSelf().filter(function() {
+ return $.curCSS( this, "visibility" ) === "hidden" ||
+ $.expr.filters.hidden( this );
+ }).length;
+}
+
+$.extend( $.expr[ ":" ], {
+ data: function( elem, i, match ) {
+ return !!$.data( elem, match[ 3 ] );
+ },
+
+ focusable: function( element ) {
+ return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
+ },
+
+ tabbable: function( element ) {
+ var tabIndex = $.attr( element, "tabindex" ),
+ isTabIndexNaN = isNaN( tabIndex );
+ return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
+ }
+});
+
+// support
+$(function() {
+ var body = document.body,
+ div = body.appendChild( div = document.createElement( "div" ) );
+
+ $.extend( div.style, {
+ minHeight: "100px",
+ height: "auto",
+ padding: 0,
+ borderWidth: 0
+ });
+
+ $.support.minHeight = div.offsetHeight === 100;
+ $.support.selectstart = "onselectstart" in div;
+
+ // set display to none to avoid a layout bug in IE
+ // http://dev.jquery.com/ticket/4014
+ body.removeChild( div ).style.display = "none";
+});
+
+
+
+
+
+// deprecated
+$.extend( $.ui, {
+ // $.ui.plugin is deprecated. Use the proxy pattern instead.
+ plugin: {
+ add: function( module, option, set ) {
+ var proto = $.ui[ module ].prototype;
+ for ( var i in set ) {
+ proto.plugins[ i ] = proto.plugins[ i ] || [];
+ proto.plugins[ i ].push( [ option, set[ i ] ] );
+ }
+ },
+ call: function( instance, name, args ) {
+ var set = instance.plugins[ name ];
+ if ( !set || !instance.element[ 0 ].parentNode ) {
+ return;
+ }
+
+ for ( var i = 0; i < set.length; i++ ) {
+ if ( instance.options[ set[ i ][ 0 ] ] ) {
+ set[ i ][ 1 ].apply( instance.element, args );
+ }
+ }
+ }
+ },
+
+ // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
+ contains: function( a, b ) {
+ return document.compareDocumentPosition ?
+ a.compareDocumentPosition( b ) & 16 :
+ a !== b && a.contains( b );
+ },
+
+ // only used by resizable
+ hasScroll: function( el, a ) {
+
+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
+ if ( $( el ).css( "overflow" ) === "hidden") {
+ return false;
+ }
+
+ var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
+ has = false;
+
+ if ( el[ scroll ] > 0 ) {
+ return true;
+ }
+
+ // TODO: determine which cases actually cause this to happen
+ // if the element doesn't have the scroll set, see if it's possible to
+ // set the scroll
+ el[ scroll ] = 1;
+ has = ( el[ scroll ] > 0 );
+ el[ scroll ] = 0;
+ return has;
+ },
+
+ // these are odd functions, fix the API or move into individual plugins
+ isOverAxis: function( x, reference, size ) {
+ //Determines when x coordinate is over "b" element axis
+ return ( x > reference ) && ( x < ( reference + size ) );
+ },
+ isOver: function( y, x, top, left, height, width ) {
+ //Determines when x, y coordinates is over "b" element
+ return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
+ }
+});
+
+})( jQuery );
+/*!
+ * jQuery UI Widget 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Widget
+ */
+(function( $, undefined ) {
+
+// jQuery 1.4+
+if ( $.cleanData ) {
+ var _cleanData = $.cleanData;
+ $.cleanData = function( elems ) {
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ try {
+ $( elem ).triggerHandler( "remove" );
+ // http://bugs.jquery.com/ticket/8235
+ } catch( e ) {}
+ }
+ _cleanData( elems );
+ };
+} else {
+ var _remove = $.fn.remove;
+ $.fn.remove = function( selector, keepData ) {
+ return this.each(function() {
+ if ( !keepData ) {
+ if ( !selector || $.filter( selector, [ this ] ).length ) {
+ $( "*", this ).add( [ this ] ).each(function() {
+ try {
+ $( this ).triggerHandler( "remove" );
+ // http://bugs.jquery.com/ticket/8235
+ } catch( e ) {}
+ });
+ }
+ }
+ return _remove.call( $(this), selector, keepData );
+ });
+ };
+}
+
+$.widget = function( name, base, prototype ) {
+ var namespace = name.split( "." )[ 0 ],
+ fullName;
+ name = name.split( "." )[ 1 ];
+ fullName = namespace + "-" + name;
+
+ if ( !prototype ) {
+ prototype = base;
+ base = $.Widget;
+ }
+
+ // create selector for plugin
+ $.expr[ ":" ][ fullName ] = function( elem ) {
+ return !!$.data( elem, name );
+ };
+
+ $[ namespace ] = $[ namespace ] || {};
+ $[ namespace ][ name ] = function( options, element ) {
+ // allow instantiation without initializing for simple inheritance
+ if ( arguments.length ) {
+ this._createWidget( options, element );
+ }
+ };
+
+ var basePrototype = new base();
+ // we need to make the options hash a property directly on the new instance
+ // otherwise we'll modify the options hash on the prototype that we're
+ // inheriting from
+// $.each( basePrototype, function( key, val ) {
+// if ( $.isPlainObject(val) ) {
+// basePrototype[ key ] = $.extend( {}, val );
+// }
+// });
+ basePrototype.options = $.extend( true, {}, basePrototype.options );
+ $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
+ namespace: namespace,
+ widgetName: name,
+ widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
+ widgetBaseClass: fullName
+ }, prototype );
+
+ $.widget.bridge( name, $[ namespace ][ name ] );
+};
+
+$.widget.bridge = function( name, object ) {
+ $.fn[ name ] = function( options ) {
+ var isMethodCall = typeof options === "string",
+ args = Array.prototype.slice.call( arguments, 1 ),
+ returnValue = this;
+
+ // allow multiple hashes to be passed on init
+ options = !isMethodCall && args.length ?
+ $.extend.apply( null, [ true, options ].concat(args) ) :
+ options;
+
+ // prevent calls to internal methods
+ if ( isMethodCall && options.charAt( 0 ) === "_" ) {
+ return returnValue;
+ }
+
+ if ( isMethodCall ) {
+ this.each(function() {
+ var instance = $.data( this, name ),
+ methodValue = instance && $.isFunction( instance[options] ) ?
+ instance[ options ].apply( instance, args ) :
+ instance;
+ // TODO: add this back in 1.9 and use $.error() (see #5972)
+// if ( !instance ) {
+// throw "cannot call methods on " + name + " prior to initialization; " +
+// "attempted to call method '" + options + "'";
+// }
+// if ( !$.isFunction( instance[options] ) ) {
+// throw "no such method '" + options + "' for " + name + " widget instance";
+// }
+// var methodValue = instance[ options ].apply( instance, args );
+ if ( methodValue !== instance && methodValue !== undefined ) {
+ returnValue = methodValue;
+ return false;
+ }
+ });
+ } else {
+ this.each(function() {
+ var instance = $.data( this, name );
+ if ( instance ) {
+ instance.option( options || {} )._init();
+ } else {
+ $.data( this, name, new object( options, this ) );
+ }
+ });
+ }
+
+ return returnValue;
+ };
+};
+
+$.Widget = function( options, element ) {
+ // allow instantiation without initializing for simple inheritance
+ if ( arguments.length ) {
+ this._createWidget( options, element );
+ }
+};
+
+$.Widget.prototype = {
+ widgetName: "widget",
+ widgetEventPrefix: "",
+ options: {
+ disabled: false
+ },
+ _createWidget: function( options, element ) {
+ // $.widget.bridge stores the plugin instance, but we do it anyway
+ // so that it's stored even before the _create function runs
+ $.data( element, this.widgetName, this );
+ this.element = $( element );
+ this.options = $.extend( true, {},
+ this.options,
+ this._getCreateOptions(),
+ options );
+
+ var self = this;
+ this.element.bind( "remove." + this.widgetName, function() {
+ self.destroy();
+ });
+
+ this._create();
+ this._trigger( "create" );
+ this._init();
+ },
+ _getCreateOptions: function() {
+ return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
+ },
+ _create: function() {},
+ _init: function() {},
+
+ destroy: function() {
+ this.element
+ .unbind( "." + this.widgetName )
+ .removeData( this.widgetName );
+ this.widget()
+ .unbind( "." + this.widgetName )
+ .removeAttr( "aria-disabled" )
+ .removeClass(
+ this.widgetBaseClass + "-disabled " +
+ "ui-state-disabled" );
+ },
+
+ widget: function() {
+ return this.element;
+ },
+
+ option: function( key, value ) {
+ var options = key;
+
+ if ( arguments.length === 0 ) {
+ // don't return a reference to the internal hash
+ return $.extend( {}, this.options );
+ }
+
+ if (typeof key === "string" ) {
+ if ( value === undefined ) {
+ return this.options[ key ];
+ }
+ options = {};
+ options[ key ] = value;
+ }
+
+ this._setOptions( options );
+
+ return this;
+ },
+ _setOptions: function( options ) {
+ var self = this;
+ $.each( options, function( key, value ) {
+ self._setOption( key, value );
+ });
+
+ return this;
+ },
+ _setOption: function( key, value ) {
+ this.options[ key ] = value;
+
+ if ( key === "disabled" ) {
+ this.widget()
+ [ value ? "addClass" : "removeClass"](
+ this.widgetBaseClass + "-disabled" + " " +
+ "ui-state-disabled" )
+ .attr( "aria-disabled", value );
+ }
+
+ return this;
+ },
+
+ enable: function() {
+ return this._setOption( "disabled", false );
+ },
+ disable: function() {
+ return this._setOption( "disabled", true );
+ },
+
+ _trigger: function( type, event, data ) {
+ var callback = this.options[ type ];
+
+ event = $.Event( event );
+ event.type = ( type === this.widgetEventPrefix ?
+ type :
+ this.widgetEventPrefix + type ).toLowerCase();
+ data = data || {};
+
+ // copy original event properties over to the new event
+ // this would happen if we could call $.event.fix instead of $.Event
+ // but we don't have a way to force an event to be fixed multiple times
+ if ( event.originalEvent ) {
+ for ( var i = $.event.props.length, prop; i; ) {
+ prop = $.event.props[ --i ];
+ event[ prop ] = event.originalEvent[ prop ];
+ }
+ }
+
+ this.element.trigger( event, data );
+
+ return !( $.isFunction(callback) &&
+ callback.call( this.element[0], event, data ) === false ||
+ event.isDefaultPrevented() );
+ }
+};
+
+})( jQuery );
+/*!
+ * jQuery UI Mouse 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Mouse
+ *
+ * Depends:
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+var mouseHandled = false;
+$( document ).mouseup( function( e ) {
+ mouseHandled = false;
+});
+
+$.widget("ui.mouse", {
+ options: {
+ cancel: ':input,option',
+ distance: 1,
+ delay: 0
+ },
+ _mouseInit: function() {
+ var self = this;
+
+ this.element
+ .bind('mousedown.'+this.widgetName, function(event) {
+ return self._mouseDown(event);
+ })
+ .bind('click.'+this.widgetName, function(event) {
+ if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
+ $.removeData(event.target, self.widgetName + '.preventClickEvent');
+ event.stopImmediatePropagation();
+ return false;
+ }
+ });
+
+ this.started = false;
+ },
+
+ // TODO: make sure destroying one instance of mouse doesn't mess with
+ // other instances of mouse
+ _mouseDestroy: function() {
+ this.element.unbind('.'+this.widgetName);
+ },
+
+ _mouseDown: function(event) {
+ // don't let more than one widget handle mouseStart
+ if( mouseHandled ) { return };
+
+ // we may have missed mouseup (out of window)
+ (this._mouseStarted && this._mouseUp(event));
+
+ this._mouseDownEvent = event;
+
+ var self = this,
+ btnIsLeft = (event.which == 1),
+ // event.target.nodeName works around a bug in IE 8 with
+ // disabled inputs (#7620)
+ elIsCancel = (typeof this.options.cancel == "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+ return true;
+ }
+
+ this.mouseDelayMet = !this.options.delay;
+ if (!this.mouseDelayMet) {
+ this._mouseDelayTimer = setTimeout(function() {
+ self.mouseDelayMet = true;
+ }, this.options.delay);
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted = (this._mouseStart(event) !== false);
+ if (!this._mouseStarted) {
+ event.preventDefault();
+ return true;
+ }
+ }
+
+ // Click event may never have fired (Gecko & Opera)
+ if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
+ $.removeData(event.target, this.widgetName + '.preventClickEvent');
+ }
+
+ // these delegates are required to keep context
+ this._mouseMoveDelegate = function(event) {
+ return self._mouseMove(event);
+ };
+ this._mouseUpDelegate = function(event) {
+ return self._mouseUp(event);
+ };
+ $(document)
+ .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+ .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+ event.preventDefault();
+
+ mouseHandled = true;
+ return true;
+ },
+
+ _mouseMove: function(event) {
+ // IE mouseup check - mouseup happened when mouse was out of window
+ if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
+ return this._mouseUp(event);
+ }
+
+ if (this._mouseStarted) {
+ this._mouseDrag(event);
+ return event.preventDefault();
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted =
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+ }
+
+ return !this._mouseStarted;
+ },
+
+ _mouseUp: function(event) {
+ $(document)
+ .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+ .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+ if (this._mouseStarted) {
+ this._mouseStarted = false;
+
+ if (event.target == this._mouseDownEvent.target) {
+ $.data(event.target, this.widgetName + '.preventClickEvent', true);
+ }
+
+ this._mouseStop(event);
+ }
+
+ return false;
+ },
+
+ _mouseDistanceMet: function(event) {
+ return (Math.max(
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
+ ) >= this.options.distance
+ );
+ },
+
+ _mouseDelayMet: function(event) {
+ return this.mouseDelayMet;
+ },
+
+ // These are placeholder methods, to be overriden by extending plugin
+ _mouseStart: function(event) {},
+ _mouseDrag: function(event) {},
+ _mouseStop: function(event) {},
+ _mouseCapture: function(event) { return true; }
+});
+
+})(jQuery);
+/*
+ * jQuery UI Draggable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Draggables
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.mouse.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.draggable", $.ui.mouse, {
+ widgetEventPrefix: "drag",
+ options: {
+ addClasses: true,
+ appendTo: "parent",
+ axis: false,
+ connectToSortable: false,
+ containment: false,
+ cursor: "auto",
+ cursorAt: false,
+ grid: false,
+ handle: false,
+ helper: "original",
+ iframeFix: false,
+ opacity: false,
+ refreshPositions: false,
+ revert: false,
+ revertDuration: 500,
+ scope: "default",
+ scroll: true,
+ scrollSensitivity: 20,
+ scrollSpeed: 20,
+ snap: false,
+ snapMode: "both",
+ snapTolerance: 20,
+ stack: false,
+ zIndex: false
+ },
+ _create: function() {
+
+ if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
+ this.element[0].style.position = 'relative';
+
+ (this.options.addClasses && this.element.addClass("ui-draggable"));
+ (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
+
+ this._mouseInit();
+
+ },
+
+ destroy: function() {
+ if(!this.element.data('draggable')) return;
+ this.element
+ .removeData("draggable")
+ .unbind(".draggable")
+ .removeClass("ui-draggable"
+ + " ui-draggable-dragging"
+ + " ui-draggable-disabled");
+ this._mouseDestroy();
+
+ return this;
+ },
+
+ _mouseCapture: function(event) {
+
+ var o = this.options;
+
+ // among others, prevent a drag on a resizable-handle
+ if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
+ return false;
+
+ //Quit if we're not on a valid handle
+ this.handle = this._getHandle(event);
+ if (!this.handle)
+ return false;
+
+ if ( o.iframeFix ) {
+ $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
+ $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
+ .css({
+ width: this.offsetWidth+"px", height: this.offsetHeight+"px",
+ position: "absolute", opacity: "0.001", zIndex: 1000
+ })
+ .css($(this).offset())
+ .appendTo("body");
+ });
+ }
+
+ return true;
+
+ },
+
+ _mouseStart: function(event) {
+
+ var o = this.options;
+
+ //Create and append the visible helper
+ this.helper = this._createHelper(event);
+
+ //Cache the helper size
+ this._cacheHelperProportions();
+
+ //If ddmanager is used for droppables, set the global draggable
+ if($.ui.ddmanager)
+ $.ui.ddmanager.current = this;
+
+ /*
+ * - Position generation -
+ * This block generates everything position related - it's the core of draggables.
+ */
+
+ //Cache the margins of the original element
+ this._cacheMargins();
+
+ //Store the helper's css position
+ this.cssPosition = this.helper.css("position");
+ this.scrollParent = this.helper.scrollParent();
+
+ //The element's absolute position on the page minus margins
+ this.offset = this.positionAbs = this.element.offset();
+ this.offset = {
+ top: this.offset.top - this.margins.top,
+ left: this.offset.left - this.margins.left
+ };
+
+ $.extend(this.offset, {
+ click: { //Where the click happened, relative to the element
+ left: event.pageX - this.offset.left,
+ top: event.pageY - this.offset.top
+ },
+ parent: this._getParentOffset(),
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
+ });
+
+ //Generate the original position
+ this.originalPosition = this.position = this._generatePosition(event);
+ this.originalPageX = event.pageX;
+ this.originalPageY = event.pageY;
+
+ //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+ //Set a containment if given in the options
+ if(o.containment)
+ this._setContainment();
+
+ //Trigger event + callbacks
+ if(this._trigger("start", event) === false) {
+ this._clear();
+ return false;
+ }
+
+ //Recache the helper size
+ this._cacheHelperProportions();
+
+ //Prepare the droppable offsets
+ if ($.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(this, event);
+
+ this.helper.addClass("ui-draggable-dragging");
+ this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+
+ //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
+ if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
+
+ return true;
+ },
+
+ _mouseDrag: function(event, noPropagation) {
+
+ //Compute the helpers position
+ this.position = this._generatePosition(event);
+ this.positionAbs = this._convertPositionTo("absolute");
+
+ //Call plugins and callbacks and use the resulting position if something is returned
+ if (!noPropagation) {
+ var ui = this._uiHash();
+ if(this._trigger('drag', event, ui) === false) {
+ this._mouseUp({});
+ return false;
+ }
+ this.position = ui.position;
+ }
+
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
+
+ return false;
+ },
+
+ _mouseStop: function(event) {
+
+ //If we are using droppables, inform the manager about the drop
+ var dropped = false;
+ if ($.ui.ddmanager && !this.options.dropBehaviour)
+ dropped = $.ui.ddmanager.drop(this, event);
+
+ //if a drop comes from outside (a sortable)
+ if(this.dropped) {
+ dropped = this.dropped;
+ this.dropped = false;
+ }
+
+ //if the original element is removed, don't bother to continue if helper is set to "original"
+ if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original")
+ return false;
+
+ if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
+ var self = this;
+ $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
+ if(self._trigger("stop", event) !== false) {
+ self._clear();
+ }
+ });
+ } else {
+ if(this._trigger("stop", event) !== false) {
+ this._clear();
+ }
+ }
+
+ return false;
+ },
+
+ _mouseUp: function(event) {
+ if (this.options.iframeFix === true) {
+ $("div.ui-draggable-iframeFix").each(function() {
+ this.parentNode.removeChild(this);
+ }); //Remove frame helpers
+ }
+
+ //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
+ if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
+
+ return $.ui.mouse.prototype._mouseUp.call(this, event);
+ },
+
+ cancel: function() {
+
+ if(this.helper.is(".ui-draggable-dragging")) {
+ this._mouseUp({});
+ } else {
+ this._clear();
+ }
+
+ return this;
+
+ },
+
+ _getHandle: function(event) {
+
+ var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
+ $(this.options.handle, this.element)
+ .find("*")
+ .andSelf()
+ .each(function() {
+ if(this == event.target) handle = true;
+ });
+
+ return handle;
+
+ },
+
+ _createHelper: function(event) {
+
+ var o = this.options;
+ var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
+
+ if(!helper.parents('body').length)
+ helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
+
+ if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
+ helper.css("position", "absolute");
+
+ return helper;
+
+ },
+
+ _adjustOffsetFromHelper: function(obj) {
+ if (typeof obj == 'string') {
+ obj = obj.split(' ');
+ }
+ if ($.isArray(obj)) {
+ obj = {left: +obj[0], top: +obj[1] || 0};
+ }
+ if ('left' in obj) {
+ this.offset.click.left = obj.left + this.margins.left;
+ }
+ if ('right' in obj) {
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+ }
+ if ('top' in obj) {
+ this.offset.click.top = obj.top + this.margins.top;
+ }
+ if ('bottom' in obj) {
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+ }
+ },
+
+ _getParentOffset: function() {
+
+ //Get the offsetParent and cache its position
+ this.offsetParent = this.helper.offsetParent();
+ var po = this.offsetParent.offset();
+
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+ if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
+ po.left += this.scrollParent.scrollLeft();
+ po.top += this.scrollParent.scrollTop();
+ }
+
+ if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
+ || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
+ po = { top: 0, left: 0 };
+
+ return {
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+ };
+
+ },
+
+ _getRelativeOffset: function() {
+
+ if(this.cssPosition == "relative") {
+ var p = this.element.position();
+ return {
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+ };
+ } else {
+ return { top: 0, left: 0 };
+ }
+
+ },
+
+ _cacheMargins: function() {
+ this.margins = {
+ left: (parseInt(this.element.css("marginLeft"),10) || 0),
+ top: (parseInt(this.element.css("marginTop"),10) || 0),
+ right: (parseInt(this.element.css("marginRight"),10) || 0),
+ bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
+ };
+ },
+
+ _cacheHelperProportions: function() {
+ this.helperProportions = {
+ width: this.helper.outerWidth(),
+ height: this.helper.outerHeight()
+ };
+ },
+
+ _setContainment: function() {
+
+ var o = this.options;
+ if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
+ if(o.containment == 'document' || o.containment == 'window') this.containment = [
+ o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
+ o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
+ (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
+ (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+ ];
+
+ if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
+ var c = $(o.containment);
+ var ce = c[0]; if(!ce) return;
+ var co = c.offset();
+ var over = ($(ce).css("overflow") != 'hidden');
+
+ this.containment = [
+ (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
+ (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
+ (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
+ (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom
+ ];
+ this.relative_container = c;
+
+ } else if(o.containment.constructor == Array) {
+ this.containment = o.containment;
+ }
+
+ },
+
+ _convertPositionTo: function(d, pos) {
+
+ if(!pos) pos = this.position;
+ var mod = d == "absolute" ? 1 : -1;
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+ return {
+ top: (
+ pos.top // The absolute mouse position
+ + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
+ - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
+ ),
+ left: (
+ pos.left // The absolute mouse position
+ + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
+ - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
+ )
+ };
+
+ },
+
+ _generatePosition: function(event) {
+
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+ var pageX = event.pageX;
+ var pageY = event.pageY;
+
+ /*
+ * - Position constraining -
+ * Constrain the position to a mix of grid, containment.
+ */
+
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
+ var containment;
+ if(this.containment) {
+ if (this.relative_container){
+ var co = this.relative_container.offset();
+ containment = [ this.containment[0] + co.left,
+ this.containment[1] + co.top,
+ this.containment[2] + co.left,
+ this.containment[3] + co.top ];
+ }
+ else {
+ containment = this.containment;
+ }
+
+ if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
+ if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
+ }
+
+ if(o.grid) {
+ //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
+ var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
+ pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+ var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
+ pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+ }
+
+ }
+
+ return {
+ top: (
+ pageY // The absolute mouse position
+ - this.offset.click.top // Click offset (relative to the element)
+ - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
+ + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
+ ),
+ left: (
+ pageX // The absolute mouse position
+ - this.offset.click.left // Click offset (relative to the element)
+ - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
+ + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
+ )
+ };
+
+ },
+
+ _clear: function() {
+ this.helper.removeClass("ui-draggable-dragging");
+ if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
+ //if($.ui.ddmanager) $.ui.ddmanager.current = null;
+ this.helper = null;
+ this.cancelHelperRemoval = false;
+ },
+
+ // From now on bulk stuff - mainly helpers
+
+ _trigger: function(type, event, ui) {
+ ui = ui || this._uiHash();
+ $.ui.plugin.call(this, type, [event, ui]);
+ if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
+ return $.Widget.prototype._trigger.call(this, type, event, ui);
+ },
+
+ plugins: {},
+
+ _uiHash: function(event) {
+ return {
+ helper: this.helper,
+ position: this.position,
+ originalPosition: this.originalPosition,
+ offset: this.positionAbs
+ };
+ }
+
+});
+
+$.extend($.ui.draggable, {
+ version: "1.8.16"
+});
+
+$.ui.plugin.add("draggable", "connectToSortable", {
+ start: function(event, ui) {
+
+ var inst = $(this).data("draggable"), o = inst.options,
+ uiSortable = $.extend({}, ui, { item: inst.element });
+ inst.sortables = [];
+ $(o.connectToSortable).each(function() {
+ var sortable = $.data(this, 'sortable');
+ if (sortable && !sortable.options.disabled) {
+ inst.sortables.push({
+ instance: sortable,
+ shouldRevert: sortable.options.revert
+ });
+ sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
+ sortable._trigger("activate", event, uiSortable);
+ }
+ });
+
+ },
+ stop: function(event, ui) {
+
+ //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
+ var inst = $(this).data("draggable"),
+ uiSortable = $.extend({}, ui, { item: inst.element });
+
+ $.each(inst.sortables, function() {
+ if(this.instance.isOver) {
+
+ this.instance.isOver = 0;
+
+ inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
+ this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
+
+ //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
+ if(this.shouldRevert) this.instance.options.revert = true;
+
+ //Trigger the stop of the sortable
+ this.instance._mouseStop(event);
+
+ this.instance.options.helper = this.instance.options._helper;
+
+ //If the helper has been the original item, restore properties in the sortable
+ if(inst.options.helper == 'original')
+ this.instance.currentItem.css({ top: 'auto', left: 'auto' });
+
+ } else {
+ this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
+ this.instance._trigger("deactivate", event, uiSortable);
+ }
+
+ });
+
+ },
+ drag: function(event, ui) {
+
+ var inst = $(this).data("draggable"), self = this;
+
+ var checkPos = function(o) {
+ var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
+ var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
+ var itemHeight = o.height, itemWidth = o.width;
+ var itemTop = o.top, itemLeft = o.left;
+
+ return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
+ };
+
+ $.each(inst.sortables, function(i) {
+
+ //Copy over some variables to allow calling the sortable's native _intersectsWith
+ this.instance.positionAbs = inst.positionAbs;
+ this.instance.helperProportions = inst.helperProportions;
+ this.instance.offset.click = inst.offset.click;
+
+ if(this.instance._intersectsWith(this.instance.containerCache)) {
+
+ //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
+ if(!this.instance.isOver) {
+
+ this.instance.isOver = 1;
+ //Now we fake the start of dragging for the sortable instance,
+ //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
+ //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
+ this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
+ this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
+ this.instance.options.helper = function() { return ui.helper[0]; };
+
+ event.target = this.instance.currentItem[0];
+ this.instance._mouseCapture(event, true);
+ this.instance._mouseStart(event, true, true);
+
+ //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
+ this.instance.offset.click.top = inst.offset.click.top;
+ this.instance.offset.click.left = inst.offset.click.left;
+ this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
+ this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
+
+ inst._trigger("toSortable", event);
+ inst.dropped = this.instance.element; //draggable revert needs that
+ //hack so receive/update callbacks work (mostly)
+ inst.currentItem = inst.element;
+ this.instance.fromOutside = inst;
+
+ }
+
+ //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
+ if(this.instance.currentItem) this.instance._mouseDrag(event);
+
+ } else {
+
+ //If it doesn't intersect with the sortable, and it intersected before,
+ //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
+ if(this.instance.isOver) {
+
+ this.instance.isOver = 0;
+ this.instance.cancelHelperRemoval = true;
+
+ //Prevent reverting on this forced stop
+ this.instance.options.revert = false;
+
+ // The out event needs to be triggered independently
+ this.instance._trigger('out', event, this.instance._uiHash(this.instance));
+
+ this.instance._mouseStop(event, true);
+ this.instance.options.helper = this.instance.options._helper;
+
+ //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
+ this.instance.currentItem.remove();
+ if(this.instance.placeholder) this.instance.placeholder.remove();
+
+ inst._trigger("fromSortable", event);
+ inst.dropped = false; //draggable revert needs that
+ }
+
+ };
+
+ });
+
+ }
+});
+
+$.ui.plugin.add("draggable", "cursor", {
+ start: function(event, ui) {
+ var t = $('body'), o = $(this).data('draggable').options;
+ if (t.css("cursor")) o._cursor = t.css("cursor");
+ t.css("cursor", o.cursor);
+ },
+ stop: function(event, ui) {
+ var o = $(this).data('draggable').options;
+ if (o._cursor) $('body').css("cursor", o._cursor);
+ }
+});
+
+$.ui.plugin.add("draggable", "opacity", {
+ start: function(event, ui) {
+ var t = $(ui.helper), o = $(this).data('draggable').options;
+ if(t.css("opacity")) o._opacity = t.css("opacity");
+ t.css('opacity', o.opacity);
+ },
+ stop: function(event, ui) {
+ var o = $(this).data('draggable').options;
+ if(o._opacity) $(ui.helper).css('opacity', o._opacity);
+ }
+});
+
+$.ui.plugin.add("draggable", "scroll", {
+ start: function(event, ui) {
+ var i = $(this).data("draggable");
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
+ },
+ drag: function(event, ui) {
+
+ var i = $(this).data("draggable"), o = i.options, scrolled = false;
+
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
+
+ if(!o.axis || o.axis != 'x') {
+ if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
+ else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
+ }
+
+ if(!o.axis || o.axis != 'y') {
+ if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
+ else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
+ }
+
+ } else {
+
+ if(!o.axis || o.axis != 'x') {
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+ }
+
+ if(!o.axis || o.axis != 'y') {
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+ }
+
+ }
+
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(i, event);
+
+ }
+});
+
+$.ui.plugin.add("draggable", "snap", {
+ start: function(event, ui) {
+
+ var i = $(this).data("draggable"), o = i.options;
+ i.snapElements = [];
+
+ $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
+ var $t = $(this); var $o = $t.offset();
+ if(this != i.element[0]) i.snapElements.push({
+ item: this,
+ width: $t.outerWidth(), height: $t.outerHeight(),
+ top: $o.top, left: $o.left
+ });
+ });
+
+ },
+ drag: function(event, ui) {
+
+ var inst = $(this).data("draggable"), o = inst.options;
+ var d = o.snapTolerance;
+
+ var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
+ y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
+
+ for (var i = inst.snapElements.length - 1; i >= 0; i--){
+
+ var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
+ t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
+
+ //Yes, I know, this is insane ;)
+ if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
+ if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+ inst.snapElements[i].snapping = false;
+ continue;
+ }
+
+ if(o.snapMode != 'inner') {
+ var ts = Math.abs(t - y2) <= d;
+ var bs = Math.abs(b - y1) <= d;
+ var ls = Math.abs(l - x2) <= d;
+ var rs = Math.abs(r - x1) <= d;
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
+ }
+
+ var first = (ts || bs || ls || rs);
+
+ if(o.snapMode != 'outer') {
+ var ts = Math.abs(t - y1) <= d;
+ var bs = Math.abs(b - y2) <= d;
+ var ls = Math.abs(l - x1) <= d;
+ var rs = Math.abs(r - x2) <= d;
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
+ }
+
+ if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
+ (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+ inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
+
+ };
+
+ }
+});
+
+$.ui.plugin.add("draggable", "stack", {
+ start: function(event, ui) {
+
+ var o = $(this).data("draggable").options;
+
+ var group = $.makeArray($(o.stack)).sort(function(a,b) {
+ return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
+ });
+ if (!group.length) { return; }
+
+ var min = parseInt(group[0].style.zIndex) || 0;
+ $(group).each(function(i) {
+ this.style.zIndex = min + i;
+ });
+
+ this[0].style.zIndex = min + group.length;
+
+ }
+});
+
+$.ui.plugin.add("draggable", "zIndex", {
+ start: function(event, ui) {
+ var t = $(ui.helper), o = $(this).data("draggable").options;
+ if(t.css("zIndex")) o._zIndex = t.css("zIndex");
+ t.css('zIndex', o.zIndex);
+ },
+ stop: function(event, ui) {
+ var o = $(this).data("draggable").options;
+ if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
+ }
+});
+
+})(jQuery);
+/*
+ * jQuery UI Droppable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Droppables
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ * jquery.ui.mouse.js
+ * jquery.ui.draggable.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.droppable", {
+ widgetEventPrefix: "drop",
+ options: {
+ accept: '*',
+ activeClass: false,
+ addClasses: true,
+ greedy: false,
+ hoverClass: false,
+ scope: 'default',
+ tolerance: 'intersect'
+ },
+ _create: function() {
+
+ var o = this.options, accept = o.accept;
+ this.isover = 0; this.isout = 1;
+
+ this.accept = $.isFunction(accept) ? accept : function(d) {
+ return d.is(accept);
+ };
+
+ //Store the droppable's proportions
+ this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
+
+ // Add the reference and positions to the manager
+ $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
+ $.ui.ddmanager.droppables[o.scope].push(this);
+
+ (o.addClasses && this.element.addClass("ui-droppable"));
+
+ },
+
+ destroy: function() {
+ var drop = $.ui.ddmanager.droppables[this.options.scope];
+ for ( var i = 0; i < drop.length; i++ )
+ if ( drop[i] == this )
+ drop.splice(i, 1);
+
+ this.element
+ .removeClass("ui-droppable ui-droppable-disabled")
+ .removeData("droppable")
+ .unbind(".droppable");
+
+ return this;
+ },
+
+ _setOption: function(key, value) {
+
+ if(key == 'accept') {
+ this.accept = $.isFunction(value) ? value : function(d) {
+ return d.is(value);
+ };
+ }
+ $.Widget.prototype._setOption.apply(this, arguments);
+ },
+
+ _activate: function(event) {
+ var draggable = $.ui.ddmanager.current;
+ if(this.options.activeClass) this.element.addClass(this.options.activeClass);
+ (draggable && this._trigger('activate', event, this.ui(draggable)));
+ },
+
+ _deactivate: function(event) {
+ var draggable = $.ui.ddmanager.current;
+ if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
+ (draggable && this._trigger('deactivate', event, this.ui(draggable)));
+ },
+
+ _over: function(event) {
+
+ var draggable = $.ui.ddmanager.current;
+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
+
+ if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+ if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
+ this._trigger('over', event, this.ui(draggable));
+ }
+
+ },
+
+ _out: function(event) {
+
+ var draggable = $.ui.ddmanager.current;
+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
+
+ if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+ if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
+ this._trigger('out', event, this.ui(draggable));
+ }
+
+ },
+
+ _drop: function(event,custom) {
+
+ var draggable = custom || $.ui.ddmanager.current;
+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
+
+ var childrenIntersection = false;
+ this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
+ var inst = $.data(this, 'droppable');
+ if(
+ inst.options.greedy
+ && !inst.options.disabled
+ && inst.options.scope == draggable.options.scope
+ && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
+ && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
+ ) { childrenIntersection = true; return false; }
+ });
+ if(childrenIntersection) return false;
+
+ if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+ if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
+ if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
+ this._trigger('drop', event, this.ui(draggable));
+ return this.element;
+ }
+
+ return false;
+
+ },
+
+ ui: function(c) {
+ return {
+ draggable: (c.currentItem || c.element),
+ helper: c.helper,
+ position: c.position,
+ offset: c.positionAbs
+ };
+ }
+
+});
+
+$.extend($.ui.droppable, {
+ version: "1.8.16"
+});
+
+$.ui.intersect = function(draggable, droppable, toleranceMode) {
+
+ if (!droppable.offset) return false;
+
+ var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
+ y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
+ var l = droppable.offset.left, r = l + droppable.proportions.width,
+ t = droppable.offset.top, b = t + droppable.proportions.height;
+
+ switch (toleranceMode) {
+ case 'fit':
+ return (l <= x1 && x2 <= r
+ && t <= y1 && y2 <= b);
+ break;
+ case 'intersect':
+ return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
+ && x2 - (draggable.helperProportions.width / 2) < r // Left Half
+ && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
+ && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
+ break;
+ case 'pointer':
+ var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
+ draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
+ isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
+ return isOver;
+ break;
+ case 'touch':
+ return (
+ (y1 >= t && y1 <= b) || // Top edge touching
+ (y2 >= t && y2 <= b) || // Bottom edge touching
+ (y1 < t && y2 > b) // Surrounded vertically
+ ) && (
+ (x1 >= l && x1 <= r) || // Left edge touching
+ (x2 >= l && x2 <= r) || // Right edge touching
+ (x1 < l && x2 > r) // Surrounded horizontally
+ );
+ break;
+ default:
+ return false;
+ break;
+ }
+
+};
+
+/*
+ This manager tracks offsets of draggables and droppables
+*/
+$.ui.ddmanager = {
+ current: null,
+ droppables: { 'default': [] },
+ prepareOffsets: function(t, event) {
+
+ var m = $.ui.ddmanager.droppables[t.options.scope] || [];
+ var type = event ? event.type : null; // workaround for #2317
+ var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
+
+ droppablesLoop: for (var i = 0; i < m.length; i++) {
+
+ if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
+ for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
+ m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
+
+ if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
+
+ m[i].offset = m[i].element.offset();
+ m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
+
+ }
+
+ },
+ drop: function(draggable, event) {
+
+ var dropped = false;
+ $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
+
+ if(!this.options) return;
+ if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
+ dropped = dropped || this._drop.call(this, event);
+
+ if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+ this.isout = 1; this.isover = 0;
+ this._deactivate.call(this, event);
+ }
+
+ });
+ return dropped;
+
+ },
+ dragStart: function( draggable, event ) {
+ //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
+ draggable.element.parents( ":not(body,html)" ).bind( "scroll.droppable", function() {
+ if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
+ });
+ },
+ drag: function(draggable, event) {
+
+ //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
+ if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
+
+ //Run through all droppables and check their positions based on specific tolerance options
+ $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
+
+ if(this.options.disabled || this.greedyChild || !this.visible) return;
+ var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
+
+ var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
+ if(!c) return;
+
+ var parentInstance;
+ if (this.options.greedy) {
+ var parent = this.element.parents(':data(droppable):eq(0)');
+ if (parent.length) {
+ parentInstance = $.data(parent[0], 'droppable');
+ parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
+ }
+ }
+
+ // we just moved into a greedy child
+ if (parentInstance && c == 'isover') {
+ parentInstance['isover'] = 0;
+ parentInstance['isout'] = 1;
+ parentInstance._out.call(parentInstance, event);
+ }
+
+ this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
+ this[c == "isover" ? "_over" : "_out"].call(this, event);
+
+ // we just moved out of a greedy child
+ if (parentInstance && c == 'isout') {
+ parentInstance['isout'] = 0;
+ parentInstance['isover'] = 1;
+ parentInstance._over.call(parentInstance, event);
+ }
+ });
+
+ },
+ dragStop: function( draggable, event ) {
+ draggable.element.parents( ":not(body,html)" ).unbind( "scroll.droppable" );
+ //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
+ if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
+ }
+};
+
+})(jQuery);
+/*
+ * jQuery UI Resizable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizables
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.mouse.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.resizable", $.ui.mouse, {
+ widgetEventPrefix: "resize",
+ options: {
+ alsoResize: false,
+ animate: false,
+ animateDuration: "slow",
+ animateEasing: "swing",
+ aspectRatio: false,
+ autoHide: false,
+ containment: false,
+ ghost: false,
+ grid: false,
+ handles: "e,s,se",
+ helper: false,
+ maxHeight: null,
+ maxWidth: null,
+ minHeight: 10,
+ minWidth: 10,
+ zIndex: 1000
+ },
+ _create: function() {
+
+ var self = this, o = this.options;
+ this.element.addClass("ui-resizable");
+
+ $.extend(this, {
+ _aspectRatio: !!(o.aspectRatio),
+ aspectRatio: o.aspectRatio,
+ originalElement: this.element,
+ _proportionallyResizeElements: [],
+ _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
+ });
+
+ //Wrap the element if it cannot hold child nodes
+ if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
+
+ //Opera fix for relative positioning
+ if (/relative/.test(this.element.css('position')) && $.browser.opera)
+ this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+ //Create a wrapper element and set the wrapper to the new current internal element
+ this.element.wrap(
+ $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
+ position: this.element.css('position'),
+ width: this.element.outerWidth(),
+ height: this.element.outerHeight(),
+ top: this.element.css('top'),
+ left: this.element.css('left')
+ })
+ );
+
+ //Overwrite the original this.element
+ this.element = this.element.parent().data(
+ "resizable", this.element.data('resizable')
+ );
+
+ this.elementIsWrapper = true;
+
+ //Move margins to the wrapper
+ this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
+ this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
+
+ //Prevent Safari textarea resize
+ this.originalResizeStyle = this.originalElement.css('resize');
+ this.originalElement.css('resize', 'none');
+
+ //Push the actual element to our proportionallyResize internal array
+ this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
+
+ // avoid IE jump (hard set the margin)
+ this.originalElement.css({ margin: this.originalElement.css('margin') });
+
+ // fix handlers offset
+ this._proportionallyResize();
+
+ }
+
+ this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
+ if(this.handles.constructor == String) {
+
+ if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
+ var n = this.handles.split(","); this.handles = {};
+
+ for(var i = 0; i < n.length; i++) {
+
+ var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
+ var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
+
+ // increase zIndex of sw, se, ne, nw axis
+ //TODO : this modifies original option
+ if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
+
+ //TODO : What's going on here?
+ if ('se' == handle) {
+ axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
+ };
+
+ //Insert into internal handles object and append to element
+ this.handles[handle] = '.ui-resizable-'+handle;
+ this.element.append(axis);
+ }
+
+ }
+
+ this._renderAxis = function(target) {
+
+ target = target || this.element;
+
+ for(var i in this.handles) {
+
+ if(this.handles[i].constructor == String)
+ this.handles[i] = $(this.handles[i], this.element).show();
+
+ //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
+ if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
+
+ var axis = $(this.handles[i], this.element), padWrapper = 0;
+
+ //Checking the correct pad and border
+ padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
+
+ //The padding type i have to apply...
+ var padPos = [ 'padding',
+ /ne|nw|n/.test(i) ? 'Top' :
+ /se|sw|s/.test(i) ? 'Bottom' :
+ /^e$/.test(i) ? 'Right' : 'Left' ].join("");
+
+ target.css(padPos, padWrapper);
+
+ this._proportionallyResize();
+
+ }
+
+ //TODO: What's that good for? There's not anything to be executed left
+ if(!$(this.handles[i]).length)
+ continue;
+
+ }
+ };
+
+ //TODO: make renderAxis a prototype function
+ this._renderAxis(this.element);
+
+ this._handles = $('.ui-resizable-handle', this.element)
+ .disableSelection();
+
+ //Matching axis name
+ this._handles.mouseover(function() {
+ if (!self.resizing) {
+ if (this.className)
+ var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
+ //Axis, default = se
+ self.axis = axis && axis[1] ? axis[1] : 'se';
+ }
+ });
+
+ //If we want to auto hide the elements
+ if (o.autoHide) {
+ this._handles.hide();
+ $(this.element)
+ .addClass("ui-resizable-autohide")
+ .hover(function() {
+ if (o.disabled) return;
+ $(this).removeClass("ui-resizable-autohide");
+ self._handles.show();
+ },
+ function(){
+ if (o.disabled) return;
+ if (!self.resizing) {
+ $(this).addClass("ui-resizable-autohide");
+ self._handles.hide();
+ }
+ });
+ }
+
+ //Initialize the mouse interaction
+ this._mouseInit();
+
+ },
+
+ destroy: function() {
+
+ this._mouseDestroy();
+
+ var _destroy = function(exp) {
+ $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
+ .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
+ };
+
+ //TODO: Unwrap at same DOM position
+ if (this.elementIsWrapper) {
+ _destroy(this.element);
+ var wrapper = this.element;
+ wrapper.after(
+ this.originalElement.css({
+ position: wrapper.css('position'),
+ width: wrapper.outerWidth(),
+ height: wrapper.outerHeight(),
+ top: wrapper.css('top'),
+ left: wrapper.css('left')
+ })
+ ).remove();
+ }
+
+ this.originalElement.css('resize', this.originalResizeStyle);
+ _destroy(this.originalElement);
+
+ return this;
+ },
+
+ _mouseCapture: function(event) {
+ var handle = false;
+ for (var i in this.handles) {
+ if ($(this.handles[i])[0] == event.target) {
+ handle = true;
+ }
+ }
+
+ return !this.options.disabled && handle;
+ },
+
+ _mouseStart: function(event) {
+
+ var o = this.options, iniPos = this.element.position(), el = this.element;
+
+ this.resizing = true;
+ this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
+
+ // bugfix for http://dev.jquery.com/ticket/1749
+ if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
+ el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
+ }
+
+ //Opera fixing relative position
+ if ($.browser.opera && (/relative/).test(el.css('position')))
+ el.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+ this._renderProxy();
+
+ var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
+
+ if (o.containment) {
+ curleft += $(o.containment).scrollLeft() || 0;
+ curtop += $(o.containment).scrollTop() || 0;
+ }
+
+ //Store needed variables
+ this.offset = this.helper.offset();
+ this.position = { left: curleft, top: curtop };
+ this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+ this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+ this.originalPosition = { left: curleft, top: curtop };
+ this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
+ this.originalMousePosition = { left: event.pageX, top: event.pageY };
+
+ //Aspect Ratio
+ this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
+
+ var cursor = $('.ui-resizable-' + this.axis).css('cursor');
+ $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
+
+ el.addClass("ui-resizable-resizing");
+ this._propagate("start", event);
+ return true;
+ },
+
+ _mouseDrag: function(event) {
+
+ //Increase performance, avoid regex
+ var el = this.helper, o = this.options, props = {},
+ self = this, smp = this.originalMousePosition, a = this.axis;
+
+ var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
+ var trigger = this._change[a];
+ if (!trigger) return false;
+
+ // Calculate the attrs that will be change
+ var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
+
+ // Put this in the mouseDrag handler since the user can start pressing shift while resizing
+ this._updateVirtualBoundaries(event.shiftKey);
+ if (this._aspectRatio || event.shiftKey)
+ data = this._updateRatio(data, event);
+
+ data = this._respectSize(data, event);
+
+ // plugins callbacks need to be called first
+ this._propagate("resize", event);
+
+ el.css({
+ top: this.position.top + "px", left: this.position.left + "px",
+ width: this.size.width + "px", height: this.size.height + "px"
+ });
+
+ if (!this._helper && this._proportionallyResizeElements.length)
+ this._proportionallyResize();
+
+ this._updateCache(data);
+
+ // calling the user callback at the end
+ this._trigger('resize', event, this.ui());
+
+ return false;
+ },
+
+ _mouseStop: function(event) {
+
+ this.resizing = false;
+ var o = this.options, self = this;
+
+ if(this._helper) {
+ var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+ soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+ soffsetw = ista ? 0 : self.sizeDiff.width;
+
+ var s = { width: (self.helper.width() - soffsetw), height: (self.helper.height() - soffseth) },
+ left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+ top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+ if (!o.animate)
+ this.element.css($.extend(s, { top: top, left: left }));
+
+ self.helper.height(self.size.height);
+ self.helper.width(self.size.width);
+
+ if (this._helper && !o.animate) this._proportionallyResize();
+ }
+
+ $('body').css('cursor', 'auto');
+
+ this.element.removeClass("ui-resizable-resizing");
+
+ this._propagate("stop", event);
+
+ if (this._helper) this.helper.remove();
+ return false;
+
+ },
+
+ _updateVirtualBoundaries: function(forceAspectRatio) {
+ var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
+
+ b = {
+ minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
+ maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
+ minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
+ maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
+ };
+
+ if(this._aspectRatio || forceAspectRatio) {
+ // We want to create an enclosing box whose aspect ration is the requested one
+ // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
+ pMinWidth = b.minHeight * this.aspectRatio;
+ pMinHeight = b.minWidth / this.aspectRatio;
+ pMaxWidth = b.maxHeight * this.aspectRatio;
+ pMaxHeight = b.maxWidth / this.aspectRatio;
+
+ if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
+ if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
+ if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
+ if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
+ }
+ this._vBoundaries = b;
+ },
+
+ _updateCache: function(data) {
+ var o = this.options;
+ this.offset = this.helper.offset();
+ if (isNumber(data.left)) this.position.left = data.left;
+ if (isNumber(data.top)) this.position.top = data.top;
+ if (isNumber(data.height)) this.size.height = data.height;
+ if (isNumber(data.width)) this.size.width = data.width;
+ },
+
+ _updateRatio: function(data, event) {
+
+ var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
+
+ if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
+ else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
+
+ if (a == 'sw') {
+ data.left = cpos.left + (csize.width - data.width);
+ data.top = null;
+ }
+ if (a == 'nw') {
+ data.top = cpos.top + (csize.height - data.height);
+ data.left = cpos.left + (csize.width - data.width);
+ }
+
+ return data;
+ },
+
+ _respectSize: function(data, event) {
+
+ var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
+ ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
+ isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
+
+ if (isminw) data.width = o.minWidth;
+ if (isminh) data.height = o.minHeight;
+ if (ismaxw) data.width = o.maxWidth;
+ if (ismaxh) data.height = o.maxHeight;
+
+ var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
+ var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
+
+ if (isminw && cw) data.left = dw - o.minWidth;
+ if (ismaxw && cw) data.left = dw - o.maxWidth;
+ if (isminh && ch) data.top = dh - o.minHeight;
+ if (ismaxh && ch) data.top = dh - o.maxHeight;
+
+ // fixing jump error on top/left - bug #2330
+ var isNotwh = !data.width && !data.height;
+ if (isNotwh && !data.left && data.top) data.top = null;
+ else if (isNotwh && !data.top && data.left) data.left = null;
+
+ return data;
+ },
+
+ _proportionallyResize: function() {
+
+ var o = this.options;
+ if (!this._proportionallyResizeElements.length) return;
+ var element = this.helper || this.element;
+
+ for (var i=0; i < this._proportionallyResizeElements.length; i++) {
+
+ var prel = this._proportionallyResizeElements[i];
+
+ if (!this.borderDif) {
+ var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
+ p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
+
+ this.borderDif = $.map(b, function(v, i) {
+ var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
+ return border + padding;
+ });
+ }
+
+ if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
+ continue;
+
+ prel.css({
+ height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
+ width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
+ });
+
+ };
+
+ },
+
+ _renderProxy: function() {
+
+ var el = this.element, o = this.options;
+ this.elementOffset = el.offset();
+
+ if(this._helper) {
+
+ this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
+
+ // fix ie6 offset TODO: This seems broken
+ var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
+ pxyoffset = ( ie6 ? 2 : -1 );
+
+ this.helper.addClass(this._helper).css({
+ width: this.element.outerWidth() + pxyoffset,
+ height: this.element.outerHeight() + pxyoffset,
+ position: 'absolute',
+ left: this.elementOffset.left - ie6offset +'px',
+ top: this.elementOffset.top - ie6offset +'px',
+ zIndex: ++o.zIndex //TODO: Don't modify option
+ });
+
+ this.helper
+ .appendTo("body")
+ .disableSelection();
+
+ } else {
+ this.helper = this.element;
+ }
+
+ },
+
+ _change: {
+ e: function(event, dx, dy) {
+ return { width: this.originalSize.width + dx };
+ },
+ w: function(event, dx, dy) {
+ var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+ return { left: sp.left + dx, width: cs.width - dx };
+ },
+ n: function(event, dx, dy) {
+ var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+ return { top: sp.top + dy, height: cs.height - dy };
+ },
+ s: function(event, dx, dy) {
+ return { height: this.originalSize.height + dy };
+ },
+ se: function(event, dx, dy) {
+ return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+ },
+ sw: function(event, dx, dy) {
+ return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+ },
+ ne: function(event, dx, dy) {
+ return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+ },
+ nw: function(event, dx, dy) {
+ return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+ }
+ },
+
+ _propagate: function(n, event) {
+ $.ui.plugin.call(this, n, [event, this.ui()]);
+ (n != "resize" && this._trigger(n, event, this.ui()));
+ },
+
+ plugins: {},
+
+ ui: function() {
+ return {
+ originalElement: this.originalElement,
+ element: this.element,
+ helper: this.helper,
+ position: this.position,
+ size: this.size,
+ originalSize: this.originalSize,
+ originalPosition: this.originalPosition
+ };
+ }
+
+});
+
+$.extend($.ui.resizable, {
+ version: "1.8.16"
+});
+
+/*
+ * Resizable Extensions
+ */
+
+$.ui.plugin.add("resizable", "alsoResize", {
+
+ start: function (event, ui) {
+ var self = $(this).data("resizable"), o = self.options;
+
+ var _store = function (exp) {
+ $(exp).each(function() {
+ var el = $(this);
+ el.data("resizable-alsoresize", {
+ width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
+ left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10),
+ position: el.css('position') // to reset Opera on stop()
+ });
+ });
+ };
+
+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
+ if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
+ else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
+ }else{
+ _store(o.alsoResize);
+ }
+ },
+
+ resize: function (event, ui) {
+ var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
+
+ var delta = {
+ height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
+ top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
+ },
+
+ _alsoResize = function (exp, c) {
+ $(exp).each(function() {
+ var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
+ css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
+
+ $.each(css, function (i, prop) {
+ var sum = (start[prop]||0) + (delta[prop]||0);
+ if (sum && sum >= 0)
+ style[prop] = sum || null;
+ });
+
+ // Opera fixing relative position
+ if ($.browser.opera && /relative/.test(el.css('position'))) {
+ self._revertToRelativePosition = true;
+ el.css({ position: 'absolute', top: 'auto', left: 'auto' });
+ }
+
+ el.css(style);
+ });
+ };
+
+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
+ $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
+ }else{
+ _alsoResize(o.alsoResize);
+ }
+ },
+
+ stop: function (event, ui) {
+ var self = $(this).data("resizable"), o = self.options;
+
+ var _reset = function (exp) {
+ $(exp).each(function() {
+ var el = $(this);
+ // reset position for Opera - no need to verify it was changed
+ el.css({ position: el.data("resizable-alsoresize").position });
+ });
+ };
+
+ if (self._revertToRelativePosition) {
+ self._revertToRelativePosition = false;
+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
+ $.each(o.alsoResize, function (exp) { _reset(exp); });
+ }else{
+ _reset(o.alsoResize);
+ }
+ }
+
+ $(this).removeData("resizable-alsoresize");
+ }
+});
+
+$.ui.plugin.add("resizable", "animate", {
+
+ stop: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options;
+
+ var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+ soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+ soffsetw = ista ? 0 : self.sizeDiff.width;
+
+ var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+ left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+ top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+ self.element.animate(
+ $.extend(style, top && left ? { top: top, left: left } : {}), {
+ duration: o.animateDuration,
+ easing: o.animateEasing,
+ step: function() {
+
+ var data = {
+ width: parseInt(self.element.css('width'), 10),
+ height: parseInt(self.element.css('height'), 10),
+ top: parseInt(self.element.css('top'), 10),
+ left: parseInt(self.element.css('left'), 10)
+ };
+
+ if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
+
+ // propagating resize, and updating values for each animation step
+ self._updateCache(data);
+ self._propagate("resize", event);
+
+ }
+ }
+ );
+ }
+
+});
+
+$.ui.plugin.add("resizable", "containment", {
+
+ start: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options, el = self.element;
+ var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
+ if (!ce) return;
+
+ self.containerElement = $(ce);
+
+ if (/document/.test(oc) || oc == document) {
+ self.containerOffset = { left: 0, top: 0 };
+ self.containerPosition = { left: 0, top: 0 };
+
+ self.parentData = {
+ element: $(document), left: 0, top: 0,
+ width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
+ };
+ }
+
+ // i'm a node, so compute top, left, right, bottom
+ else {
+ var element = $(ce), p = [];
+ $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
+
+ self.containerOffset = element.offset();
+ self.containerPosition = element.position();
+ self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
+
+ var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
+ width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
+
+ self.parentData = {
+ element: ce, left: co.left, top: co.top, width: width, height: height
+ };
+ }
+ },
+
+ resize: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options,
+ ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
+ pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
+
+ if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
+
+ if (cp.left < (self._helper ? co.left : 0)) {
+ self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
+ if (pRatio) self.size.height = self.size.width / o.aspectRatio;
+ self.position.left = o.helper ? co.left : 0;
+ }
+
+ if (cp.top < (self._helper ? co.top : 0)) {
+ self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
+ if (pRatio) self.size.width = self.size.height * o.aspectRatio;
+ self.position.top = self._helper ? co.top : 0;
+ }
+
+ self.offset.left = self.parentData.left+self.position.left;
+ self.offset.top = self.parentData.top+self.position.top;
+
+ var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
+ hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
+
+ var isParent = self.containerElement.get(0) == self.element.parent().get(0),
+ isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
+
+ if(isParent && isOffsetRelative) woset -= self.parentData.left;
+
+ if (woset + self.size.width >= self.parentData.width) {
+ self.size.width = self.parentData.width - woset;
+ if (pRatio) self.size.height = self.size.width / self.aspectRatio;
+ }
+
+ if (hoset + self.size.height >= self.parentData.height) {
+ self.size.height = self.parentData.height - hoset;
+ if (pRatio) self.size.width = self.size.height * self.aspectRatio;
+ }
+ },
+
+ stop: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options, cp = self.position,
+ co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
+
+ var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
+
+ if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
+ $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+ if (self._helper && !o.animate && (/static/).test(ce.css('position')))
+ $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+ }
+});
+
+$.ui.plugin.add("resizable", "ghost", {
+
+ start: function(event, ui) {
+
+ var self = $(this).data("resizable"), o = self.options, cs = self.size;
+
+ self.ghost = self.originalElement.clone();
+ self.ghost
+ .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
+ .addClass('ui-resizable-ghost')
+ .addClass(typeof o.ghost == 'string' ? o.ghost : '');
+
+ self.ghost.appendTo(self.helper);
+
+ },
+
+ resize: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options;
+ if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
+ },
+
+ stop: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options;
+ if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
+ }
+
+});
+
+$.ui.plugin.add("resizable", "grid", {
+
+ resize: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
+ o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
+ var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
+
+ if (/^(se|s|e)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ }
+ else if (/^(ne)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.top = op.top - oy;
+ }
+ else if (/^(sw)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.left = op.left - ox;
+ }
+ else {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.top = op.top - oy;
+ self.position.left = op.left - ox;
+ }
+ }
+
+});
+
+var num = function(v) {
+ return parseInt(v, 10) || 0;
+};
+
+var isNumber = function(value) {
+ return !isNaN(parseInt(value, 10));
+};
+
+})(jQuery);
+/*
+ * jQuery UI Selectable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Selectables
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.mouse.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.selectable", $.ui.mouse, {
+ options: {
+ appendTo: 'body',
+ autoRefresh: true,
+ distance: 0,
+ filter: '*',
+ tolerance: 'touch'
+ },
+ _create: function() {
+ var self = this;
+
+ this.element.addClass("ui-selectable");
+
+ this.dragged = false;
+
+ // cache selectee children based on filter
+ var selectees;
+ this.refresh = function() {
+ selectees = $(self.options.filter, self.element[0]);
+ selectees.each(function() {
+ var $this = $(this);
+ var pos = $this.offset();
+ $.data(this, "selectable-item", {
+ element: this,
+ $element: $this,
+ left: pos.left,
+ top: pos.top,
+ right: pos.left + $this.outerWidth(),
+ bottom: pos.top + $this.outerHeight(),
+ startselected: false,
+ selected: $this.hasClass('ui-selected'),
+ selecting: $this.hasClass('ui-selecting'),
+ unselecting: $this.hasClass('ui-unselecting')
+ });
+ });
+ };
+ this.refresh();
+
+ this.selectees = selectees.addClass("ui-selectee");
+
+ this._mouseInit();
+
+ this.helper = $("<div class='ui-selectable-helper'></div>");
+ },
+
+ destroy: function() {
+ this.selectees
+ .removeClass("ui-selectee")
+ .removeData("selectable-item");
+ this.element
+ .removeClass("ui-selectable ui-selectable-disabled")
+ .removeData("selectable")
+ .unbind(".selectable");
+ this._mouseDestroy();
+
+ return this;
+ },
+
+ _mouseStart: function(event) {
+ var self = this;
+
+ this.opos = [event.pageX, event.pageY];
+
+ if (this.options.disabled)
+ return;
+
+ var options = this.options;
+
+ this.selectees = $(options.filter, this.element[0]);
+
+ this._trigger("start", event);
+
+ $(options.appendTo).append(this.helper);
+ // position helper (lasso)
+ this.helper.css({
+ "left": event.clientX,
+ "top": event.clientY,
+ "width": 0,
+ "height": 0
+ });
+
+ if (options.autoRefresh) {
+ this.refresh();
+ }
+
+ this.selectees.filter('.ui-selected').each(function() {
+ var selectee = $.data(this, "selectable-item");
+ selectee.startselected = true;
+ if (!event.metaKey) {
+ selectee.$element.removeClass('ui-selected');
+ selectee.selected = false;
+ selectee.$element.addClass('ui-unselecting');
+ selectee.unselecting = true;
+ // selectable UNSELECTING callback
+ self._trigger("unselecting", event, {
+ unselecting: selectee.element
+ });
+ }
+ });
+
+ $(event.target).parents().andSelf().each(function() {
+ var selectee = $.data(this, "selectable-item");
+ if (selectee) {
+ var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');
+ selectee.$element
+ .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
+ .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
+ selectee.unselecting = !doSelect;
+ selectee.selecting = doSelect;
+ selectee.selected = doSelect;
+ // selectable (UN)SELECTING callback
+ if (doSelect) {
+ self._trigger("selecting", event, {
+ selecting: selectee.element
+ });
+ } else {
+ self._trigger("unselecting", event, {
+ unselecting: selectee.element
+ });
+ }
+ return false;
+ }
+ });
+
+ },
+
+ _mouseDrag: function(event) {
+ var self = this;
+ this.dragged = true;
+
+ if (this.options.disabled)
+ return;
+
+ var options = this.options;
+
+ var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
+ if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
+ if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
+ this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
+
+ this.selectees.each(function() {
+ var selectee = $.data(this, "selectable-item");
+ //prevent helper from being selected if appendTo: selectable
+ if (!selectee || selectee.element == self.element[0])
+ return;
+ var hit = false;
+ if (options.tolerance == 'touch') {
+ hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
+ } else if (options.tolerance == 'fit') {
+ hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
+ }
+
+ if (hit) {
+ // SELECT
+ if (selectee.selected) {
+ selectee.$element.removeClass('ui-selected');
+ selectee.selected = false;
+ }
+ if (selectee.unselecting) {
+ selectee.$element.removeClass('ui-unselecting');
+ selectee.unselecting = false;
+ }
+ if (!selectee.selecting) {
+ selectee.$element.addClass('ui-selecting');
+ selectee.selecting = true;
+ // selectable SELECTING callback
+ self._trigger("selecting", event, {
+ selecting: selectee.element
+ });
+ }
+ } else {
+ // UNSELECT
+ if (selectee.selecting) {
+ if (event.metaKey && selectee.startselected) {
+ selectee.$element.removeClass('ui-selecting');
+ selectee.selecting = false;
+ selectee.$element.addClass('ui-selected');
+ selectee.selected = true;
+ } else {
+ selectee.$element.removeClass('ui-selecting');
+ selectee.selecting = false;
+ if (selectee.startselected) {
+ selectee.$element.addClass('ui-unselecting');
+ selectee.unselecting = true;
+ }
+ // selectable UNSELECTING callback
+ self._trigger("unselecting", event, {
+ unselecting: selectee.element
+ });
+ }
+ }
+ if (selectee.selected) {
+ if (!event.metaKey && !selectee.startselected) {
+ selectee.$element.removeClass('ui-selected');
+ selectee.selected = false;
+
+ selectee.$element.addClass('ui-unselecting');
+ selectee.unselecting = true;
+ // selectable UNSELECTING callback
+ self._trigger("unselecting", event, {
+ unselecting: selectee.element
+ });
+ }
+ }
+ }
+ });
+
+ return false;
+ },
+
+ _mouseStop: function(event) {
+ var self = this;
+
+ this.dragged = false;
+
+ var options = this.options;
+
+ $('.ui-unselecting', this.element[0]).each(function() {
+ var selectee = $.data(this, "selectable-item");
+ selectee.$element.removeClass('ui-unselecting');
+ selectee.unselecting = false;
+ selectee.startselected = false;
+ self._trigger("unselected", event, {
+ unselected: selectee.element
+ });
+ });
+ $('.ui-selecting', this.element[0]).each(function() {
+ var selectee = $.data(this, "selectable-item");
+ selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
+ selectee.selecting = false;
+ selectee.selected = true;
+ selectee.startselected = true;
+ self._trigger("selected", event, {
+ selected: selectee.element
+ });
+ });
+ this._trigger("stop", event);
+
+ this.helper.remove();
+
+ return false;
+ }
+
+});
+
+$.extend($.ui.selectable, {
+ version: "1.8.16"
+});
+
+})(jQuery);
+/*
+ * jQuery UI Sortable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Sortables
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.mouse.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.sortable", $.ui.mouse, {
+ widgetEventPrefix: "sort",
+ options: {
+ appendTo: "parent",
+ axis: false,
+ connectWith: false,
+ containment: false,
+ cursor: 'auto',
+ cursorAt: false,
+ dropOnEmpty: true,
+ forcePlaceholderSize: false,
+ forceHelperSize: false,
+ grid: false,
+ handle: false,
+ helper: "original",
+ items: '> *',
+ opacity: false,
+ placeholder: false,
+ revert: false,
+ scroll: true,
+ scrollSensitivity: 20,
+ scrollSpeed: 20,
+ scope: "default",
+ tolerance: "intersect",
+ zIndex: 1000
+ },
+ _create: function() {
+
+ var o = this.options;
+ this.containerCache = {};
+ this.element.addClass("ui-sortable");
+
+ //Get the items
+ this.refresh();
+
+ //Let's determine if the items are being displayed horizontally
+ this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
+
+ //Let's determine the parent's offset
+ this.offset = this.element.offset();
+
+ //Initialize mouse events for interaction
+ this._mouseInit();
+
+ },
+
+ destroy: function() {
+ this.element
+ .removeClass("ui-sortable ui-sortable-disabled")
+ .removeData("sortable")
+ .unbind(".sortable");
+ this._mouseDestroy();
+
+ for ( var i = this.items.length - 1; i >= 0; i-- )
+ this.items[i].item.removeData("sortable-item");
+
+ return this;
+ },
+
+ _setOption: function(key, value){
+ if ( key === "disabled" ) {
+ this.options[ key ] = value;
+
+ this.widget()
+ [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
+ } else {
+ // Don't call widget base _setOption for disable as it adds ui-state-disabled class
+ $.Widget.prototype._setOption.apply(this, arguments);
+ }
+ },
+
+ _mouseCapture: function(event, overrideHandle) {
+
+ if (this.reverting) {
+ return false;
+ }
+
+ if(this.options.disabled || this.options.type == 'static') return false;
+
+ //We have to refresh the items data once first
+ this._refreshItems(event);
+
+ //Find out if the clicked node (or one of its parents) is a actual item in this.items
+ var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
+ if($.data(this, 'sortable-item') == self) {
+ currentItem = $(this);
+ return false;
+ }
+ });
+ if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
+
+ if(!currentItem) return false;
+ if(this.options.handle && !overrideHandle) {
+ var validHandle = false;
+
+ $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
+ if(!validHandle) return false;
+ }
+
+ this.currentItem = currentItem;
+ this._removeCurrentsFromItems();
+ return true;
+
+ },
+
+ _mouseStart: function(event, overrideHandle, noActivation) {
+
+ var o = this.options, self = this;
+ this.currentContainer = this;
+
+ //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
+ this.refreshPositions();
+
+ //Create and append the visible helper
+ this.helper = this._createHelper(event);
+
+ //Cache the helper size
+ this._cacheHelperProportions();
+
+ /*
+ * - Position generation -
+ * This block generates everything position related - it's the core of draggables.
+ */
+
+ //Cache the margins of the original element
+ this._cacheMargins();
+
+ //Get the next scrolling parent
+ this.scrollParent = this.helper.scrollParent();
+
+ //The element's absolute position on the page minus margins
+ this.offset = this.currentItem.offset();
+ this.offset = {
+ top: this.offset.top - this.margins.top,
+ left: this.offset.left - this.margins.left
+ };
+
+ // Only after we got the offset, we can change the helper's position to absolute
+ // TODO: Still need to figure out a way to make relative sorting possible
+ this.helper.css("position", "absolute");
+ this.cssPosition = this.helper.css("position");
+
+ $.extend(this.offset, {
+ click: { //Where the click happened, relative to the element
+ left: event.pageX - this.offset.left,
+ top: event.pageY - this.offset.top
+ },
+ parent: this._getParentOffset(),
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
+ });
+
+ //Generate the original position
+ this.originalPosition = this._generatePosition(event);
+ this.originalPageX = event.pageX;
+ this.originalPageY = event.pageY;
+
+ //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+ //Cache the former DOM position
+ this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
+
+ //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
+ if(this.helper[0] != this.currentItem[0]) {
+ this.currentItem.hide();
+ }
+
+ //Create the placeholder
+ this._createPlaceholder();
+
+ //Set a containment if given in the options
+ if(o.containment)
+ this._setContainment();
+
+ if(o.cursor) { // cursor option
+ if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
+ $('body').css("cursor", o.cursor);
+ }
+
+ if(o.opacity) { // opacity option
+ if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
+ this.helper.css("opacity", o.opacity);
+ }
+
+ if(o.zIndex) { // zIndex option
+ if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
+ this.helper.css("zIndex", o.zIndex);
+ }
+
+ //Prepare scrolling
+ if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
+ this.overflowOffset = this.scrollParent.offset();
+
+ //Call callbacks
+ this._trigger("start", event, this._uiHash());
+
+ //Recache the helper size
+ if(!this._preserveHelperProportions)
+ this._cacheHelperProportions();
+
+
+ //Post 'activate' events to possible containers
+ if(!noActivation) {
+ for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
+ }
+
+ //Prepare possible droppables
+ if($.ui.ddmanager)
+ $.ui.ddmanager.current = this;
+
+ if ($.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(this, event);
+
+ this.dragging = true;
+
+ this.helper.addClass("ui-sortable-helper");
+ this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+ return true;
+
+ },
+
+ _mouseDrag: function(event) {
+
+ //Compute the helpers position
+ this.position = this._generatePosition(event);
+ this.positionAbs = this._convertPositionTo("absolute");
+
+ if (!this.lastPositionAbs) {
+ this.lastPositionAbs = this.positionAbs;
+ }
+
+ //Do scrolling
+ if(this.options.scroll) {
+ var o = this.options, scrolled = false;
+ if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
+
+ if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
+ else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
+
+ if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
+ else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
+
+ } else {
+
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+
+ }
+
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(this, event);
+ }
+
+ //Regenerate the absolute position used for position checks
+ this.positionAbs = this._convertPositionTo("absolute");
+
+ //Set the helper position
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
+
+ //Rearrange
+ for (var i = this.items.length - 1; i >= 0; i--) {
+
+ //Cache variables and intersection, continue if no intersection
+ var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
+ if (!intersection) continue;
+
+ if(itemElement != this.currentItem[0] //cannot intersect with itself
+ && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
+ && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
+ && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
+ //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
+ ) {
+
+ this.direction = intersection == 1 ? "down" : "up";
+
+ if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
+ this._rearrange(event, item);
+ } else {
+ break;
+ }
+
+ this._trigger("change", event, this._uiHash());
+ break;
+ }
+ }
+
+ //Post events to containers
+ this._contactContainers(event);
+
+ //Interconnect with droppables
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
+
+ //Call callbacks
+ this._trigger('sort', event, this._uiHash());
+
+ this.lastPositionAbs = this.positionAbs;
+ return false;
+
+ },
+
+ _mouseStop: function(event, noPropagation) {
+
+ if(!event) return;
+
+ //If we are using droppables, inform the manager about the drop
+ if ($.ui.ddmanager && !this.options.dropBehaviour)
+ $.ui.ddmanager.drop(this, event);
+
+ if(this.options.revert) {
+ var self = this;
+ var cur = self.placeholder.offset();
+
+ self.reverting = true;
+
+ $(this.helper).animate({
+ left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
+ top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
+ }, parseInt(this.options.revert, 10) || 500, function() {
+ self._clear(event);
+ });
+ } else {
+ this._clear(event, noPropagation);
+ }
+
+ return false;
+
+ },
+
+ cancel: function() {
+
+ var self = this;
+
+ if(this.dragging) {
+
+ this._mouseUp({ target: null });
+
+ if(this.options.helper == "original")
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+ else
+ this.currentItem.show();
+
+ //Post deactivating events to containers
+ for (var i = this.containers.length - 1; i >= 0; i--){
+ this.containers[i]._trigger("deactivate", null, self._uiHash(this));
+ if(this.containers[i].containerCache.over) {
+ this.containers[i]._trigger("out", null, self._uiHash(this));
+ this.containers[i].containerCache.over = 0;
+ }
+ }
+
+ }
+
+ if (this.placeholder) {
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+ if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+ if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
+
+ $.extend(this, {
+ helper: null,
+ dragging: false,
+ reverting: false,
+ _noFinalSort: null
+ });
+
+ if(this.domPosition.prev) {
+ $(this.domPosition.prev).after(this.currentItem);
+ } else {
+ $(this.domPosition.parent).prepend(this.currentItem);
+ }
+ }
+
+ return this;
+
+ },
+
+ serialize: function(o) {
+
+ var items = this._getItemsAsjQuery(o && o.connected);
+ var str = []; o = o || {};
+
+ $(items).each(function() {
+ var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
+ if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
+ });
+
+ if(!str.length && o.key) {
+ str.push(o.key + '=');
+ }
+
+ return str.join('&');
+
+ },
+
+ toArray: function(o) {
+
+ var items = this._getItemsAsjQuery(o && o.connected);
+ var ret = []; o = o || {};
+
+ items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
+ return ret;
+
+ },
+
+ /* Be careful with the following core functions */
+ _intersectsWith: function(item) {
+
+ var x1 = this.positionAbs.left,
+ x2 = x1 + this.helperProportions.width,
+ y1 = this.positionAbs.top,
+ y2 = y1 + this.helperProportions.height;
+
+ var l = item.left,
+ r = l + item.width,
+ t = item.top,
+ b = t + item.height;
+
+ var dyClick = this.offset.click.top,
+ dxClick = this.offset.click.left;
+
+ var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
+
+ if( this.options.tolerance == "pointer"
+ || this.options.forcePointerForContainers
+ || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
+ ) {
+ return isOverElement;
+ } else {
+
+ return (l < x1 + (this.helperProportions.width / 2) // Right Half
+ && x2 - (this.helperProportions.width / 2) < r // Left Half
+ && t < y1 + (this.helperProportions.height / 2) // Bottom Half
+ && y2 - (this.helperProportions.height / 2) < b ); // Top Half
+
+ }
+ },
+
+ _intersectsWithPointer: function(item) {
+
+ var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
+ isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
+ isOverElement = isOverElementHeight && isOverElementWidth,
+ verticalDirection = this._getDragVerticalDirection(),
+ horizontalDirection = this._getDragHorizontalDirection();
+
+ if (!isOverElement)
+ return false;
+
+ return this.floating ?
+ ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
+ : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
+
+ },
+
+ _intersectsWithSides: function(item) {
+
+ var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
+ isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
+ verticalDirection = this._getDragVerticalDirection(),
+ horizontalDirection = this._getDragHorizontalDirection();
+
+ if (this.floating && horizontalDirection) {
+ return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
+ } else {
+ return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
+ }
+
+ },
+
+ _getDragVerticalDirection: function() {
+ var delta = this.positionAbs.top - this.lastPositionAbs.top;
+ return delta != 0 && (delta > 0 ? "down" : "up");
+ },
+
+ _getDragHorizontalDirection: function() {
+ var delta = this.positionAbs.left - this.lastPositionAbs.left;
+ return delta != 0 && (delta > 0 ? "right" : "left");
+ },
+
+ refresh: function(event) {
+ this._refreshItems(event);
+ this.refreshPositions();
+ return this;
+ },
+
+ _connectWith: function() {
+ var options = this.options;
+ return options.connectWith.constructor == String
+ ? [options.connectWith]
+ : options.connectWith;
+ },
+
+ _getItemsAsjQuery: function(connected) {
+
+ var self = this;
+ var items = [];
+ var queries = [];
+ var connectWith = this._connectWith();
+
+ if(connectWith && connected) {
+ for (var i = connectWith.length - 1; i >= 0; i--){
+ var cur = $(connectWith[i]);
+ for (var j = cur.length - 1; j >= 0; j--){
+ var inst = $.data(cur[j], 'sortable');
+ if(inst && inst != this && !inst.options.disabled) {
+ queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
+ }
+ };
+ };
+ }
+
+ queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
+
+ for (var i = queries.length - 1; i >= 0; i--){
+ queries[i][0].each(function() {
+ items.push(this);
+ });
+ };
+
+ return $(items);
+
+ },
+
+ _removeCurrentsFromItems: function() {
+
+ var list = this.currentItem.find(":data(sortable-item)");
+
+ for (var i=0; i < this.items.length; i++) {
+
+ for (var j=0; j < list.length; j++) {
+ if(list[j] == this.items[i].item[0])
+ this.items.splice(i,1);
+ };
+
+ };
+
+ },
+
+ _refreshItems: function(event) {
+
+ this.items = [];
+ this.containers = [this];
+ var items = this.items;
+ var self = this;
+ var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
+ var connectWith = this._connectWith();
+
+ if(connectWith) {
+ for (var i = connectWith.length - 1; i >= 0; i--){
+ var cur = $(connectWith[i]);
+ for (var j = cur.length - 1; j >= 0; j--){
+ var inst = $.data(cur[j], 'sortable');
+ if(inst && inst != this && !inst.options.disabled) {
+ queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
+ this.containers.push(inst);
+ }
+ };
+ };
+ }
+
+ for (var i = queries.length - 1; i >= 0; i--) {
+ var targetData = queries[i][1];
+ var _queries = queries[i][0];
+
+ for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
+ var item = $(_queries[j]);
+
+ item.data('sortable-item', targetData); // Data for target checking (mouse manager)
+
+ items.push({
+ item: item,
+ instance: targetData,
+ width: 0, height: 0,
+ left: 0, top: 0
+ });
+ };
+ };
+
+ },
+
+ refreshPositions: function(fast) {
+
+ //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
+ if(this.offsetParent && this.helper) {
+ this.offset.parent = this._getParentOffset();
+ }
+
+ for (var i = this.items.length - 1; i >= 0; i--){
+ var item = this.items[i];
+
+ //We ignore calculating positions of all connected containers when we're not over them
+ if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
+ continue;
+
+ var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
+
+ if (!fast) {
+ item.width = t.outerWidth();
+ item.height = t.outerHeight();
+ }
+
+ var p = t.offset();
+ item.left = p.left;
+ item.top = p.top;
+ };
+
+ if(this.options.custom && this.options.custom.refreshContainers) {
+ this.options.custom.refreshContainers.call(this);
+ } else {
+ for (var i = this.containers.length - 1; i >= 0; i--){
+ var p = this.containers[i].element.offset();
+ this.containers[i].containerCache.left = p.left;
+ this.containers[i].containerCache.top = p.top;
+ this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
+ this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
+ };
+ }
+
+ return this;
+ },
+
+ _createPlaceholder: function(that) {
+
+ var self = that || this, o = self.options;
+
+ if(!o.placeholder || o.placeholder.constructor == String) {
+ var className = o.placeholder;
+ o.placeholder = {
+ element: function() {
+
+ var el = $(document.createElement(self.currentItem[0].nodeName))
+ .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
+ .removeClass("ui-sortable-helper")[0];
+
+ if(!className)
+ el.style.visibility = "hidden";
+
+ return el;
+ },
+ update: function(container, p) {
+
+ // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
+ // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
+ if(className && !o.forcePlaceholderSize) return;
+
+ //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
+ if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
+ if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
+ }
+ };
+ }
+
+ //Create the placeholder
+ self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
+
+ //Append it after the actual current item
+ self.currentItem.after(self.placeholder);
+
+ //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
+ o.placeholder.update(self, self.placeholder);
+
+ },
+
+ _contactContainers: function(event) {
+
+ // get innermost container that intersects with item
+ var innermostContainer = null, innermostIndex = null;
+
+
+ for (var i = this.containers.length - 1; i >= 0; i--){
+
+ // never consider a container that's located within the item itself
+ if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
+ continue;
+
+ if(this._intersectsWith(this.containers[i].containerCache)) {
+
+ // if we've already found a container and it's more "inner" than this, then continue
+ if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
+ continue;
+
+ innermostContainer = this.containers[i];
+ innermostIndex = i;
+
+ } else {
+ // container doesn't intersect. trigger "out" event if necessary
+ if(this.containers[i].containerCache.over) {
+ this.containers[i]._trigger("out", event, this._uiHash(this));
+ this.containers[i].containerCache.over = 0;
+ }
+ }
+
+ }
+
+ // if no intersecting containers found, return
+ if(!innermostContainer) return;
+
+ // move the item into the container if it's not there already
+ if(this.containers.length === 1) {
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
+ this.containers[innermostIndex].containerCache.over = 1;
+ } else if(this.currentContainer != this.containers[innermostIndex]) {
+
+ //When entering a new container, we will find the item with the least distance and append our item near it
+ var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top'];
+ for (var j = this.items.length - 1; j >= 0; j--) {
+ if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
+ var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top'];
+ if(Math.abs(cur - base) < dist) {
+ dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
+ }
+ }
+
+ if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
+ return;
+
+ this.currentContainer = this.containers[innermostIndex];
+ itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
+ this._trigger("change", event, this._uiHash());
+ this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
+
+ //Update the placeholder
+ this.options.placeholder.update(this.currentContainer, this.placeholder);
+
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
+ this.containers[innermostIndex].containerCache.over = 1;
+ }
+
+
+ },
+
+ _createHelper: function(event) {
+
+ var o = this.options;
+ var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
+
+ if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
+ $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
+
+ if(helper[0] == this.currentItem[0])
+ this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
+
+ if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
+ if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
+
+ return helper;
+
+ },
+
+ _adjustOffsetFromHelper: function(obj) {
+ if (typeof obj == 'string') {
+ obj = obj.split(' ');
+ }
+ if ($.isArray(obj)) {
+ obj = {left: +obj[0], top: +obj[1] || 0};
+ }
+ if ('left' in obj) {
+ this.offset.click.left = obj.left + this.margins.left;
+ }
+ if ('right' in obj) {
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+ }
+ if ('top' in obj) {
+ this.offset.click.top = obj.top + this.margins.top;
+ }
+ if ('bottom' in obj) {
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+ }
+ },
+
+ _getParentOffset: function() {
+
+
+ //Get the offsetParent and cache its position
+ this.offsetParent = this.helper.offsetParent();
+ var po = this.offsetParent.offset();
+
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+ if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
+ po.left += this.scrollParent.scrollLeft();
+ po.top += this.scrollParent.scrollTop();
+ }
+
+ if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
+ || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
+ po = { top: 0, left: 0 };
+
+ return {
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+ };
+
+ },
+
+ _getRelativeOffset: function() {
+
+ if(this.cssPosition == "relative") {
+ var p = this.currentItem.position();
+ return {
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+ };
+ } else {
+ return { top: 0, left: 0 };
+ }
+
+ },
+
+ _cacheMargins: function() {
+ this.margins = {
+ left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
+ top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
+ };
+ },
+
+ _cacheHelperProportions: function() {
+ this.helperProportions = {
+ width: this.helper.outerWidth(),
+ height: this.helper.outerHeight()
+ };
+ },
+
+ _setContainment: function() {
+
+ var o = this.options;
+ if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
+ if(o.containment == 'document' || o.containment == 'window') this.containment = [
+ 0 - this.offset.relative.left - this.offset.parent.left,
+ 0 - this.offset.relative.top - this.offset.parent.top,
+ $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
+ ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+ ];
+
+ if(!(/^(document|window|parent)$/).test(o.containment)) {
+ var ce = $(o.containment)[0];
+ var co = $(o.containment).offset();
+ var over = ($(ce).css("overflow") != 'hidden');
+
+ this.containment = [
+ co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
+ co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
+ co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
+ co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
+ ];
+ }
+
+ },
+
+ _convertPositionTo: function(d, pos) {
+
+ if(!pos) pos = this.position;
+ var mod = d == "absolute" ? 1 : -1;
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+ return {
+ top: (
+ pos.top // The absolute mouse position
+ + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
+ - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
+ ),
+ left: (
+ pos.left // The absolute mouse position
+ + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
+ - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
+ )
+ };
+
+ },
+
+ _generatePosition: function(event) {
+
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+ // This is another very weird special case that only happens for relative elements:
+ // 1. If the css position is relative
+ // 2. and the scroll parent is the document or similar to the offset parent
+ // we have to refresh the relative offset during the scroll so there are no jumps
+ if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
+ this.offset.relative = this._getRelativeOffset();
+ }
+
+ var pageX = event.pageX;
+ var pageY = event.pageY;
+
+ /*
+ * - Position constraining -
+ * Constrain the position to a mix of grid, containment.
+ */
+
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
+
+ if(this.containment) {
+ if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
+ if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
+ }
+
+ if(o.grid) {
+ var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
+ pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+ var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
+ pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+ }
+
+ }
+
+ return {
+ top: (
+ pageY // The absolute mouse position
+ - this.offset.click.top // Click offset (relative to the element)
+ - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
+ + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
+ ),
+ left: (
+ pageX // The absolute mouse position
+ - this.offset.click.left // Click offset (relative to the element)
+ - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
+ + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
+ )
+ };
+
+ },
+
+ _rearrange: function(event, i, a, hardRefresh) {
+
+ a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
+
+ //Various things done here to improve the performance:
+ // 1. we create a setTimeout, that calls refreshPositions
+ // 2. on the instance, we have a counter variable, that get's higher after every append
+ // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
+ // 4. this lets only the last addition to the timeout stack through
+ this.counter = this.counter ? ++this.counter : 1;
+ var self = this, counter = this.counter;
+
+ window.setTimeout(function() {
+ if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
+ },0);
+
+ },
+
+ _clear: function(event, noPropagation) {
+
+ this.reverting = false;
+ // We delay all events that have to be triggered to after the point where the placeholder has been removed and
+ // everything else normalized again
+ var delayedTriggers = [], self = this;
+
+ // We first have to update the dom position of the actual currentItem
+ // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
+ if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
+ this._noFinalSort = null;
+
+ if(this.helper[0] == this.currentItem[0]) {
+ for(var i in this._storedCSS) {
+ if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
+ }
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+ } else {
+ this.currentItem.show();
+ }
+
+ if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
+ if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
+ if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
+ if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
+ for (var i = this.containers.length - 1; i >= 0; i--){
+ if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
+ }
+ };
+ };
+
+ //Post events to containers
+ for (var i = this.containers.length - 1; i >= 0; i--){
+ if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
+ if(this.containers[i].containerCache.over) {
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
+ this.containers[i].containerCache.over = 0;
+ }
+ }
+
+ //Do what was originally in plugins
+ if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
+ if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
+ if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
+
+ this.dragging = false;
+ if(this.cancelHelperRemoval) {
+ if(!noPropagation) {
+ this._trigger("beforeStop", event, this._uiHash());
+ for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
+ this._trigger("stop", event, this._uiHash());
+ }
+ return false;
+ }
+
+ if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
+
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+ this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+
+ if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
+
+ if(!noPropagation) {
+ for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
+ this._trigger("stop", event, this._uiHash());
+ }
+
+ this.fromOutside = false;
+ return true;
+
+ },
+
+ _trigger: function() {
+ if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
+ this.cancel();
+ }
+ },
+
+ _uiHash: function(inst) {
+ var self = inst || this;
+ return {
+ helper: self.helper,
+ placeholder: self.placeholder || $([]),
+ position: self.position,
+ originalPosition: self.originalPosition,
+ offset: self.positionAbs,
+ item: self.currentItem,
+ sender: inst ? inst.element : null
+ };
+ }
+
+});
+
+$.extend($.ui.sortable, {
+ version: "1.8.16"
+});
+
+})(jQuery);
+/*
+ * jQuery UI Effects 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/
+ */
+;jQuery.effects || (function($, undefined) {
+
+$.effects = {};
+
+
+
+/******************************************************************************/
+/****************************** COLOR ANIMATIONS ******************************/
+/******************************************************************************/
+
+// override the animation for color styles
+$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
+ 'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
+function(i, attr) {
+ $.fx.step[attr] = function(fx) {
+ if (!fx.colorInit) {
+ fx.start = getColor(fx.elem, attr);
+ fx.end = getRGB(fx.end);
+ fx.colorInit = true;
+ }
+
+ fx.elem.style[attr] = 'rgb(' +
+ Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
+ Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
+ Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
+ };
+});
+
+// Color Conversion functions from highlightFade
+// By Blair Mitchelmore
+// http://jquery.offput.ca/highlightFade/
+
+// Parse strings looking for color tuples [255,255,255]
+function getRGB(color) {
+ var result;
+
+ // Check if we're already dealing with an array of colors
+ if ( color && color.constructor == Array && color.length == 3 )
+ return color;
+
+ // Look for rgb(num,num,num)
+ if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
+ return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
+
+ // Look for rgb(num%,num%,num%)
+ if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
+ return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
+
+ // Look for #a0b1c2
+ if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
+ return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
+
+ // Look for #fff
+ if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
+ return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
+
+ // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
+ if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
+ return colors['transparent'];
+
+ // Otherwise, we're most likely dealing with a named color
+ return colors[$.trim(color).toLowerCase()];
+}
+
+function getColor(elem, attr) {
+ var color;
+
+ do {
+ color = $.curCSS(elem, attr);
+
+ // Keep going until we find an element that has color, or we hit the body
+ if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
+ break;
+
+ attr = "backgroundColor";
+ } while ( elem = elem.parentNode );
+
+ return getRGB(color);
+};
+
+// Some named colors to work with
+// From Interface by Stefan Petre
+// http://interface.eyecon.ro/
+
+var colors = {
+ aqua:[0,255,255],
+ azure:[240,255,255],
+ beige:[245,245,220],
+ black:[0,0,0],
+ blue:[0,0,255],
+ brown:[165,42,42],
+ cyan:[0,255,255],
+ darkblue:[0,0,139],
+ darkcyan:[0,139,139],
+ darkgrey:[169,169,169],
+ darkgreen:[0,100,0],
+ darkkhaki:[189,183,107],
+ darkmagenta:[139,0,139],
+ darkolivegreen:[85,107,47],
+ darkorange:[255,140,0],
+ darkorchid:[153,50,204],
+ darkred:[139,0,0],
+ darksalmon:[233,150,122],
+ darkviolet:[148,0,211],
+ fuchsia:[255,0,255],
+ gold:[255,215,0],
+ green:[0,128,0],
+ indigo:[75,0,130],
+ khaki:[240,230,140],
+ lightblue:[173,216,230],
+ lightcyan:[224,255,255],
+ lightgreen:[144,238,144],
+ lightgrey:[211,211,211],
+ lightpink:[255,182,193],
+ lightyellow:[255,255,224],
+ lime:[0,255,0],
+ magenta:[255,0,255],
+ maroon:[128,0,0],
+ navy:[0,0,128],
+ olive:[128,128,0],
+ orange:[255,165,0],
+ pink:[255,192,203],
+ purple:[128,0,128],
+ violet:[128,0,128],
+ red:[255,0,0],
+ silver:[192,192,192],
+ white:[255,255,255],
+ yellow:[255,255,0],
+ transparent: [255,255,255]
+};
+
+
+
+/******************************************************************************/
+/****************************** CLASS ANIMATIONS ******************************/
+/******************************************************************************/
+
+var classAnimationActions = ['add', 'remove', 'toggle'],
+ shorthandStyles = {
+ border: 1,
+ borderBottom: 1,
+ borderColor: 1,
+ borderLeft: 1,
+ borderRight: 1,
+ borderTop: 1,
+ borderWidth: 1,
+ margin: 1,
+ padding: 1
+ };
+
+function getElementStyles() {
+ var style = document.defaultView
+ ? document.defaultView.getComputedStyle(this, null)
+ : this.currentStyle,
+ newStyle = {},
+ key,
+ camelCase;
+
+ // webkit enumerates style porperties
+ if (style && style.length && style[0] && style[style[0]]) {
+ var len = style.length;
+ while (len--) {
+ key = style[len];
+ if (typeof style[key] == 'string') {
+ camelCase = key.replace(/\-(\w)/g, function(all, letter){
+ return letter.toUpperCase();
+ });
+ newStyle[camelCase] = style[key];
+ }
+ }
+ } else {
+ for (key in style) {
+ if (typeof style[key] === 'string') {
+ newStyle[key] = style[key];
+ }
+ }
+ }
+
+ return newStyle;
+}
+
+function filterStyles(styles) {
+ var name, value;
+ for (name in styles) {
+ value = styles[name];
+ if (
+ // ignore null and undefined values
+ value == null ||
+ // ignore functions (when does this occur?)
+ $.isFunction(value) ||
+ // shorthand styles that need to be expanded
+ name in shorthandStyles ||
+ // ignore scrollbars (break in IE)
+ (/scrollbar/).test(name) ||
+
+ // only colors or values that can be converted to numbers
+ (!(/color/i).test(name) && isNaN(parseFloat(value)))
+ ) {
+ delete styles[name];
+ }
+ }
+
+ return styles;
+}
+
+function styleDifference(oldStyle, newStyle) {
+ var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
+ name;
+
+ for (name in newStyle) {
+ if (oldStyle[name] != newStyle[name]) {
+ diff[name] = newStyle[name];
+ }
+ }
+
+ return diff;
+}
+
+$.effects.animateClass = function(value, duration, easing, callback) {
+ if ($.isFunction(easing)) {
+ callback = easing;
+ easing = null;
+ }
+
+ return this.queue(function() {
+ var that = $(this),
+ originalStyleAttr = that.attr('style') || ' ',
+ originalStyle = filterStyles(getElementStyles.call(this)),
+ newStyle,
+ className = that.attr('class');
+
+ $.each(classAnimationActions, function(i, action) {
+ if (value[action]) {
+ that[action + 'Class'](value[action]);
+ }
+ });
+ newStyle = filterStyles(getElementStyles.call(this));
+ that.attr('class', className);
+
+ that.animate(styleDifference(originalStyle, newStyle), {
+ queue: false,
+ duration: duration,
+ easing: easing,
+ complete: function() {
+ $.each(classAnimationActions, function(i, action) {
+ if (value[action]) { that[action + 'Class'](value[action]); }
+ });
+ // work around bug in IE by clearing the cssText before setting it
+ if (typeof that.attr('style') == 'object') {
+ that.attr('style').cssText = '';
+ that.attr('style').cssText = originalStyleAttr;
+ } else {
+ that.attr('style', originalStyleAttr);
+ }
+ if (callback) { callback.apply(this, arguments); }
+ $.dequeue( this );
+ }
+ });
+ });
+};
+
+$.fn.extend({
+ _addClass: $.fn.addClass,
+ addClass: function(classNames, speed, easing, callback) {
+ return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
+ },
+
+ _removeClass: $.fn.removeClass,
+ removeClass: function(classNames,speed,easing,callback) {
+ return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
+ },
+
+ _toggleClass: $.fn.toggleClass,
+ toggleClass: function(classNames, force, speed, easing, callback) {
+ if ( typeof force == "boolean" || force === undefined ) {
+ if ( !speed ) {
+ // without speed parameter;
+ return this._toggleClass(classNames, force);
+ } else {
+ return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
+ }
+ } else {
+ // without switch parameter;
+ return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
+ }
+ },
+
+ switchClass: function(remove,add,speed,easing,callback) {
+ return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
+ }
+});
+
+
+
+/******************************************************************************/
+/*********************************** EFFECTS **********************************/
+/******************************************************************************/
+
+$.extend($.effects, {
+ version: "1.8.16",
+
+ // Saves a set of properties in a data storage
+ save: function(element, set) {
+ for(var i=0; i < set.length; i++) {
+ if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
+ }
+ },
+
+ // Restores a set of previously saved properties from a data storage
+ restore: function(element, set) {
+ for(var i=0; i < set.length; i++) {
+ if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
+ }
+ },
+
+ setMode: function(el, mode) {
+ if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
+ return mode;
+ },
+
+ getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
+ // this should be a little more flexible in the future to handle a string & hash
+ var y, x;
+ switch (origin[0]) {
+ case 'top': y = 0; break;
+ case 'middle': y = 0.5; break;
+ case 'bottom': y = 1; break;
+ default: y = origin[0] / original.height;
+ };
+ switch (origin[1]) {
+ case 'left': x = 0; break;
+ case 'center': x = 0.5; break;
+ case 'right': x = 1; break;
+ default: x = origin[1] / original.width;
+ };
+ return {x: x, y: y};
+ },
+
+ // Wraps the element around a wrapper that copies position properties
+ createWrapper: function(element) {
+
+ // if the element is already wrapped, return it
+ if (element.parent().is('.ui-effects-wrapper')) {
+ return element.parent();
+ }
+
+ // wrap the element
+ var props = {
+ width: element.outerWidth(true),
+ height: element.outerHeight(true),
+ 'float': element.css('float')
+ },
+ wrapper = $('<div></div>')
+ .addClass('ui-effects-wrapper')
+ .css({
+ fontSize: '100%',
+ background: 'transparent',
+ border: 'none',
+ margin: 0,
+ padding: 0
+ }),
+ active = document.activeElement;
+
+ element.wrap(wrapper);
+
+ // Fixes #7595 - Elements lose focus when wrapped.
+ if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+ $( active ).focus();
+ }
+
+ wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
+
+ // transfer positioning properties to the wrapper
+ if (element.css('position') == 'static') {
+ wrapper.css({ position: 'relative' });
+ element.css({ position: 'relative' });
+ } else {
+ $.extend(props, {
+ position: element.css('position'),
+ zIndex: element.css('z-index')
+ });
+ $.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
+ props[pos] = element.css(pos);
+ if (isNaN(parseInt(props[pos], 10))) {
+ props[pos] = 'auto';
+ }
+ });
+ element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
+ }
+
+ return wrapper.css(props).show();
+ },
+
+ removeWrapper: function(element) {
+ var parent,
+ active = document.activeElement;
+
+ if (element.parent().is('.ui-effects-wrapper')) {
+ parent = element.parent().replaceWith(element);
+ // Fixes #7595 - Elements lose focus when wrapped.
+ if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+ $( active ).focus();
+ }
+ return parent;
+ }
+
+ return element;
+ },
+
+ setTransition: function(element, list, factor, value) {
+ value = value || {};
+ $.each(list, function(i, x){
+ unit = element.cssUnit(x);
+ if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
+ });
+ return value;
+ }
+});
+
+
+function _normalizeArguments(effect, options, speed, callback) {
+ // shift params for method overloading
+ if (typeof effect == 'object') {
+ callback = options;
+ speed = null;
+ options = effect;
+ effect = options.effect;
+ }
+ if ($.isFunction(options)) {
+ callback = options;
+ speed = null;
+ options = {};
+ }
+ if (typeof options == 'number' || $.fx.speeds[options]) {
+ callback = speed;
+ speed = options;
+ options = {};
+ }
+ if ($.isFunction(speed)) {
+ callback = speed;
+ speed = null;
+ }
+
+ options = options || {};
+
+ speed = speed || options.duration;
+ speed = $.fx.off ? 0 : typeof speed == 'number'
+ ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
+
+ callback = callback || options.complete;
+
+ return [effect, options, speed, callback];
+}
+
+function standardSpeed( speed ) {
+ // valid standard speeds
+ if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
+ return true;
+ }
+
+ // invalid strings - treat as "normal" speed
+ if ( typeof speed === "string" && !$.effects[ speed ] ) {
+ return true;
+ }
+
+ return false;
+}
+
+$.fn.extend({
+ effect: function(effect, options, speed, callback) {
+ var args = _normalizeArguments.apply(this, arguments),
+ // TODO: make effects take actual parameters instead of a hash
+ args2 = {
+ options: args[1],
+ duration: args[2],
+ callback: args[3]
+ },
+ mode = args2.options.mode,
+ effectMethod = $.effects[effect];
+
+ if ( $.fx.off || !effectMethod ) {
+ // delegate to the original method (e.g., .show()) if possible
+ if ( mode ) {
+ return this[ mode ]( args2.duration, args2.callback );
+ } else {
+ return this.each(function() {
+ if ( args2.callback ) {
+ args2.callback.call( this );
+ }
+ });
+ }
+ }
+
+ return effectMethod.call(this, args2);
+ },
+
+ _show: $.fn.show,
+ show: function(speed) {
+ if ( standardSpeed( speed ) ) {
+ return this._show.apply(this, arguments);
+ } else {
+ var args = _normalizeArguments.apply(this, arguments);
+ args[1].mode = 'show';
+ return this.effect.apply(this, args);
+ }
+ },
+
+ _hide: $.fn.hide,
+ hide: function(speed) {
+ if ( standardSpeed( speed ) ) {
+ return this._hide.apply(this, arguments);
+ } else {
+ var args = _normalizeArguments.apply(this, arguments);
+ args[1].mode = 'hide';
+ return this.effect.apply(this, args);
+ }
+ },
+
+ // jQuery core overloads toggle and creates _toggle
+ __toggle: $.fn.toggle,
+ toggle: function(speed) {
+ if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
+ return this.__toggle.apply(this, arguments);
+ } else {
+ var args = _normalizeArguments.apply(this, arguments);
+ args[1].mode = 'toggle';
+ return this.effect.apply(this, args);
+ }
+ },
+
+ // helper functions
+ cssUnit: function(key) {
+ var style = this.css(key), val = [];
+ $.each( ['em','px','%','pt'], function(i, unit){
+ if(style.indexOf(unit) > 0)
+ val = [parseFloat(style), unit];
+ });
+ return val;
+ }
+});
+
+
+
+/******************************************************************************/
+/*********************************** EASING ***********************************/
+/******************************************************************************/
+
+/*
+ * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
+ *
+ * Uses the built in easing capabilities added In jQuery 1.1
+ * to offer multiple easing options
+ *
+ * TERMS OF USE - jQuery Easing
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright 2008 George McGinley Smith
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
+// t: current time, b: begInnIng value, c: change In value, d: duration
+$.easing.jswing = $.easing.swing;
+
+$.extend($.easing,
+{
+ def: 'easeOutQuad',
+ swing: function (x, t, b, c, d) {
+ //alert($.easing.default);
+ return $.easing[$.easing.def](x, t, b, c, d);
+ },
+ easeInQuad: function (x, t, b, c, d) {
+ return c*(t/=d)*t + b;
+ },
+ easeOutQuad: function (x, t, b, c, d) {
+ return -c *(t/=d)*(t-2) + b;
+ },
+ easeInOutQuad: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t + b;
+ return -c/2 * ((--t)*(t-2) - 1) + b;
+ },
+ easeInCubic: function (x, t, b, c, d) {
+ return c*(t/=d)*t*t + b;
+ },
+ easeOutCubic: function (x, t, b, c, d) {
+ return c*((t=t/d-1)*t*t + 1) + b;
+ },
+ easeInOutCubic: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t + b;
+ return c/2*((t-=2)*t*t + 2) + b;
+ },
+ easeInQuart: function (x, t, b, c, d) {
+ return c*(t/=d)*t*t*t + b;
+ },
+ easeOutQuart: function (x, t, b, c, d) {
+ return -c * ((t=t/d-1)*t*t*t - 1) + b;
+ },
+ easeInOutQuart: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
+ return -c/2 * ((t-=2)*t*t*t - 2) + b;
+ },
+ easeInQuint: function (x, t, b, c, d) {
+ return c*(t/=d)*t*t*t*t + b;
+ },
+ easeOutQuint: function (x, t, b, c, d) {
+ return c*((t=t/d-1)*t*t*t*t + 1) + b;
+ },
+ easeInOutQuint: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
+ return c/2*((t-=2)*t*t*t*t + 2) + b;
+ },
+ easeInSine: function (x, t, b, c, d) {
+ return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
+ },
+ easeOutSine: function (x, t, b, c, d) {
+ return c * Math.sin(t/d * (Math.PI/2)) + b;
+ },
+ easeInOutSine: function (x, t, b, c, d) {
+ return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
+ },
+ easeInExpo: function (x, t, b, c, d) {
+ return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
+ },
+ easeOutExpo: function (x, t, b, c, d) {
+ return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
+ },
+ easeInOutExpo: function (x, t, b, c, d) {
+ if (t==0) return b;
+ if (t==d) return b+c;
+ if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
+ return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
+ },
+ easeInCirc: function (x, t, b, c, d) {
+ return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
+ },
+ easeOutCirc: function (x, t, b, c, d) {
+ return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
+ },
+ easeInOutCirc: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
+ return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
+ },
+ easeInElastic: function (x, t, b, c, d) {
+ var s=1.70158;var p=0;var a=c;
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
+ return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+ },
+ easeOutElastic: function (x, t, b, c, d) {
+ var s=1.70158;var p=0;var a=c;
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
+ return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
+ },
+ easeInOutElastic: function (x, t, b, c, d) {
+ var s=1.70158;var p=0;var a=c;
+ if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
+ if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+ return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
+ },
+ easeInBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ return c*(t/=d)*t*((s+1)*t - s) + b;
+ },
+ easeOutBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
+ },
+ easeInOutBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
+ return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
+ },
+ easeInBounce: function (x, t, b, c, d) {
+ return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
+ },
+ easeOutBounce: function (x, t, b, c, d) {
+ if ((t/=d) < (1/2.75)) {
+ return c*(7.5625*t*t) + b;
+ } else if (t < (2/2.75)) {
+ return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
+ } else if (t < (2.5/2.75)) {
+ return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
+ } else {
+ return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
+ }
+ },
+ easeInOutBounce: function (x, t, b, c, d) {
+ if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
+ return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
+ }
+});
+
+/*
+ *
+ * TERMS OF USE - EASING EQUATIONS
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright 2001 Robert Penner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+})(jQuery);
+/*
+ * jQuery UI Effects Blind 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Blind
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.blind = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+ var direction = o.options.direction || 'vertical'; // Default direction
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+ var ref = (direction == 'vertical') ? 'height' : 'width';
+ var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
+ if(mode == 'show') wrapper.css(ref, 0); // Shift
+
+ // Animation
+ var animation = {};
+ animation[ref] = mode == 'show' ? distance : 0;
+
+ // Animate
+ wrapper.animate(animation, o.duration, o.options.easing, function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(el[0], arguments); // Callback
+ el.dequeue();
+ });
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Bounce 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Bounce
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.bounce = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+ var direction = o.options.direction || 'up'; // Default direction
+ var distance = o.options.distance || 20; // Default distance
+ var times = o.options.times || 5; // Default # of times
+ var speed = o.duration || 250; // Default speed per bounce
+ if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ $.effects.createWrapper(el); // Create Wrapper
+ var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+ var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+ var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
+ if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
+ if (mode == 'hide') distance = distance / (times * 2);
+ if (mode != 'hide') times--;
+
+ // Animate
+ if (mode == 'show') { // Show Bounce
+ var animation = {opacity: 1};
+ animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
+ el.animate(animation, speed / 2, o.options.easing);
+ distance = distance / 2;
+ times--;
+ };
+ for (var i = 0; i < times; i++) { // Bounces
+ var animation1 = {}, animation2 = {};
+ animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+ animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
+ el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
+ distance = (mode == 'hide') ? distance * 2 : distance / 2;
+ };
+ if (mode == 'hide') { // Last Bounce
+ var animation = {opacity: 0};
+ animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+ el.animate(animation, speed / 2, o.options.easing, function(){
+ el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ });
+ } else {
+ var animation1 = {}, animation2 = {};
+ animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+ animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
+ el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ });
+ };
+ el.queue('fx', function() { el.dequeue(); });
+ el.dequeue();
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Clip 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Clip
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.clip = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right','height','width'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+ var direction = o.options.direction || 'vertical'; // Default direction
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+ var animate = el[0].tagName == 'IMG' ? wrapper : el;
+ var ref = {
+ size: (direction == 'vertical') ? 'height' : 'width',
+ position: (direction == 'vertical') ? 'top' : 'left'
+ };
+ var distance = (direction == 'vertical') ? animate.height() : animate.width();
+ if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
+
+ // Animation
+ var animation = {};
+ animation[ref.size] = mode == 'show' ? distance : 0;
+ animation[ref.position] = mode == 'show' ? 0 : distance / 2;
+
+ // Animate
+ animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(el[0], arguments); // Callback
+ el.dequeue();
+ }});
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Drop 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Drop
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.drop = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right','opacity'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+ var direction = o.options.direction || 'left'; // Default Direction
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ $.effects.createWrapper(el); // Create Wrapper
+ var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+ var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+ var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
+ if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
+
+ // Animation
+ var animation = {opacity: mode == 'show' ? 1 : 0};
+ animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
+
+ // Animate
+ el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ el.dequeue();
+ }});
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Explode 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Explode
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.explode = function(o) {
+
+ return this.queue(function() {
+
+ var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
+ var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
+
+ o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
+ var el = $(this).show().css('visibility', 'hidden');
+ var offset = el.offset();
+
+ //Substract the margins - not fixing the problem yet.
+ offset.top -= parseInt(el.css("marginTop"),10) || 0;
+ offset.left -= parseInt(el.css("marginLeft"),10) || 0;
+
+ var width = el.outerWidth(true);
+ var height = el.outerHeight(true);
+
+ for(var i=0;i<rows;i++) { // =
+ for(var j=0;j<cells;j++) { // ||
+ el
+ .clone()
+ .appendTo('body')
+ .wrap('<div></div>')
+ .css({
+ position: 'absolute',
+ visibility: 'visible',
+ left: -j*(width/cells),
+ top: -i*(height/rows)
+ })
+ .parent()
+ .addClass('ui-effects-explode')
+ .css({
+ position: 'absolute',
+ overflow: 'hidden',
+ width: width/cells,
+ height: height/rows,
+ left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
+ top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
+ opacity: o.options.mode == 'show' ? 0 : 1
+ }).animate({
+ left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
+ top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
+ opacity: o.options.mode == 'show' ? 1 : 0
+ }, o.duration || 500);
+ }
+ }
+
+ // Set a timeout, to call the callback approx. when the other animations have finished
+ setTimeout(function() {
+
+ o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
+ if(o.callback) o.callback.apply(el[0]); // Callback
+ el.dequeue();
+
+ $('div.ui-effects-explode').remove();
+
+ }, o.duration || 500);
+
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Fade 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Fade
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.fade = function(o) {
+ return this.queue(function() {
+ var elem = $(this),
+ mode = $.effects.setMode(elem, o.options.mode || 'hide');
+
+ elem.animate({ opacity: mode }, {
+ queue: false,
+ duration: o.duration,
+ easing: o.options.easing,
+ complete: function() {
+ (o.callback && o.callback.apply(this, arguments));
+ elem.dequeue();
+ }
+ });
+ });
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Fold 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Fold
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.fold = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+ var size = o.options.size || 15; // Default fold size
+ var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
+ var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+ var widthFirst = ((mode == 'show') != horizFirst);
+ var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
+ var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
+ var percent = /([0-9]+)%/.exec(size);
+ if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
+ if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
+
+ // Animation
+ var animation1 = {}, animation2 = {};
+ animation1[ref[0]] = mode == 'show' ? distance[0] : size;
+ animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
+
+ // Animate
+ wrapper.animate(animation1, duration, o.options.easing)
+ .animate(animation2, duration, o.options.easing, function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(el[0], arguments); // Callback
+ el.dequeue();
+ });
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Highlight 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Highlight
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.highlight = function(o) {
+ return this.queue(function() {
+ var elem = $(this),
+ props = ['backgroundImage', 'backgroundColor', 'opacity'],
+ mode = $.effects.setMode(elem, o.options.mode || 'show'),
+ animation = {
+ backgroundColor: elem.css('backgroundColor')
+ };
+
+ if (mode == 'hide') {
+ animation.opacity = 0;
+ }
+
+ $.effects.save(elem, props);
+ elem
+ .show()
+ .css({
+ backgroundImage: 'none',
+ backgroundColor: o.options.color || '#ffff99'
+ })
+ .animate(animation, {
+ queue: false,
+ duration: o.duration,
+ easing: o.options.easing,
+ complete: function() {
+ (mode == 'hide' && elem.hide());
+ $.effects.restore(elem, props);
+ (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
+ (o.callback && o.callback.apply(this, arguments));
+ elem.dequeue();
+ }
+ });
+ });
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Pulsate 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Pulsate
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.pulsate = function(o) {
+ return this.queue(function() {
+ var elem = $(this),
+ mode = $.effects.setMode(elem, o.options.mode || 'show');
+ times = ((o.options.times || 5) * 2) - 1;
+ duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
+ isVisible = elem.is(':visible'),
+ animateTo = 0;
+
+ if (!isVisible) {
+ elem.css('opacity', 0).show();
+ animateTo = 1;
+ }
+
+ if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
+ times--;
+ }
+
+ for (var i = 0; i < times; i++) {
+ elem.animate({ opacity: animateTo }, duration, o.options.easing);
+ animateTo = (animateTo + 1) % 2;
+ }
+
+ elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
+ if (animateTo == 0) {
+ elem.hide();
+ }
+ (o.callback && o.callback.apply(this, arguments));
+ });
+
+ elem
+ .queue('fx', function() { elem.dequeue(); })
+ .dequeue();
+ });
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Scale 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Scale
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.puff = function(o) {
+ return this.queue(function() {
+ var elem = $(this),
+ mode = $.effects.setMode(elem, o.options.mode || 'hide'),
+ percent = parseInt(o.options.percent, 10) || 150,
+ factor = percent / 100,
+ original = { height: elem.height(), width: elem.width() };
+
+ $.extend(o.options, {
+ fade: true,
+ mode: mode,
+ percent: mode == 'hide' ? percent : 100,
+ from: mode == 'hide'
+ ? original
+ : {
+ height: original.height * factor,
+ width: original.width * factor
+ }
+ });
+
+ elem.effect('scale', o.options, o.duration, o.callback);
+ elem.dequeue();
+ });
+};
+
+$.effects.scale = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this);
+
+ // Set options
+ var options = $.extend(true, {}, o.options);
+ var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+ var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
+ var direction = o.options.direction || 'both'; // Set default axis
+ var origin = o.options.origin; // The origin of the scaling
+ if (mode != 'effect') { // Set default origin and restore for show/hide
+ options.origin = origin || ['middle','center'];
+ options.restore = true;
+ }
+ var original = {height: el.height(), width: el.width()}; // Save original
+ el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
+
+ // Adjust
+ var factor = { // Set scaling factor
+ y: direction != 'horizontal' ? (percent / 100) : 1,
+ x: direction != 'vertical' ? (percent / 100) : 1
+ };
+ el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
+
+ if (o.options.fade) { // Fade option to support puff
+ if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
+ if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
+ };
+
+ // Animation
+ options.from = el.from; options.to = el.to; options.mode = mode;
+
+ // Animate
+ el.effect('size', options, o.duration, o.callback);
+ el.dequeue();
+ });
+
+};
+
+$.effects.size = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity'];
+ var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore
+ var props2 = ['width','height','overflow']; // Copy for children
+ var cProps = ['fontSize'];
+ var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
+ var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+ var restore = o.options.restore || false; // Default restore
+ var scale = o.options.scale || 'both'; // Default scale mode
+ var origin = o.options.origin; // The origin of the sizing
+ var original = {height: el.height(), width: el.width()}; // Save original
+ el.from = o.options.from || original; // Default from state
+ el.to = o.options.to || original; // Default to state
+ // Adjust
+ if (origin) { // Calculate baseline shifts
+ var baseline = $.effects.getBaseline(origin, original);
+ el.from.top = (original.height - el.from.height) * baseline.y;
+ el.from.left = (original.width - el.from.width) * baseline.x;
+ el.to.top = (original.height - el.to.height) * baseline.y;
+ el.to.left = (original.width - el.to.width) * baseline.x;
+ };
+ var factor = { // Set scaling factor
+ from: {y: el.from.height / original.height, x: el.from.width / original.width},
+ to: {y: el.to.height / original.height, x: el.to.width / original.width}
+ };
+ if (scale == 'box' || scale == 'both') { // Scale the css box
+ if (factor.from.y != factor.to.y) { // Vertical props scaling
+ props = props.concat(vProps);
+ el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
+ el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
+ };
+ if (factor.from.x != factor.to.x) { // Horizontal props scaling
+ props = props.concat(hProps);
+ el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
+ el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
+ };
+ };
+ if (scale == 'content' || scale == 'both') { // Scale the content
+ if (factor.from.y != factor.to.y) { // Vertical props scaling
+ props = props.concat(cProps);
+ el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
+ el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
+ };
+ };
+ $.effects.save(el, restore ? props : props1); el.show(); // Save & Show
+ $.effects.createWrapper(el); // Create Wrapper
+ el.css('overflow','hidden').css(el.from); // Shift
+
+ // Animate
+ if (scale == 'content' || scale == 'both') { // Scale the children
+ vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
+ hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
+ props2 = props.concat(vProps).concat(hProps); // Concat
+ el.find("*[width]").each(function(){
+ child = $(this);
+ if (restore) $.effects.save(child, props2);
+ var c_original = {height: child.height(), width: child.width()}; // Save original
+ child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
+ child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
+ if (factor.from.y != factor.to.y) { // Vertical props scaling
+ child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
+ child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
+ };
+ if (factor.from.x != factor.to.x) { // Horizontal props scaling
+ child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
+ child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
+ };
+ child.css(child.from); // Shift children
+ child.animate(child.to, o.duration, o.options.easing, function(){
+ if (restore) $.effects.restore(child, props2); // Restore children
+ }); // Animate children
+ });
+ };
+
+ // Animate
+ el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+ if (el.to.opacity === 0) {
+ el.css('opacity', el.from.opacity);
+ }
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ el.dequeue();
+ }});
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Shake 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Shake
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.shake = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+ var direction = o.options.direction || 'left'; // Default direction
+ var distance = o.options.distance || 20; // Default distance
+ var times = o.options.times || 3; // Default # of times
+ var speed = o.duration || o.options.duration || 140; // Default speed per shake
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ $.effects.createWrapper(el); // Create Wrapper
+ var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+ var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+
+ // Animation
+ var animation = {}, animation1 = {}, animation2 = {};
+ animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+ animation1[ref] = (motion == 'pos' ? '+=' : '-=') + distance * 2;
+ animation2[ref] = (motion == 'pos' ? '-=' : '+=') + distance * 2;
+
+ // Animate
+ el.animate(animation, speed, o.options.easing);
+ for (var i = 1; i < times; i++) { // Shakes
+ el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
+ };
+ el.animate(animation1, speed, o.options.easing).
+ animate(animation, speed / 2, o.options.easing, function(){ // Last shake
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ });
+ el.queue('fx', function() { el.dequeue(); });
+ el.dequeue();
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Slide 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Slide
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.slide = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
+ var direction = o.options.direction || 'left'; // Default Direction
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+ var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+ var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+ var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
+ if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
+
+ // Animation
+ var animation = {};
+ animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
+
+ // Animate
+ el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ el.dequeue();
+ }});
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Transfer 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Transfer
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.transfer = function(o) {
+ return this.queue(function() {
+ var elem = $(this),
+ target = $(o.options.to),
+ endPosition = target.offset(),
+ animation = {
+ top: endPosition.top,
+ left: endPosition.left,
+ height: target.innerHeight(),
+ width: target.innerWidth()
+ },
+ startPosition = elem.offset(),
+ transfer = $('<div class="ui-effects-transfer"></div>')
+ .appendTo(document.body)
+ .addClass(o.options.className)
+ .css({
+ top: startPosition.top,
+ left: startPosition.left,
+ height: elem.innerHeight(),
+ width: elem.innerWidth(),
+ position: 'absolute'
+ })
+ .animate(animation, o.duration, o.options.easing, function() {
+ transfer.remove();
+ (o.callback && o.callback.apply(elem[0], arguments));
+ elem.dequeue();
+ });
+ });
+};
+
+})(jQuery);
+/*
+ * jQuery UI Accordion 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Accordion
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget( "ui.accordion", {
+ options: {
+ active: 0,
+ animated: "slide",
+ autoHeight: true,
+ clearStyle: false,
+ collapsible: false,
+ event: "click",
+ fillSpace: false,
+ header: "> li > :first-child,> :not(li):even",
+ icons: {
+ header: "ui-icon-triangle-1-e",
+ headerSelected: "ui-icon-triangle-1-s"
+ },
+ navigation: false,
+ navigationFilter: function() {
+ return this.href.toLowerCase() === location.href.toLowerCase();
+ }
+ },
+
+ _create: function() {
+ var self = this,
+ options = self.options;
+
+ self.running = 0;
+
+ self.element
+ .addClass( "ui-accordion ui-widget ui-helper-reset" )
+ // in lack of child-selectors in CSS
+ // we need to mark top-LIs in a UL-accordion for some IE-fix
+ .children( "li" )
+ .addClass( "ui-accordion-li-fix" );
+
+ self.headers = self.element.find( options.header )
+ .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
+ .bind( "mouseenter.accordion", function() {
+ if ( options.disabled ) {
+ return;
+ }
+ $( this ).addClass( "ui-state-hover" );
+ })
+ .bind( "mouseleave.accordion", function() {
+ if ( options.disabled ) {
+ return;
+ }
+ $( this ).removeClass( "ui-state-hover" );
+ })
+ .bind( "focus.accordion", function() {
+ if ( options.disabled ) {
+ return;
+ }
+ $( this ).addClass( "ui-state-focus" );
+ })
+ .bind( "blur.accordion", function() {
+ if ( options.disabled ) {
+ return;
+ }
+ $( this ).removeClass( "ui-state-focus" );
+ });
+
+ self.headers.next()
+ .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
+
+ if ( options.navigation ) {
+ var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
+ if ( current.length ) {
+ var header = current.closest( ".ui-accordion-header" );
+ if ( header.length ) {
+ // anchor within header
+ self.active = header;
+ } else {
+ // anchor within content
+ self.active = current.closest( ".ui-accordion-content" ).prev();
+ }
+ }
+ }
+
+ self.active = self._findActive( self.active || options.active )
+ .addClass( "ui-state-default ui-state-active" )
+ .toggleClass( "ui-corner-all" )
+ .toggleClass( "ui-corner-top" );
+ self.active.next().addClass( "ui-accordion-content-active" );
+
+ self._createIcons();
+ self.resize();
+
+ // ARIA
+ self.element.attr( "role", "tablist" );
+
+ self.headers
+ .attr( "role", "tab" )
+ .bind( "keydown.accordion", function( event ) {
+ return self._keydown( event );
+ })
+ .next()
+ .attr( "role", "tabpanel" );
+
+ self.headers
+ .not( self.active || "" )
+ .attr({
+ "aria-expanded": "false",
+ "aria-selected": "false",
+ tabIndex: -1
+ })
+ .next()
+ .hide();
+
+ // make sure at least one header is in the tab order
+ if ( !self.active.length ) {
+ self.headers.eq( 0 ).attr( "tabIndex", 0 );
+ } else {
+ self.active
+ .attr({
+ "aria-expanded": "true",
+ "aria-selected": "true",
+ tabIndex: 0
+ });
+ }
+
+ // only need links in tab order for Safari
+ if ( !$.browser.safari ) {
+ self.headers.find( "a" ).attr( "tabIndex", -1 );
+ }
+
+ if ( options.event ) {
+ self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
+ self._clickHandler.call( self, event, this );
+ event.preventDefault();
+ });
+ }
+ },
+
+ _createIcons: function() {
+ var options = this.options;
+ if ( options.icons ) {
+ $( "<span></span>" )
+ .addClass( "ui-icon " + options.icons.header )
+ .prependTo( this.headers );
+ this.active.children( ".ui-icon" )
+ .toggleClass(options.icons.header)
+ .toggleClass(options.icons.headerSelected);
+ this.element.addClass( "ui-accordion-icons" );
+ }
+ },
+
+ _destroyIcons: function() {
+ this.headers.children( ".ui-icon" ).remove();
+ this.element.removeClass( "ui-accordion-icons" );
+ },
+
+ destroy: function() {
+ var options = this.options;
+
+ this.element
+ .removeClass( "ui-accordion ui-widget ui-helper-reset" )
+ .removeAttr( "role" );
+
+ this.headers
+ .unbind( ".accordion" )
+ .removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
+ .removeAttr( "role" )
+ .removeAttr( "aria-expanded" )
+ .removeAttr( "aria-selected" )
+ .removeAttr( "tabIndex" );
+
+ this.headers.find( "a" ).removeAttr( "tabIndex" );
+ this._destroyIcons();
+ var contents = this.headers.next()
+ .css( "display", "" )
+ .removeAttr( "role" )
+ .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
+ if ( options.autoHeight || options.fillHeight ) {
+ contents.css( "height", "" );
+ }
+
+ return $.Widget.prototype.destroy.call( this );
+ },
+
+ _setOption: function( key, value ) {
+ $.Widget.prototype._setOption.apply( this, arguments );
+
+ if ( key == "active" ) {
+ this.activate( value );
+ }
+ if ( key == "icons" ) {
+ this._destroyIcons();
+ if ( value ) {
+ this._createIcons();
+ }
+ }
+ // #5332 - opacity doesn't cascade to positioned elements in IE
+ // so we need to add the disabled class to the headers and panels
+ if ( key == "disabled" ) {
+ this.headers.add(this.headers.next())
+ [ value ? "addClass" : "removeClass" ](
+ "ui-accordion-disabled ui-state-disabled" );
+ }
+ },
+
+ _keydown: function( event ) {
+ if ( this.options.disabled || event.altKey || event.ctrlKey ) {
+ return;
+ }
+
+ var keyCode = $.ui.keyCode,
+ length = this.headers.length,
+ currentIndex = this.headers.index( event.target ),
+ toFocus = false;
+
+ switch ( event.keyCode ) {
+ case keyCode.RIGHT:
+ case keyCode.DOWN:
+ toFocus = this.headers[ ( currentIndex + 1 ) % length ];
+ break;
+ case keyCode.LEFT:
+ case keyCode.UP:
+ toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
+ break;
+ case keyCode.SPACE:
+ case keyCode.ENTER:
+ this._clickHandler( { target: event.target }, event.target );
+ event.preventDefault();
+ }
+
+ if ( toFocus ) {
+ $( event.target ).attr( "tabIndex", -1 );
+ $( toFocus ).attr( "tabIndex", 0 );
+ toFocus.focus();
+ return false;
+ }
+
+ return true;
+ },
+
+ resize: function() {
+ var options = this.options,
+ maxHeight;
+
+ if ( options.fillSpace ) {
+ if ( $.browser.msie ) {
+ var defOverflow = this.element.parent().css( "overflow" );
+ this.element.parent().css( "overflow", "hidden");
+ }
+ maxHeight = this.element.parent().height();
+ if ($.browser.msie) {
+ this.element.parent().css( "overflow", defOverflow );
+ }
+
+ this.headers.each(function() {
+ maxHeight -= $( this ).outerHeight( true );
+ });
+
+ this.headers.next()
+ .each(function() {
+ $( this ).height( Math.max( 0, maxHeight -
+ $( this ).innerHeight() + $( this ).height() ) );
+ })
+ .css( "overflow", "auto" );
+ } else if ( options.autoHeight ) {
+ maxHeight = 0;
+ this.headers.next()
+ .each(function() {
+ maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
+ })
+ .height( maxHeight );
+ }
+
+ return this;
+ },
+
+ activate: function( index ) {
+ // TODO this gets called on init, changing the option without an explicit call for that
+ this.options.active = index;
+ // call clickHandler with custom event
+ var active = this._findActive( index )[ 0 ];
+ this._clickHandler( { target: active }, active );
+
+ return this;
+ },
+
+ _findActive: function( selector ) {
+ return selector
+ ? typeof selector === "number"
+ ? this.headers.filter( ":eq(" + selector + ")" )
+ : this.headers.not( this.headers.not( selector ) )
+ : selector === false
+ ? $( [] )
+ : this.headers.filter( ":eq(0)" );
+ },
+
+ // TODO isn't event.target enough? why the separate target argument?
+ _clickHandler: function( event, target ) {
+ var options = this.options;
+ if ( options.disabled ) {
+ return;
+ }
+
+ // called only when using activate(false) to close all parts programmatically
+ if ( !event.target ) {
+ if ( !options.collapsible ) {
+ return;
+ }
+ this.active
+ .removeClass( "ui-state-active ui-corner-top" )
+ .addClass( "ui-state-default ui-corner-all" )
+ .children( ".ui-icon" )
+ .removeClass( options.icons.headerSelected )
+ .addClass( options.icons.header );
+ this.active.next().addClass( "ui-accordion-content-active" );
+ var toHide = this.active.next(),
+ data = {
+ options: options,
+ newHeader: $( [] ),
+ oldHeader: options.active,
+ newContent: $( [] ),
+ oldContent: toHide
+ },
+ toShow = ( this.active = $( [] ) );
+ this._toggle( toShow, toHide, data );
+ return;
+ }
+
+ // get the click target
+ var clicked = $( event.currentTarget || target ),
+ clickedIsActive = clicked[0] === this.active[0];
+
+ // TODO the option is changed, is that correct?
+ // TODO if it is correct, shouldn't that happen after determining that the click is valid?
+ options.active = options.collapsible && clickedIsActive ?
+ false :
+ this.headers.index( clicked );
+
+ // if animations are still active, or the active header is the target, ignore click
+ if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
+ return;
+ }
+
+ // find elements to show and hide
+ var active = this.active,
+ toShow = clicked.next(),
+ toHide = this.active.next(),
+ data = {
+ options: options,
+ newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
+ oldHeader: this.active,
+ newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
+ oldContent: toHide
+ },
+ down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
+
+ // when the call to ._toggle() comes after the class changes
+ // it causes a very odd bug in IE 8 (see #6720)
+ this.active = clickedIsActive ? $([]) : clicked;
+ this._toggle( toShow, toHide, data, clickedIsActive, down );
+
+ // switch classes
+ active
+ .removeClass( "ui-state-active ui-corner-top" )
+ .addClass( "ui-state-default ui-corner-all" )
+ .children( ".ui-icon" )
+ .removeClass( options.icons.headerSelected )
+ .addClass( options.icons.header );
+ if ( !clickedIsActive ) {
+ clicked
+ .removeClass( "ui-state-default ui-corner-all" )
+ .addClass( "ui-state-active ui-corner-top" )
+ .children( ".ui-icon" )
+ .removeClass( options.icons.header )
+ .addClass( options.icons.headerSelected );
+ clicked
+ .next()
+ .addClass( "ui-accordion-content-active" );
+ }
+
+ return;
+ },
+
+ _toggle: function( toShow, toHide, data, clickedIsActive, down ) {
+ var self = this,
+ options = self.options;
+
+ self.toShow = toShow;
+ self.toHide = toHide;
+ self.data = data;
+
+ var complete = function() {
+ if ( !self ) {
+ return;
+ }
+ return self._completed.apply( self, arguments );
+ };
+
+ // trigger changestart event
+ self._trigger( "changestart", null, self.data );
+
+ // count elements to animate
+ self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
+
+ if ( options.animated ) {
+ var animOptions = {};
+
+ if ( options.collapsible && clickedIsActive ) {
+ animOptions = {
+ toShow: $( [] ),
+ toHide: toHide,
+ complete: complete,
+ down: down,
+ autoHeight: options.autoHeight || options.fillSpace
+ };
+ } else {
+ animOptions = {
+ toShow: toShow,
+ toHide: toHide,
+ complete: complete,
+ down: down,
+ autoHeight: options.autoHeight || options.fillSpace
+ };
+ }
+
+ if ( !options.proxied ) {
+ options.proxied = options.animated;
+ }
+
+ if ( !options.proxiedDuration ) {
+ options.proxiedDuration = options.duration;
+ }
+
+ options.animated = $.isFunction( options.proxied ) ?
+ options.proxied( animOptions ) :
+ options.proxied;
+
+ options.duration = $.isFunction( options.proxiedDuration ) ?
+ options.proxiedDuration( animOptions ) :
+ options.proxiedDuration;
+
+ var animations = $.ui.accordion.animations,
+ duration = options.duration,
+ easing = options.animated;
+
+ if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
+ easing = "slide";
+ }
+ if ( !animations[ easing ] ) {
+ animations[ easing ] = function( options ) {
+ this.slide( options, {
+ easing: easing,
+ duration: duration || 700
+ });
+ };
+ }
+
+ animations[ easing ]( animOptions );
+ } else {
+ if ( options.collapsible && clickedIsActive ) {
+ toShow.toggle();
+ } else {
+ toHide.hide();
+ toShow.show();
+ }
+
+ complete( true );
+ }
+
+ // TODO assert that the blur and focus triggers are really necessary, remove otherwise
+ toHide.prev()
+ .attr({
+ "aria-expanded": "false",
+ "aria-selected": "false",
+ tabIndex: -1
+ })
+ .blur();
+ toShow.prev()
+ .attr({
+ "aria-expanded": "true",
+ "aria-selected": "true",
+ tabIndex: 0
+ })
+ .focus();
+ },
+
+ _completed: function( cancel ) {
+ this.running = cancel ? 0 : --this.running;
+ if ( this.running ) {
+ return;
+ }
+
+ if ( this.options.clearStyle ) {
+ this.toShow.add( this.toHide ).css({
+ height: "",
+ overflow: ""
+ });
+ }
+
+ // other classes are removed before the animation; this one needs to stay until completed
+ this.toHide.removeClass( "ui-accordion-content-active" );
+ // Work around for rendering bug in IE (#5421)
+ if ( this.toHide.length ) {
+ this.toHide.parent()[0].className = this.toHide.parent()[0].className;
+ }
+
+ this._trigger( "change", null, this.data );
+ }
+});
+
+$.extend( $.ui.accordion, {
+ version: "1.8.16",
+ animations: {
+ slide: function( options, additions ) {
+ options = $.extend({
+ easing: "swing",
+ duration: 300
+ }, options, additions );
+ if ( !options.toHide.size() ) {
+ options.toShow.animate({
+ height: "show",
+ paddingTop: "show",
+ paddingBottom: "show"
+ }, options );
+ return;
+ }
+ if ( !options.toShow.size() ) {
+ options.toHide.animate({
+ height: "hide",
+ paddingTop: "hide",
+ paddingBottom: "hide"
+ }, options );
+ return;
+ }
+ var overflow = options.toShow.css( "overflow" ),
+ percentDone = 0,
+ showProps = {},
+ hideProps = {},
+ fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
+ originalWidth;
+ // fix width before calculating height of hidden element
+ var s = options.toShow;
+ originalWidth = s[0].style.width;
+ s.width( parseInt( s.parent().width(), 10 )
+ - parseInt( s.css( "paddingLeft" ), 10 )
+ - parseInt( s.css( "paddingRight" ), 10 )
+ - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 )
+ - ( parseInt( s.css( "borderRightWidth" ), 10) || 0 ) );
+
+ $.each( fxAttrs, function( i, prop ) {
+ hideProps[ prop ] = "hide";
+
+ var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
+ showProps[ prop ] = {
+ value: parts[ 1 ],
+ unit: parts[ 2 ] || "px"
+ };
+ });
+ options.toShow.css({ height: 0, overflow: "hidden" }).show();
+ options.toHide
+ .filter( ":hidden" )
+ .each( options.complete )
+ .end()
+ .filter( ":visible" )
+ .animate( hideProps, {
+ step: function( now, settings ) {
+ // only calculate the percent when animating height
+ // IE gets very inconsistent results when animating elements
+ // with small values, which is common for padding
+ if ( settings.prop == "height" ) {
+ percentDone = ( settings.end - settings.start === 0 ) ? 0 :
+ ( settings.now - settings.start ) / ( settings.end - settings.start );
+ }
+
+ options.toShow[ 0 ].style[ settings.prop ] =
+ ( percentDone * showProps[ settings.prop ].value )
+ + showProps[ settings.prop ].unit;
+ },
+ duration: options.duration,
+ easing: options.easing,
+ complete: function() {
+ if ( !options.autoHeight ) {
+ options.toShow.css( "height", "" );
+ }
+ options.toShow.css({
+ width: originalWidth,
+ overflow: overflow
+ });
+ options.complete();
+ }
+ });
+ },
+ bounceslide: function( options ) {
+ this.slide( options, {
+ easing: options.down ? "easeOutBounce" : "swing",
+ duration: options.down ? 1000 : 200
+ });
+ }
+ }
+});
+
+})( jQuery );
+/*
+ * jQuery UI Autocomplete 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ * jquery.ui.position.js
+ */
+(function( $, undefined ) {
+
+// used to prevent race conditions with remote data sources
+var requestIndex = 0;
+
+$.widget( "ui.autocomplete", {
+ options: {
+ appendTo: "body",
+ autoFocus: false,
+ delay: 300,
+ minLength: 1,
+ position: {
+ my: "left top",
+ at: "left bottom",
+ collision: "none"
+ },
+ source: null
+ },
+
+ pending: 0,
+
+ _create: function() {
+ var self = this,
+ doc = this.element[ 0 ].ownerDocument,
+ suppressKeyPress;
+
+ this.element
+ .addClass( "ui-autocomplete-input" )
+ .attr( "autocomplete", "off" )
+ // TODO verify these actually work as intended
+ .attr({
+ role: "textbox",
+ "aria-autocomplete": "list",
+ "aria-haspopup": "true"
+ })
+ .bind( "keydown.autocomplete", function( event ) {
+ if ( self.options.disabled || self.element.propAttr( "readOnly" ) ) {
+ return;
+ }
+
+ suppressKeyPress = false;
+ var keyCode = $.ui.keyCode;
+ switch( event.keyCode ) {
+ case keyCode.PAGE_UP:
+ self._move( "previousPage", event );
+ break;
+ case keyCode.PAGE_DOWN:
+ self._move( "nextPage", event );
+ break;
+ case keyCode.UP:
+ self._move( "previous", event );
+ // prevent moving cursor to beginning of text field in some browsers
+ event.preventDefault();
+ break;
+ case keyCode.DOWN:
+ self._move( "next", event );
+ // prevent moving cursor to end of text field in some browsers
+ event.preventDefault();
+ break;
+ case keyCode.ENTER:
+ case keyCode.NUMPAD_ENTER:
+ // when menu is open and has focus
+ if ( self.menu.active ) {
+ // #6055 - Opera still allows the keypress to occur
+ // which causes forms to submit
+ suppressKeyPress = true;
+ event.preventDefault();
+ }
+ //passthrough - ENTER and TAB both select the current element
+ case keyCode.TAB:
+ if ( !self.menu.active ) {
+ return;
+ }
+ self.menu.select( event );
+ break;
+ case keyCode.ESCAPE:
+ self.element.val( self.term );
+ self.close( event );
+ break;
+ default:
+ // keypress is triggered before the input value is changed
+ clearTimeout( self.searching );
+ self.searching = setTimeout(function() {
+ // only search if the value has changed
+ if ( self.term != self.element.val() ) {
+ self.selectedItem = null;
+ self.search( null, event );
+ }
+ }, self.options.delay );
+ break;
+ }
+ })
+ .bind( "keypress.autocomplete", function( event ) {
+ if ( suppressKeyPress ) {
+ suppressKeyPress = false;
+ event.preventDefault();
+ }
+ })
+ .bind( "focus.autocomplete", function() {
+ if ( self.options.disabled ) {
+ return;
+ }
+
+ self.selectedItem = null;
+ self.previous = self.element.val();
+ })
+ .bind( "blur.autocomplete", function( event ) {
+ if ( self.options.disabled ) {
+ return;
+ }
+
+ clearTimeout( self.searching );
+ // clicks on the menu (or a button to trigger a search) will cause a blur event
+ self.closing = setTimeout(function() {
+ self.close( event );
+ self._change( event );
+ }, 150 );
+ });
+ this._initSource();
+ this.response = function() {
+ return self._response.apply( self, arguments );
+ };
+ this.menu = $( "<ul></ul>" )
+ .addClass( "ui-autocomplete" )
+ .appendTo( $( this.options.appendTo || "body", doc )[0] )
+ // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
+ .mousedown(function( event ) {
+ // clicking on the scrollbar causes focus to shift to the body
+ // but we can't detect a mouseup or a click immediately afterward
+ // so we have to track the next mousedown and close the menu if
+ // the user clicks somewhere outside of the autocomplete
+ var menuElement = self.menu.element[ 0 ];
+ if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
+ setTimeout(function() {
+ $( document ).one( 'mousedown', function( event ) {
+ if ( event.target !== self.element[ 0 ] &&
+ event.target !== menuElement &&
+ !$.ui.contains( menuElement, event.target ) ) {
+ self.close();
+ }
+ });
+ }, 1 );
+ }
+
+ // use another timeout to make sure the blur-event-handler on the input was already triggered
+ setTimeout(function() {
+ clearTimeout( self.closing );
+ }, 13);
+ })
+ .menu({
+ focus: function( event, ui ) {
+ var item = ui.item.data( "item.autocomplete" );
+ if ( false !== self._trigger( "focus", event, { item: item } ) ) {
+ // use value to match what will end up in the input, if it was a key event
+ if ( /^key/.test(event.originalEvent.type) ) {
+ self.element.val( item.value );
+ }
+ }
+ },
+ selected: function( event, ui ) {
+ var item = ui.item.data( "item.autocomplete" ),
+ previous = self.previous;
+
+ // only trigger when focus was lost (click on menu)
+ if ( self.element[0] !== doc.activeElement ) {
+ self.element.focus();
+ self.previous = previous;
+ // #6109 - IE triggers two focus events and the second
+ // is asynchronous, so we need to reset the previous
+ // term synchronously and asynchronously :-(
+ setTimeout(function() {
+ self.previous = previous;
+ self.selectedItem = item;
+ }, 1);
+ }
+
+ if ( false !== self._trigger( "select", event, { item: item } ) ) {
+ self.element.val( item.value );
+ }
+ // reset the term after the select event
+ // this allows custom select handling to work properly
+ self.term = self.element.val();
+
+ self.close( event );
+ self.selectedItem = item;
+ },
+ blur: function( event, ui ) {
+ // don't set the value of the text field if it's already correct
+ // this prevents moving the cursor unnecessarily
+ if ( self.menu.element.is(":visible") &&
+ ( self.element.val() !== self.term ) ) {
+ self.element.val( self.term );
+ }
+ }
+ })
+ .zIndex( this.element.zIndex() + 1 )
+ // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
+ .css({ top: 0, left: 0 })
+ .hide()
+ .data( "menu" );
+ if ( $.fn.bgiframe ) {
+ this.menu.element.bgiframe();
+ }
+ },
+
+ destroy: function() {
+ this.element
+ .removeClass( "ui-autocomplete-input" )
+ .removeAttr( "autocomplete" )
+ .removeAttr( "role" )
+ .removeAttr( "aria-autocomplete" )
+ .removeAttr( "aria-haspopup" );
+ this.menu.element.remove();
+ $.Widget.prototype.destroy.call( this );
+ },
+
+ _setOption: function( key, value ) {
+ $.Widget.prototype._setOption.apply( this, arguments );
+ if ( key === "source" ) {
+ this._initSource();
+ }
+ if ( key === "appendTo" ) {
+ this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
+ }
+ if ( key === "disabled" && value && this.xhr ) {
+ this.xhr.abort();
+ }
+ },
+
+ _initSource: function() {
+ var self = this,
+ array,
+ url;
+ if ( $.isArray(this.options.source) ) {
+ array = this.options.source;
+ this.source = function( request, response ) {
+ response( $.ui.autocomplete.filter(array, request.term) );
+ };
+ } else if ( typeof this.options.source === "string" ) {
+ url = this.options.source;
+ this.source = function( request, response ) {
+ if ( self.xhr ) {
+ self.xhr.abort();
+ }
+ self.xhr = $.ajax({
+ url: url,
+ data: request,
+ dataType: "json",
+ autocompleteRequest: ++requestIndex,
+ success: function( data, status ) {
+ if ( this.autocompleteRequest === requestIndex ) {
+ response( data );
+ }
+ },
+ error: function() {
+ if ( this.autocompleteRequest === requestIndex ) {
+ response( [] );
+ }
+ }
+ });
+ };
+ } else {
+ this.source = this.options.source;
+ }
+ },
+
+ search: function( value, event ) {
+ value = value != null ? value : this.element.val();
+
+ // always save the actual value, not the one passed as an argument
+ this.term = this.element.val();
+
+ if ( value.length < this.options.minLength ) {
+ return this.close( event );
+ }
+
+ clearTimeout( this.closing );
+ if ( this._trigger( "search", event ) === false ) {
+ return;
+ }
+
+ return this._search( value );
+ },
+
+ _search: function( value ) {
+ this.pending++;
+ this.element.addClass( "ui-autocomplete-loading" );
+
+ this.source( { term: value }, this.response );
+ },
+
+ _response: function( content ) {
+ if ( !this.options.disabled && content && content.length ) {
+ content = this._normalize( content );
+ this._suggest( content );
+ this._trigger( "open" );
+ } else {
+ this.close();
+ }
+ this.pending--;
+ if ( !this.pending ) {
+ this.element.removeClass( "ui-autocomplete-loading" );
+ }
+ },
+
+ close: function( event ) {
+ clearTimeout( this.closing );
+ if ( this.menu.element.is(":visible") ) {
+ this.menu.element.hide();
+ this.menu.deactivate();
+ this._trigger( "close", event );
+ }
+ },
+
+ _change: function( event ) {
+ if ( this.previous !== this.element.val() ) {
+ this._trigger( "change", event, { item: this.selectedItem } );
+ }
+ },
+
+ _normalize: function( items ) {
+ // assume all items have the right format when the first item is complete
+ if ( items.length && items[0].label && items[0].value ) {
+ return items;
+ }
+ return $.map( items, function(item) {
+ if ( typeof item === "string" ) {
+ return {
+ label: item,
+ value: item
+ };
+ }
+ return $.extend({
+ label: item.label || item.value,
+ value: item.value || item.label
+ }, item );
+ });
+ },
+
+ _suggest: function( items ) {
+ var ul = this.menu.element
+ .empty()
+ .zIndex( this.element.zIndex() + 1 );
+ this._renderMenu( ul, items );
+ // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
+ this.menu.deactivate();
+ this.menu.refresh();
+
+ // size and position menu
+ ul.show();
+ this._resizeMenu();
+ ul.position( $.extend({
+ of: this.element
+ }, this.options.position ));
+
+ if ( this.options.autoFocus ) {
+ this.menu.next( new $.Event("mouseover") );
+ }
+ },
+
+ _resizeMenu: function() {
+ var ul = this.menu.element;
+ ul.outerWidth( Math.max(
+ ul.width( "" ).outerWidth(),
+ this.element.outerWidth()
+ ) );
+ },
+
+ _renderMenu: function( ul, items ) {
+ var self = this;
+ $.each( items, function( index, item ) {
+ self._renderItem( ul, item );
+ });
+ },
+
+ _renderItem: function( ul, item) {
+ return $( "<li></li>" )
+ .data( "item.autocomplete", item )
+ .append( $( "<a></a>" ).text( item.label ) )
+ .appendTo( ul );
+ },
+
+ _move: function( direction, event ) {
+ if ( !this.menu.element.is(":visible") ) {
+ this.search( null, event );
+ return;
+ }
+ if ( this.menu.first() && /^previous/.test(direction) ||
+ this.menu.last() && /^next/.test(direction) ) {
+ this.element.val( this.term );
+ this.menu.deactivate();
+ return;
+ }
+ this.menu[ direction ]( event );
+ },
+
+ widget: function() {
+ return this.menu.element;
+ }
+});
+
+$.extend( $.ui.autocomplete, {
+ escapeRegex: function( value ) {
+ return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
+ },
+ filter: function(array, term) {
+ var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
+ return $.grep( array, function(value) {
+ return matcher.test( value.label || value.value || value );
+ });
+ }
+});
+
+}( jQuery ));
+
+/*
+ * jQuery UI Menu (not officially released)
+ *
+ * This widget isn't yet finished and the API is subject to change. We plan to finish
+ * it for the next release. You're welcome to give it a try anyway and give us feedback,
+ * as long as you're okay with migrating your code later on. We can help with that, too.
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Menu
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ */
+(function($) {
+
+$.widget("ui.menu", {
+ _create: function() {
+ var self = this;
+ this.element
+ .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
+ .attr({
+ role: "listbox",
+ "aria-activedescendant": "ui-active-menuitem"
+ })
+ .click(function( event ) {
+ if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
+ return;
+ }
+ // temporary
+ event.preventDefault();
+ self.select( event );
+ });
+ this.refresh();
+ },
+
+ refresh: function() {
+ var self = this;
+
+ // don't refresh list items that are already adapted
+ var items = this.element.children("li:not(.ui-menu-item):has(a)")
+ .addClass("ui-menu-item")
+ .attr("role", "menuitem");
+
+ items.children("a")
+ .addClass("ui-corner-all")
+ .attr("tabindex", -1)
+ // mouseenter doesn't work with event delegation
+ .mouseenter(function( event ) {
+ self.activate( event, $(this).parent() );
+ })
+ .mouseleave(function() {
+ self.deactivate();
+ });
+ },
+
+ activate: function( event, item ) {
+ this.deactivate();
+ if (this.hasScroll()) {
+ var offset = item.offset().top - this.element.offset().top,
+ scroll = this.element.scrollTop(),
+ elementHeight = this.element.height();
+ if (offset < 0) {
+ this.element.scrollTop( scroll + offset);
+ } else if (offset >= elementHeight) {
+ this.element.scrollTop( scroll + offset - elementHeight + item.height());
+ }
+ }
+ this.active = item.eq(0)
+ .children("a")
+ .addClass("ui-state-hover")
+ .attr("id", "ui-active-menuitem")
+ .end();
+ this._trigger("focus", event, { item: item });
+ },
+
+ deactivate: function() {
+ if (!this.active) { return; }
+
+ this.active.children("a")
+ .removeClass("ui-state-hover")
+ .removeAttr("id");
+ this._trigger("blur");
+ this.active = null;
+ },
+
+ next: function(event) {
+ this.move("next", ".ui-menu-item:first", event);
+ },
+
+ previous: function(event) {
+ this.move("prev", ".ui-menu-item:last", event);
+ },
+
+ first: function() {
+ return this.active && !this.active.prevAll(".ui-menu-item").length;
+ },
+
+ last: function() {
+ return this.active && !this.active.nextAll(".ui-menu-item").length;
+ },
+
+ move: function(direction, edge, event) {
+ if (!this.active) {
+ this.activate(event, this.element.children(edge));
+ return;
+ }
+ var next = this.active[direction + "All"](".ui-menu-item").eq(0);
+ if (next.length) {
+ this.activate(event, next);
+ } else {
+ this.activate(event, this.element.children(edge));
+ }
+ },
+
+ // TODO merge with previousPage
+ nextPage: function(event) {
+ if (this.hasScroll()) {
+ // TODO merge with no-scroll-else
+ if (!this.active || this.last()) {
+ this.activate(event, this.element.children(".ui-menu-item:first"));
+ return;
+ }
+ var base = this.active.offset().top,
+ height = this.element.height(),
+ result = this.element.children(".ui-menu-item").filter(function() {
+ var close = $(this).offset().top - base - height + $(this).height();
+ // TODO improve approximation
+ return close < 10 && close > -10;
+ });
+
+ // TODO try to catch this earlier when scrollTop indicates the last page anyway
+ if (!result.length) {
+ result = this.element.children(".ui-menu-item:last");
+ }
+ this.activate(event, result);
+ } else {
+ this.activate(event, this.element.children(".ui-menu-item")
+ .filter(!this.active || this.last() ? ":first" : ":last"));
+ }
+ },
+
+ // TODO merge with nextPage
+ previousPage: function(event) {
+ if (this.hasScroll()) {
+ // TODO merge with no-scroll-else
+ if (!this.active || this.first()) {
+ this.activate(event, this.element.children(".ui-menu-item:last"));
+ return;
+ }
+
+ var base = this.active.offset().top,
+ height = this.element.height();
+ result = this.element.children(".ui-menu-item").filter(function() {
+ var close = $(this).offset().top - base + height - $(this).height();
+ // TODO improve approximation
+ return close < 10 && close > -10;
+ });
+
+ // TODO try to catch this earlier when scrollTop indicates the last page anyway
+ if (!result.length) {
+ result = this.element.children(".ui-menu-item:first");
+ }
+ this.activate(event, result);
+ } else {
+ this.activate(event, this.element.children(".ui-menu-item")
+ .filter(!this.active || this.first() ? ":last" : ":first"));
+ }
+ },
+
+ hasScroll: function() {
+ return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight");
+ },
+
+ select: function( event ) {
+ this._trigger("selected", event, { item: this.active });
+ }
+});
+
+}(jQuery));
+/*
+ * jQuery UI Button 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Button
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+var lastActive, startXPos, startYPos, clickDragged,
+ baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
+ stateClasses = "ui-state-hover ui-state-active ",
+ typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
+ formResetHandler = function() {
+ var buttons = $( this ).find( ":ui-button" );
+ setTimeout(function() {
+ buttons.button( "refresh" );
+ }, 1 );
+ },
+ radioGroup = function( radio ) {
+ var name = radio.name,
+ form = radio.form,
+ radios = $( [] );
+ if ( name ) {
+ if ( form ) {
+ radios = $( form ).find( "[name='" + name + "']" );
+ } else {
+ radios = $( "[name='" + name + "']", radio.ownerDocument )
+ .filter(function() {
+ return !this.form;
+ });
+ }
+ }
+ return radios;
+ };
+
+$.widget( "ui.button", {
+ options: {
+ disabled: null,
+ text: true,
+ label: null,
+ icons: {
+ primary: null,
+ secondary: null
+ }
+ },
+ _create: function() {
+ this.element.closest( "form" )
+ .unbind( "reset.button" )
+ .bind( "reset.button", formResetHandler );
+
+ if ( typeof this.options.disabled !== "boolean" ) {
+ this.options.disabled = this.element.propAttr( "disabled" );
+ }
+
+ this._determineButtonType();
+ this.hasTitle = !!this.buttonElement.attr( "title" );
+
+ var self = this,
+ options = this.options,
+ toggleButton = this.type === "checkbox" || this.type === "radio",
+ hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
+ focusClass = "ui-state-focus";
+
+ if ( options.label === null ) {
+ options.label = this.buttonElement.html();
+ }
+
+ if ( this.element.is( ":disabled" ) ) {
+ options.disabled = true;
+ }
+
+ this.buttonElement
+ .addClass( baseClasses )
+ .attr( "role", "button" )
+ .bind( "mouseenter.button", function() {
+ if ( options.disabled ) {
+ return;
+ }
+ $( this ).addClass( "ui-state-hover" );
+ if ( this === lastActive ) {
+ $( this ).addClass( "ui-state-active" );
+ }
+ })
+ .bind( "mouseleave.button", function() {
+ if ( options.disabled ) {
+ return;
+ }
+ $( this ).removeClass( hoverClass );
+ })
+ .bind( "click.button", function( event ) {
+ if ( options.disabled ) {
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ }
+ });
+
+ this.element
+ .bind( "focus.button", function() {
+ // no need to check disabled, focus won't be triggered anyway
+ self.buttonElement.addClass( focusClass );
+ })
+ .bind( "blur.button", function() {
+ self.buttonElement.removeClass( focusClass );
+ });
+
+ if ( toggleButton ) {
+ this.element.bind( "change.button", function() {
+ if ( clickDragged ) {
+ return;
+ }
+ self.refresh();
+ });
+ // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
+ // prevents issue where button state changes but checkbox/radio checked state
+ // does not in Firefox (see ticket #6970)
+ this.buttonElement
+ .bind( "mousedown.button", function( event ) {
+ if ( options.disabled ) {
+ return;
+ }
+ clickDragged = false;
+ startXPos = event.pageX;
+ startYPos = event.pageY;
+ })
+ .bind( "mouseup.button", function( event ) {
+ if ( options.disabled ) {
+ return;
+ }
+ if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
+ clickDragged = true;
+ }
+ });
+ }
+
+ if ( this.type === "checkbox" ) {
+ this.buttonElement.bind( "click.button", function() {
+ if ( options.disabled || clickDragged ) {
+ return false;
+ }
+ $( this ).toggleClass( "ui-state-active" );
+ self.buttonElement.attr( "aria-pressed", self.element[0].checked );
+ });
+ } else if ( this.type === "radio" ) {
+ this.buttonElement.bind( "click.button", function() {
+ if ( options.disabled || clickDragged ) {
+ return false;
+ }
+ $( this ).addClass( "ui-state-active" );
+ self.buttonElement.attr( "aria-pressed", "true" );
+
+ var radio = self.element[ 0 ];
+ radioGroup( radio )
+ .not( radio )
+ .map(function() {
+ return $( this ).button( "widget" )[ 0 ];
+ })
+ .removeClass( "ui-state-active" )
+ .attr( "aria-pressed", "false" );
+ });
+ } else {
+ this.buttonElement
+ .bind( "mousedown.button", function() {
+ if ( options.disabled ) {
+ return false;
+ }
+ $( this ).addClass( "ui-state-active" );
+ lastActive = this;
+ $( document ).one( "mouseup", function() {
+ lastActive = null;
+ });
+ })
+ .bind( "mouseup.button", function() {
+ if ( options.disabled ) {
+ return false;
+ }
+ $( this ).removeClass( "ui-state-active" );
+ })
+ .bind( "keydown.button", function(event) {
+ if ( options.disabled ) {
+ return false;
+ }
+ if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
+ $( this ).addClass( "ui-state-active" );
+ }
+ })
+ .bind( "keyup.button", function() {
+ $( this ).removeClass( "ui-state-active" );
+ });
+
+ if ( this.buttonElement.is("a") ) {
+ this.buttonElement.keyup(function(event) {
+ if ( event.keyCode === $.ui.keyCode.SPACE ) {
+ // TODO pass through original event correctly (just as 2nd argument doesn't work)
+ $( this ).click();
+ }
+ });
+ }
+ }
+
+ // TODO: pull out $.Widget's handling for the disabled option into
+ // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
+ // be overridden by individual plugins
+ this._setOption( "disabled", options.disabled );
+ this._resetButton();
+ },
+
+ _determineButtonType: function() {
+
+ if ( this.element.is(":checkbox") ) {
+ this.type = "checkbox";
+ } else if ( this.element.is(":radio") ) {
+ this.type = "radio";
+ } else if ( this.element.is("input") ) {
+ this.type = "input";
+ } else {
+ this.type = "button";
+ }
+
+ if ( this.type === "checkbox" || this.type === "radio" ) {
+ // we don't search against the document in case the element
+ // is disconnected from the DOM
+ var ancestor = this.element.parents().filter(":last"),
+ labelSelector = "label[for='" + this.element.attr("id") + "']";
+ this.buttonElement = ancestor.find( labelSelector );
+ if ( !this.buttonElement.length ) {
+ ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
+ this.buttonElement = ancestor.filter( labelSelector );
+ if ( !this.buttonElement.length ) {
+ this.buttonElement = ancestor.find( labelSelector );
+ }
+ }
+ this.element.addClass( "ui-helper-hidden-accessible" );
+
+ var checked = this.element.is( ":checked" );
+ if ( checked ) {
+ this.buttonElement.addClass( "ui-state-active" );
+ }
+ this.buttonElement.attr( "aria-pressed", checked );
+ } else {
+ this.buttonElement = this.element;
+ }
+ },
+
+ widget: function() {
+ return this.buttonElement;
+ },
+
+ destroy: function() {
+ this.element
+ .removeClass( "ui-helper-hidden-accessible" );
+ this.buttonElement
+ .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
+ .removeAttr( "role" )
+ .removeAttr( "aria-pressed" )
+ .html( this.buttonElement.find(".ui-button-text").html() );
+
+ if ( !this.hasTitle ) {
+ this.buttonElement.removeAttr( "title" );
+ }
+
+ $.Widget.prototype.destroy.call( this );
+ },
+
+ _setOption: function( key, value ) {
+ $.Widget.prototype._setOption.apply( this, arguments );
+ if ( key === "disabled" ) {
+ if ( value ) {
+ this.element.propAttr( "disabled", true );
+ } else {
+ this.element.propAttr( "disabled", false );
+ }
+ return;
+ }
+ this._resetButton();
+ },
+
+ refresh: function() {
+ var isDisabled = this.element.is( ":disabled" );
+ if ( isDisabled !== this.options.disabled ) {
+ this._setOption( "disabled", isDisabled );
+ }
+ if ( this.type === "radio" ) {
+ radioGroup( this.element[0] ).each(function() {
+ if ( $( this ).is( ":checked" ) ) {
+ $( this ).button( "widget" )
+ .addClass( "ui-state-active" )
+ .attr( "aria-pressed", "true" );
+ } else {
+ $( this ).button( "widget" )
+ .removeClass( "ui-state-active" )
+ .attr( "aria-pressed", "false" );
+ }
+ });
+ } else if ( this.type === "checkbox" ) {
+ if ( this.element.is( ":checked" ) ) {
+ this.buttonElement
+ .addClass( "ui-state-active" )
+ .attr( "aria-pressed", "true" );
+ } else {
+ this.buttonElement
+ .removeClass( "ui-state-active" )
+ .attr( "aria-pressed", "false" );
+ }
+ }
+ },
+
+ _resetButton: function() {
+ if ( this.type === "input" ) {
+ if ( this.options.label ) {
+ this.element.val( this.options.label );
+ }
+ return;
+ }
+ var buttonElement = this.buttonElement.removeClass( typeClasses ),
+ buttonText = $( "<span></span>" )
+ .addClass( "ui-button-text" )
+ .html( this.options.label )
+ .appendTo( buttonElement.empty() )
+ .text(),
+ icons = this.options.icons,
+ multipleIcons = icons.primary && icons.secondary,
+ buttonClasses = [];
+
+ if ( icons.primary || icons.secondary ) {
+ if ( this.options.text ) {
+ buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
+ }
+
+ if ( icons.primary ) {
+ buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
+ }
+
+ if ( icons.secondary ) {
+ buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
+ }
+
+ if ( !this.options.text ) {
+ buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
+
+ if ( !this.hasTitle ) {
+ buttonElement.attr( "title", buttonText );
+ }
+ }
+ } else {
+ buttonClasses.push( "ui-button-text-only" );
+ }
+ buttonElement.addClass( buttonClasses.join( " " ) );
+ }
+});
+
+$.widget( "ui.buttonset", {
+ options: {
+ items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
+ },
+
+ _create: function() {
+ this.element.addClass( "ui-buttonset" );
+ },
+
+ _init: function() {
+ this.refresh();
+ },
+
+ _setOption: function( key, value ) {
+ if ( key === "disabled" ) {
+ this.buttons.button( "option", key, value );
+ }
+
+ $.Widget.prototype._setOption.apply( this, arguments );
+ },
+
+ refresh: function() {
+ var ltr = this.element.css( "direction" ) === "ltr";
+
+ this.buttons = this.element.find( this.options.items )
+ .filter( ":ui-button" )
+ .button( "refresh" )
+ .end()
+ .not( ":ui-button" )
+ .button()
+ .end()
+ .map(function() {
+ return $( this ).button( "widget" )[ 0 ];
+ })
+ .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
+ .filter( ":first" )
+ .addClass( ltr ? "ui-corner-left" : "ui-corner-right" )
+ .end()
+ .filter( ":last" )
+ .addClass( ltr ? "ui-corner-right" : "ui-corner-left" )
+ .end()
+ .end();
+ },
+
+ destroy: function() {
+ this.element.removeClass( "ui-buttonset" );
+ this.buttons
+ .map(function() {
+ return $( this ).button( "widget" )[ 0 ];
+ })
+ .removeClass( "ui-corner-left ui-corner-right" )
+ .end()
+ .button( "destroy" );
+
+ $.Widget.prototype.destroy.call( this );
+ }
+});
+
+}( jQuery ) );
+/*
+ * jQuery UI Datepicker 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Datepicker
+ *
+ * Depends:
+ * jquery.ui.core.js
+ */
+(function( $, undefined ) {
+
+$.extend($.ui, { datepicker: { version: "1.8.16" } });
+
+var PROP_NAME = 'datepicker';
+var dpuuid = new Date().getTime();
+var instActive;
+
+/* Date picker manager.
+ Use the singleton instance of this class, $.datepicker, to interact with the date picker.
+ Settings for (groups of) date pickers are maintained in an instance object,
+ allowing multiple different settings on the same page. */
+
+function Datepicker() {
+ this.debug = false; // Change this to true to start debugging
+ this._curInst = null; // The current instance in use
+ this._keyEvent = false; // If the last event was a key event
+ this._disabledInputs = []; // List of date picker inputs that have been disabled
+ this._datepickerShowing = false; // True if the popup picker is showing , false if not
+ this._inDialog = false; // True if showing within a "dialog", false if not
+ this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
+ this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
+ this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
+ this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
+ this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
+ this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
+ this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
+ this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
+ this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
+ this.regional = []; // Available regional settings, indexed by language code
+ this.regional[''] = { // Default regional settings
+ closeText: 'Done', // Display text for close link
+ prevText: 'Prev', // Display text for previous month link
+ nextText: 'Next', // Display text for next month link
+ currentText: 'Today', // Display text for current month link
+ monthNames: ['January','February','March','April','May','June',
+ 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
+ monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
+ dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
+ dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
+ dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
+ weekHeader: 'Wk', // Column header for week of the year
+ dateFormat: 'mm/dd/yy', // See format options on parseDate
+ firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
+ isRTL: false, // True if right-to-left language, false if left-to-right
+ showMonthAfterYear: false, // True if the year select precedes month, false for month then year
+ yearSuffix: '' // Additional text to append to the year in the month headers
+ };
+ this._defaults = { // Global defaults for all the date picker instances
+ showOn: 'focus', // 'focus' for popup on focus,
+ // 'button' for trigger button, or 'both' for either
+ showAnim: 'fadeIn', // Name of jQuery animation for popup
+ showOptions: {}, // Options for enhanced animations
+ defaultDate: null, // Used when field is blank: actual date,
+ // +/-number for offset from today, null for today
+ appendText: '', // Display text following the input box, e.g. showing the format
+ buttonText: '...', // Text for trigger button
+ buttonImage: '', // URL for trigger button image
+ buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
+ hideIfNoPrevNext: false, // True to hide next/previous month links
+ // if not applicable, false to just disable them
+ navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
+ gotoCurrent: false, // True if today link goes back to current selection instead
+ changeMonth: false, // True if month can be selected directly, false if only prev/next
+ changeYear: false, // True if year can be selected directly, false if only prev/next
+ yearRange: 'c-10:c+10', // Range of years to display in drop-down,
+ // either relative to today's year (-nn:+nn), relative to currently displayed year
+ // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
+ showOtherMonths: false, // True to show dates in other months, false to leave blank
+ selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
+ showWeek: false, // True to show week of the year, false to not show it
+ calculateWeek: this.iso8601Week, // How to calculate the week of the year,
+ // takes a Date and returns the number of the week for it
+ shortYearCutoff: '+10', // Short year values < this are in the current century,
+ // > this are in the previous century,
+ // string value starting with '+' for current year + value
+ minDate: null, // The earliest selectable date, or null for no limit
+ maxDate: null, // The latest selectable date, or null for no limit
+ duration: 'fast', // Duration of display/closure
+ beforeShowDay: null, // Function that takes a date and returns an array with
+ // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
+ // [2] = cell title (optional), e.g. $.datepicker.noWeekends
+ beforeShow: null, // Function that takes an input field and
+ // returns a set of custom settings for the date picker
+ onSelect: null, // Define a callback function when a date is selected
+ onChangeMonthYear: null, // Define a callback function when the month or year is changed
+ onClose: null, // Define a callback function when the datepicker is closed
+ numberOfMonths: 1, // Number of months to show at a time
+ showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
+ stepMonths: 1, // Number of months to step back/forward
+ stepBigMonths: 12, // Number of months to step back/forward for the big links
+ altField: '', // Selector for an alternate field to store selected dates into
+ altFormat: '', // The date format to use for the alternate field
+ constrainInput: true, // The input is constrained by the current date format
+ showButtonPanel: false, // True to show button panel, false to not show it
+ autoSize: false, // True to size the input for the date format, false to leave as is
+ disabled: false // The initial disabled state
+ };
+ $.extend(this._defaults, this.regional['']);
+ this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
+}
+
+$.extend(Datepicker.prototype, {
+ /* Class name added to elements to indicate already configured with a date picker. */
+ markerClassName: 'hasDatepicker',
+
+ //Keep track of the maximum number of rows displayed (see #7043)
+ maxRows: 4,
+
+ /* Debug logging (if enabled). */
+ log: function () {
+ if (this.debug)
+ console.log.apply('', arguments);
+ },
+
+ // TODO rename to "widget" when switching to widget factory
+ _widgetDatepicker: function() {
+ return this.dpDiv;
+ },
+
+ /* Override the default settings for all instances of the date picker.
+ @param settings object - the new settings to use as defaults (anonymous object)
+ @return the manager object */
+ setDefaults: function(settings) {
+ extendRemove(this._defaults, settings || {});
+ return this;
+ },
+
+ /* Attach the date picker to a jQuery selection.
+ @param target element - the target input field or division or span
+ @param settings object - the new settings to use for this date picker instance (anonymous) */
+ _attachDatepicker: function(target, settings) {
+ // check for settings on the control itself - in namespace 'date:'
+ var inlineSettings = null;
+ for (var attrName in this._defaults) {
+ var attrValue = target.getAttribute('date:' + attrName);
+ if (attrValue) {
+ inlineSettings = inlineSettings || {};
+ try {
+ inlineSettings[attrName] = eval(attrValue);
+ } catch (err) {
+ inlineSettings[attrName] = attrValue;
+ }
+ }
+ }
+ var nodeName = target.nodeName.toLowerCase();
+ var inline = (nodeName == 'div' || nodeName == 'span');
+ if (!target.id) {
+ this.uuid += 1;
+ target.id = 'dp' + this.uuid;
+ }
+ var inst = this._newInst($(target), inline);
+ inst.settings = $.extend({}, settings || {}, inlineSettings || {});
+ if (nodeName == 'input') {
+ this._connectDatepicker(target, inst);
+ } else if (inline) {
+ this._inlineDatepicker(target, inst);
+ }
+ },
+
+ /* Create a new instance object. */
+ _newInst: function(target, inline) {
+ var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
+ return {id: id, input: target, // associated target
+ selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
+ drawMonth: 0, drawYear: 0, // month being drawn
+ inline: inline, // is datepicker inline or not
+ dpDiv: (!inline ? this.dpDiv : // presentation div
+ bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
+ },
+
+ /* Attach the date picker to an input field. */
+ _connectDatepicker: function(target, inst) {
+ var input = $(target);
+ inst.append = $([]);
+ inst.trigger = $([]);
+ if (input.hasClass(this.markerClassName))
+ return;
+ this._attachments(input, inst);
+ input.addClass(this.markerClassName).keydown(this._doKeyDown).
+ keypress(this._doKeyPress).keyup(this._doKeyUp).
+ bind("setData.datepicker", function(event, key, value) {
+ inst.settings[key] = value;
+ }).bind("getData.datepicker", function(event, key) {
+ return this._get(inst, key);
+ });
+ this._autoSize(inst);
+ $.data(target, PROP_NAME, inst);
+ //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
+ if( inst.settings.disabled ) {
+ this._disableDatepicker( target );
+ }
+ },
+
+ /* Make attachments based on settings. */
+ _attachments: function(input, inst) {
+ var appendText = this._get(inst, 'appendText');
+ var isRTL = this._get(inst, 'isRTL');
+ if (inst.append)
+ inst.append.remove();
+ if (appendText) {
+ inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
+ input[isRTL ? 'before' : 'after'](inst.append);
+ }
+ input.unbind('focus', this._showDatepicker);
+ if (inst.trigger)
+ inst.trigger.remove();
+ var showOn = this._get(inst, 'showOn');
+ if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
+ input.focus(this._showDatepicker);
+ if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
+ var buttonText = this._get(inst, 'buttonText');
+ var buttonImage = this._get(inst, 'buttonImage');
+ inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
+ $('<img/>').addClass(this._triggerClass).
+ attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
+ $('<button type="button"></button>').addClass(this._triggerClass).
+ html(buttonImage == '' ? buttonText : $('<img/>').attr(
+ { src:buttonImage, alt:buttonText, title:buttonText })));
+ input[isRTL ? 'before' : 'after'](inst.trigger);
+ inst.trigger.click(function() {
+ if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
+ $.datepicker._hideDatepicker();
+ else
+ $.datepicker._showDatepicker(input[0]);
+ return false;
+ });
+ }
+ },
+
+ /* Apply the maximum length for the date format. */
+ _autoSize: function(inst) {
+ if (this._get(inst, 'autoSize') && !inst.inline) {
+ var date = new Date(2009, 12 - 1, 20); // Ensure double digits
+ var dateFormat = this._get(inst, 'dateFormat');
+ if (dateFormat.match(/[DM]/)) {
+ var findMax = function(names) {
+ var max = 0;
+ var maxI = 0;
+ for (var i = 0; i < names.length; i++) {
+ if (names[i].length > max) {
+ max = names[i].length;
+ maxI = i;
+ }
+ }
+ return maxI;
+ };
+ date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
+ 'monthNames' : 'monthNamesShort'))));
+ date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
+ 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
+ }
+ inst.input.attr('size', this._formatDate(inst, date).length);
+ }
+ },
+
+ /* Attach an inline date picker to a div. */
+ _inlineDatepicker: function(target, inst) {
+ var divSpan = $(target);
+ if (divSpan.hasClass(this.markerClassName))
+ return;
+ divSpan.addClass(this.markerClassName).append(inst.dpDiv).
+ bind("setData.datepicker", function(event, key, value){
+ inst.settings[key] = value;
+ }).bind("getData.datepicker", function(event, key){
+ return this._get(inst, key);
+ });
+ $.data(target, PROP_NAME, inst);
+ this._setDate(inst, this._getDefaultDate(inst), true);
+ this._updateDatepicker(inst);
+ this._updateAlternate(inst);
+ //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
+ if( inst.settings.disabled ) {
+ this._disableDatepicker( target );
+ }
+ // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
+ // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
+ inst.dpDiv.css( "display", "block" );
+ },
+
+ /* Pop-up the date picker in a "dialog" box.
+ @param input element - ignored
+ @param date string or Date - the initial date to display
+ @param onSelect function - the function to call when a date is selected
+ @param settings object - update the dialog date picker instance's settings (anonymous object)
+ @param pos int[2] - coordinates for the dialog's position within the screen or
+ event - with x/y coordinates or
+ leave empty for default (screen centre)
+ @return the manager object */
+ _dialogDatepicker: function(input, date, onSelect, settings, pos) {
+ var inst = this._dialogInst; // internal instance
+ if (!inst) {
+ this.uuid += 1;
+ var id = 'dp' + this.uuid;
+ this._dialogInput = $('<input type="text" id="' + id +
+ '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
+ this._dialogInput.keydown(this._doKeyDown);
+ $('body').append(this._dialogInput);
+ inst = this._dialogInst = this._newInst(this._dialogInput, false);
+ inst.settings = {};
+ $.data(this._dialogInput[0], PROP_NAME, inst);
+ }
+ extendRemove(inst.settings, settings || {});
+ date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
+ this._dialogInput.val(date);
+
+ this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
+ if (!this._pos) {
+ var browserWidth = document.documentElement.clientWidth;
+ var browserHeight = document.documentElement.clientHeight;
+ var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
+ var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
+ this._pos = // should use actual width/height below
+ [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
+ }
+
+ // move input on screen for focus, but hidden behind dialog
+ this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
+ inst.settings.onSelect = onSelect;
+ this._inDialog = true;
+ this.dpDiv.addClass(this._dialogClass);
+ this._showDatepicker(this._dialogInput[0]);
+ if ($.blockUI)
+ $.blockUI(this.dpDiv);
+ $.data(this._dialogInput[0], PROP_NAME, inst);
+ return this;
+ },
+
+ /* Detach a datepicker from its control.
+ @param target element - the target input field or division or span */
+ _destroyDatepicker: function(target) {
+ var $target = $(target);
+ var inst = $.data(target, PROP_NAME);
+ if (!$target.hasClass(this.markerClassName)) {
+ return;
+ }
+ var nodeName = target.nodeName.toLowerCase();
+ $.removeData(target, PROP_NAME);
+ if (nodeName == 'input') {
+ inst.append.remove();
+ inst.trigger.remove();
+ $target.removeClass(this.markerClassName).
+ unbind('focus', this._showDatepicker).
+ unbind('keydown', this._doKeyDown).
+ unbind('keypress', this._doKeyPress).
+ unbind('keyup', this._doKeyUp);
+ } else if (nodeName == 'div' || nodeName == 'span')
+ $target.removeClass(this.markerClassName).empty();
+ },
+
+ /* Enable the date picker to a jQuery selection.
+ @param target element - the target input field or division or span */
+ _enableDatepicker: function(target) {
+ var $target = $(target);
+ var inst = $.data(target, PROP_NAME);
+ if (!$target.hasClass(this.markerClassName)) {
+ return;
+ }
+ var nodeName = target.nodeName.toLowerCase();
+ if (nodeName == 'input') {
+ target.disabled = false;
+ inst.trigger.filter('button').
+ each(function() { this.disabled = false; }).end().
+ filter('img').css({opacity: '1.0', cursor: ''});
+ }
+ else if (nodeName == 'div' || nodeName == 'span') {
+ var inline = $target.children('.' + this._inlineClass);
+ inline.children().removeClass('ui-state-disabled');
+ inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
+ removeAttr("disabled");
+ }
+ this._disabledInputs = $.map(this._disabledInputs,
+ function(value) { return (value == target ? null : value); }); // delete entry
+ },
+
+ /* Disable the date picker to a jQuery selection.
+ @param target element - the target input field or division or span */
+ _disableDatepicker: function(target) {
+ var $target = $(target);
+ var inst = $.data(target, PROP_NAME);
+ if (!$target.hasClass(this.markerClassName)) {
+ return;
+ }
+ var nodeName = target.nodeName.toLowerCase();
+ if (nodeName == 'input') {
+ target.disabled = true;
+ inst.trigger.filter('button').
+ each(function() { this.disabled = true; }).end().
+ filter('img').css({opacity: '0.5', cursor: 'default'});
+ }
+ else if (nodeName == 'div' || nodeName == 'span') {
+ var inline = $target.children('.' + this._inlineClass);
+ inline.children().addClass('ui-state-disabled');
+ inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
+ attr("disabled", "disabled");
+ }
+ this._disabledInputs = $.map(this._disabledInputs,
+ function(value) { return (value == target ? null : value); }); // delete entry
+ this._disabledInputs[this._disabledInputs.length] = target;
+ },
+
+ /* Is the first field in a jQuery collection disabled as a datepicker?
+ @param target element - the target input field or division or span
+ @return boolean - true if disabled, false if enabled */
+ _isDisabledDatepicker: function(target) {
+ if (!target) {
+ return false;
+ }
+ for (var i = 0; i < this._disabledInputs.length; i++) {
+ if (this._disabledInputs[i] == target)
+ return true;
+ }
+ return false;
+ },
+
+ /* Retrieve the instance data for the target control.
+ @param target element - the target input field or division or span
+ @return object - the associated instance data
+ @throws error if a jQuery problem getting data */
+ _getInst: function(target) {
+ try {
+ return $.data(target, PROP_NAME);
+ }
+ catch (err) {
+ throw 'Missing instance data for this datepicker';
+ }
+ },
+
+ /* Update or retrieve the settings for a date picker attached to an input field or division.
+ @param target element - the target input field or division or span
+ @param name object - the new settings to update or
+ string - the name of the setting to change or retrieve,
+ when retrieving also 'all' for all instance settings or
+ 'defaults' for all global defaults
+ @param value any - the new value for the setting
+ (omit if above is an object or to retrieve a value) */
+ _optionDatepicker: function(target, name, value) {
+ var inst = this._getInst(target);
+ if (arguments.length == 2 && typeof name == 'string') {
+ return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
+ (inst ? (name == 'all' ? $.extend({}, inst.settings) :
+ this._get(inst, name)) : null));
+ }
+ var settings = name || {};
+ if (typeof name == 'string') {
+ settings = {};
+ settings[name] = value;
+ }
+ if (inst) {
+ if (this._curInst == inst) {
+ this._hideDatepicker();
+ }
+ var date = this._getDateDatepicker(target, true);
+ var minDate = this._getMinMaxDate(inst, 'min');
+ var maxDate = this._getMinMaxDate(inst, 'max');
+ extendRemove(inst.settings, settings);
+ // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
+ if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
+ inst.settings.minDate = this._formatDate(inst, minDate);
+ if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
+ inst.settings.maxDate = this._formatDate(inst, maxDate);
+ this._attachments($(target), inst);
+ this._autoSize(inst);
+ this._setDate(inst, date);
+ this._updateAlternate(inst);
+ this._updateDatepicker(inst);
+ }
+ },
+
+ // change method deprecated
+ _changeDatepicker: function(target, name, value) {
+ this._optionDatepicker(target, name, value);
+ },
+
+ /* Redraw the date picker attached to an input field or division.
+ @param target element - the target input field or division or span */
+ _refreshDatepicker: function(target) {
+ var inst = this._getInst(target);
+ if (inst) {
+ this._updateDatepicker(inst);
+ }
+ },
+
+ /* Set the dates for a jQuery selection.
+ @param target element - the target input field or division or span
+ @param date Date - the new date */
+ _setDateDatepicker: function(target, date) {
+ var inst = this._getInst(target);
+ if (inst) {
+ this._setDate(inst, date);
+ this._updateDatepicker(inst);
+ this._updateAlternate(inst);
+ }
+ },
+
+ /* Get the date(s) for the first entry in a jQuery selection.
+ @param target element - the target input field or division or span
+ @param noDefault boolean - true if no default date is to be used
+ @return Date - the current date */
+ _getDateDatepicker: function(target, noDefault) {
+ var inst = this._getInst(target);
+ if (inst && !inst.inline)
+ this._setDateFromField(inst, noDefault);
+ return (inst ? this._getDate(inst) : null);
+ },
+
+ /* Handle keystrokes. */
+ _doKeyDown: function(event) {
+ var inst = $.datepicker._getInst(event.target);
+ var handled = true;
+ var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
+ inst._keyEvent = true;
+ if ($.datepicker._datepickerShowing)
+ switch (event.keyCode) {
+ case 9: $.datepicker._hideDatepicker();
+ handled = false;
+ break; // hide on tab out
+ case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
+ $.datepicker._currentClass + ')', inst.dpDiv);
+ if (sel[0])
+ $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
+ var onSelect = $.datepicker._get(inst, 'onSelect');
+ if (onSelect) {
+ var dateStr = $.datepicker._formatDate(inst);
+
+ // trigger custom callback
+ onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
+ }
+ else
+ $.datepicker._hideDatepicker();
+ return false; // don't submit the form
+ break; // select the value on enter
+ case 27: $.datepicker._hideDatepicker();
+ break; // hide on escape
+ case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+ -$.datepicker._get(inst, 'stepBigMonths') :
+ -$.datepicker._get(inst, 'stepMonths')), 'M');
+ break; // previous month/year on page up/+ ctrl
+ case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+ +$.datepicker._get(inst, 'stepBigMonths') :
+ +$.datepicker._get(inst, 'stepMonths')), 'M');
+ break; // next month/year on page down/+ ctrl
+ case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
+ handled = event.ctrlKey || event.metaKey;
+ break; // clear on ctrl or command +end
+ case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
+ handled = event.ctrlKey || event.metaKey;
+ break; // current on ctrl or command +home
+ case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
+ handled = event.ctrlKey || event.metaKey;
+ // -1 day on ctrl or command +left
+ if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+ -$.datepicker._get(inst, 'stepBigMonths') :
+ -$.datepicker._get(inst, 'stepMonths')), 'M');
+ // next month/year on alt +left on Mac
+ break;
+ case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
+ handled = event.ctrlKey || event.metaKey;
+ break; // -1 week on ctrl or command +up
+ case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
+ handled = event.ctrlKey || event.metaKey;
+ // +1 day on ctrl or command +right
+ if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+ +$.datepicker._get(inst, 'stepBigMonths') :
+ +$.datepicker._get(inst, 'stepMonths')), 'M');
+ // next month/year on alt +right
+ break;
+ case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
+ handled = event.ctrlKey || event.metaKey;
+ break; // +1 week on ctrl or command +down
+ default: handled = false;
+ }
+ else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
+ $.datepicker._showDatepicker(this);
+ else {
+ handled = false;
+ }
+ if (handled) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ },
+
+ /* Filter entered characters - based on date format. */
+ _doKeyPress: function(event) {
+ var inst = $.datepicker._getInst(event.target);
+ if ($.datepicker._get(inst, 'constrainInput')) {
+ var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
+ var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
+ return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
+ }
+ },
+
+ /* Synchronise manual entry and field/alternate field. */
+ _doKeyUp: function(event) {
+ var inst = $.datepicker._getInst(event.target);
+ if (inst.input.val() != inst.lastVal) {
+ try {
+ var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
+ (inst.input ? inst.input.val() : null),
+ $.datepicker._getFormatConfig(inst));
+ if (date) { // only if valid
+ $.datepicker._setDateFromField(inst);
+ $.datepicker._updateAlternate(inst);
+ $.datepicker._updateDatepicker(inst);
+ }
+ }
+ catch (event) {
+ $.datepicker.log(event);
+ }
+ }
+ return true;
+ },
+
+ /* Pop-up the date picker for a given input field.
+ If false returned from beforeShow event handler do not show.
+ @param input element - the input field attached to the date picker or
+ event - if triggered by focus */
+ _showDatepicker: function(input) {
+ input = input.target || input;
+ if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
+ input = $('input', input.parentNode)[0];
+ if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
+ return;
+ var inst = $.datepicker._getInst(input);
+ if ($.datepicker._curInst && $.datepicker._curInst != inst) {
+ if ( $.datepicker._datepickerShowing ) {
+ $.datepicker._triggerOnClose($.datepicker._curInst);
+ }
+ $.datepicker._curInst.dpDiv.stop(true, true);
+ }
+ var beforeShow = $.datepicker._get(inst, 'beforeShow');
+ var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
+ if(beforeShowSettings === false){
+ //false
+ return;
+ }
+ extendRemove(inst.settings, beforeShowSettings);
+ inst.lastVal = null;
+ $.datepicker._lastInput = input;
+ $.datepicker._setDateFromField(inst);
+ if ($.datepicker._inDialog) // hide cursor
+ input.value = '';
+ if (!$.datepicker._pos) { // position below input
+ $.datepicker._pos = $.datepicker._findPos(input);
+ $.datepicker._pos[1] += input.offsetHeight; // add the height
+ }
+ var isFixed = false;
+ $(input).parents().each(function() {
+ isFixed |= $(this).css('position') == 'fixed';
+ return !isFixed;
+ });
+ if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
+ $.datepicker._pos[0] -= document.documentElement.scrollLeft;
+ $.datepicker._pos[1] -= document.documentElement.scrollTop;
+ }
+ var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
+ $.datepicker._pos = null;
+ //to avoid flashes on Firefox
+ inst.dpDiv.empty();
+ // determine sizing offscreen
+ inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
+ $.datepicker._updateDatepicker(inst);
+ // fix width for dynamic number of date pickers
+ // and adjust position before showing
+ offset = $.datepicker._checkOffset(inst, offset, isFixed);
+ inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
+ 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
+ left: offset.left + 'px', top: offset.top + 'px'});
+ if (!inst.inline) {
+ var showAnim = $.datepicker._get(inst, 'showAnim');
+ var duration = $.datepicker._get(inst, 'duration');
+ var postProcess = function() {
+ var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
+ if( !! cover.length ){
+ var borders = $.datepicker._getBorders(inst.dpDiv);
+ cover.css({left: -borders[0], top: -borders[1],
+ width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
+ }
+ };
+ inst.dpDiv.zIndex($(input).zIndex()+1);
+ $.datepicker._datepickerShowing = true;
+ if ($.effects && $.effects[showAnim])
+ inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
+ else
+ inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
+ if (!showAnim || !duration)
+ postProcess();
+ if (inst.input.is(':visible') && !inst.input.is(':disabled'))
+ inst.input.focus();
+ $.datepicker._curInst = inst;
+ }
+ },
+
+ /* Generate the date picker content. */
+ _updateDatepicker: function(inst) {
+ var self = this;
+ self.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
+ var borders = $.datepicker._getBorders(inst.dpDiv);
+ instActive = inst; // for delegate hover events
+ inst.dpDiv.empty().append(this._generateHTML(inst));
+ var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
+ if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
+ cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
+ }
+ inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
+ var numMonths = this._getNumberOfMonths(inst);
+ var cols = numMonths[1];
+ var width = 17;
+ inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
+ if (cols > 1)
+ inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
+ inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
+ 'Class']('ui-datepicker-multi');
+ inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
+ 'Class']('ui-datepicker-rtl');
+ if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
+ // #6694 - don't focus the input if it's already focused
+ // this breaks the change event in IE
+ inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
+ inst.input.focus();
+ // deffered render of the years select (to avoid flashes on Firefox)
+ if( inst.yearshtml ){
+ var origyearshtml = inst.yearshtml;
+ setTimeout(function(){
+ //assure that inst.yearshtml didn't change.
+ if( origyearshtml === inst.yearshtml && inst.yearshtml ){
+ inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
+ }
+ origyearshtml = inst.yearshtml = null;
+ }, 0);
+ }
+ },
+
+ /* Retrieve the size of left and top borders for an element.
+ @param elem (jQuery object) the element of interest
+ @return (number[2]) the left and top borders */
+ _getBorders: function(elem) {
+ var convert = function(value) {
+ return {thin: 1, medium: 2, thick: 3}[value] || value;
+ };
+ return [parseFloat(convert(elem.css('border-left-width'))),
+ parseFloat(convert(elem.css('border-top-width')))];
+ },
+
+ /* Check positioning to remain on screen. */
+ _checkOffset: function(inst, offset, isFixed) {
+ var dpWidth = inst.dpDiv.outerWidth();
+ var dpHeight = inst.dpDiv.outerHeight();
+ var inputWidth = inst.input ? inst.input.outerWidth() : 0;
+ var inputHeight = inst.input ? inst.input.outerHeight() : 0;
+ var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
+ var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
+
+ offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
+ offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
+ offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
+
+ // now check if datepicker is showing outside window viewport - move to a better place if so.
+ offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
+ Math.abs(offset.left + dpWidth - viewWidth) : 0);
+ offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
+ Math.abs(dpHeight + inputHeight) : 0);
+
+ return offset;
+ },
+
+ /* Find an object's position on the screen. */
+ _findPos: function(obj) {
+ var inst = this._getInst(obj);
+ var isRTL = this._get(inst, 'isRTL');
+ while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
+ obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
+ }
+ var position = $(obj).offset();
+ return [position.left, position.top];
+ },
+
+ /* Trigger custom callback of onClose. */
+ _triggerOnClose: function(inst) {
+ var onClose = this._get(inst, 'onClose');
+ if (onClose)
+ onClose.apply((inst.input ? inst.input[0] : null),
+ [(inst.input ? inst.input.val() : ''), inst]);
+ },
+
+ /* Hide the date picker from view.
+ @param input element - the input field attached to the date picker */
+ _hideDatepicker: function(input) {
+ var inst = this._curInst;
+ if (!inst || (input && inst != $.data(input, PROP_NAME)))
+ return;
+ if (this._datepickerShowing) {
+ var showAnim = this._get(inst, 'showAnim');
+ var duration = this._get(inst, 'duration');
+ var postProcess = function() {
+ $.datepicker._tidyDialog(inst);
+ this._curInst = null;
+ };
+ if ($.effects && $.effects[showAnim])
+ inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
+ else
+ inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
+ (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
+ if (!showAnim)
+ postProcess();
+ $.datepicker._triggerOnClose(inst);
+ this._datepickerShowing = false;
+ this._lastInput = null;
+ if (this._inDialog) {
+ this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
+ if ($.blockUI) {
+ $.unblockUI();
+ $('body').append(this.dpDiv);
+ }
+ }
+ this._inDialog = false;
+ }
+ },
+
+ /* Tidy up after a dialog display. */
+ _tidyDialog: function(inst) {
+ inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
+ },
+
+ /* Close date picker if clicked elsewhere. */
+ _checkExternalClick: function(event) {
+ if (!$.datepicker._curInst)
+ return;
+ var $target = $(event.target);
+ if ($target[0].id != $.datepicker._mainDivId &&
+ $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
+ !$target.hasClass($.datepicker.markerClassName) &&
+ !$target.hasClass($.datepicker._triggerClass) &&
+ $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
+ $.datepicker._hideDatepicker();
+ },
+
+ /* Adjust one of the date sub-fields. */
+ _adjustDate: function(id, offset, period) {
+ var target = $(id);
+ var inst = this._getInst(target[0]);
+ if (this._isDisabledDatepicker(target[0])) {
+ return;
+ }
+ this._adjustInstDate(inst, offset +
+ (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
+ period);
+ this._updateDatepicker(inst);
+ },
+
+ /* Action for current link. */
+ _gotoToday: function(id) {
+ var target = $(id);
+ var inst = this._getInst(target[0]);
+ if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
+ inst.selectedDay = inst.currentDay;
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth;
+ inst.drawYear = inst.selectedYear = inst.currentYear;
+ }
+ else {
+ var date = new Date();
+ inst.selectedDay = date.getDate();
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
+ inst.drawYear = inst.selectedYear = date.getFullYear();
+ }
+ this._notifyChange(inst);
+ this._adjustDate(target);
+ },
+
+ /* Action for selecting a new month/year. */
+ _selectMonthYear: function(id, select, period) {
+ var target = $(id);
+ var inst = this._getInst(target[0]);
+ inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
+ inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
+ parseInt(select.options[select.selectedIndex].value,10);
+ this._notifyChange(inst);
+ this._adjustDate(target);
+ },
+
+ /* Action for selecting a day. */
+ _selectDay: function(id, month, year, td) {
+ var target = $(id);
+ if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
+ return;
+ }
+ var inst = this._getInst(target[0]);
+ inst.selectedDay = inst.currentDay = $('a', td).html();
+ inst.selectedMonth = inst.currentMonth = month;
+ inst.selectedYear = inst.currentYear = year;
+ this._selectDate(id, this._formatDate(inst,
+ inst.currentDay, inst.currentMonth, inst.currentYear));
+ },
+
+ /* Erase the input field and hide the date picker. */
+ _clearDate: function(id) {
+ var target = $(id);
+ var inst = this._getInst(target[0]);
+ this._selectDate(target, '');
+ },
+
+ /* Update the input field with the selected date. */
+ _selectDate: function(id, dateStr) {
+ var target = $(id);
+ var inst = this._getInst(target[0]);
+ dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
+ if (inst.input)
+ inst.input.val(dateStr);
+ this._updateAlternate(inst);
+ var onSelect = this._get(inst, 'onSelect');
+ if (onSelect)
+ onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
+ else if (inst.input)
+ inst.input.trigger('change'); // fire the change event
+ if (inst.inline)
+ this._updateDatepicker(inst);
+ else {
+ this._hideDatepicker();
+ this._lastInput = inst.input[0];
+ if (typeof(inst.input[0]) != 'object')
+ inst.input.focus(); // restore focus
+ this._lastInput = null;
+ }
+ },
+
+ /* Update any alternate field to synchronise with the main field. */
+ _updateAlternate: function(inst) {
+ var altField = this._get(inst, 'altField');
+ if (altField) { // update alternate field too
+ var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
+ var date = this._getDate(inst);
+ var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
+ $(altField).each(function() { $(this).val(dateStr); });
+ }
+ },
+
+ /* Set as beforeShowDay function to prevent selection of weekends.
+ @param date Date - the date to customise
+ @return [boolean, string] - is this date selectable?, what is its CSS class? */
+ noWeekends: function(date) {
+ var day = date.getDay();
+ return [(day > 0 && day < 6), ''];
+ },
+
+ /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
+ @param date Date - the date to get the week for
+ @return number - the number of the week within the year that contains this date */
+ iso8601Week: function(date) {
+ var checkDate = new Date(date.getTime());
+ // Find Thursday of this week starting on Monday
+ checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
+ var time = checkDate.getTime();
+ checkDate.setMonth(0); // Compare with Jan 1
+ checkDate.setDate(1);
+ return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
+ },
+
+ /* Parse a string value into a date object.
+ See formatDate below for the possible formats.
+
+ @param format string - the expected format of the date
+ @param value string - the date in the above format
+ @param settings Object - attributes include:
+ shortYearCutoff number - the cutoff year for determining the century (optional)
+ dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
+ dayNames string[7] - names of the days from Sunday (optional)
+ monthNamesShort string[12] - abbreviated names of the months (optional)
+ monthNames string[12] - names of the months (optional)
+ @return Date - the extracted date value or null if value is blank */
+ parseDate: function (format, value, settings) {
+ if (format == null || value == null)
+ throw 'Invalid arguments';
+ value = (typeof value == 'object' ? value.toString() : value + '');
+ if (value == '')
+ return null;
+ var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
+ shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
+ new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
+ var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
+ var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
+ var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
+ var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
+ var year = -1;
+ var month = -1;
+ var day = -1;
+ var doy = -1;
+ var literal = false;
+ // Check whether a format character is doubled
+ var lookAhead = function(match) {
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
+ if (matches)
+ iFormat++;
+ return matches;
+ };
+ // Extract a number from the string value
+ var getNumber = function(match) {
+ var isDoubled = lookAhead(match);
+ var size = (match == '@' ? 14 : (match == '!' ? 20 :
+ (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
+ var digits = new RegExp('^\\d{1,' + size + '}');
+ var num = value.substring(iValue).match(digits);
+ if (!num)
+ throw 'Missing number at position ' + iValue;
+ iValue += num[0].length;
+ return parseInt(num[0], 10);
+ };
+ // Extract a name from the string value and convert to an index
+ var getName = function(match, shortNames, longNames) {
+ var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
+ return [ [k, v] ];
+ }).sort(function (a, b) {
+ return -(a[1].length - b[1].length);
+ });
+ var index = -1;
+ $.each(names, function (i, pair) {
+ var name = pair[1];
+ if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
+ index = pair[0];
+ iValue += name.length;
+ return false;
+ }
+ });
+ if (index != -1)
+ return index + 1;
+ else
+ throw 'Unknown name at position ' + iValue;
+ };
+ // Confirm that a literal character matches the string value
+ var checkLiteral = function() {
+ if (value.charAt(iValue) != format.charAt(iFormat))
+ throw 'Unexpected literal at position ' + iValue;
+ iValue++;
+ };
+ var iValue = 0;
+ for (var iFormat = 0; iFormat < format.length; iFormat++) {
+ if (literal)
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
+ literal = false;
+ else
+ checkLiteral();
+ else
+ switch (format.charAt(iFormat)) {
+ case 'd':
+ day = getNumber('d');
+ break;
+ case 'D':
+ getName('D', dayNamesShort, dayNames);
+ break;
+ case 'o':
+ doy = getNumber('o');
+ break;
+ case 'm':
+ month = getNumber('m');
+ break;
+ case 'M':
+ month = getName('M', monthNamesShort, monthNames);
+ break;
+ case 'y':
+ year = getNumber('y');
+ break;
+ case '@':
+ var date = new Date(getNumber('@'));
+ year = date.getFullYear();
+ month = date.getMonth() + 1;
+ day = date.getDate();
+ break;
+ case '!':
+ var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
+ year = date.getFullYear();
+ month = date.getMonth() + 1;
+ day = date.getDate();
+ break;
+ case "'":
+ if (lookAhead("'"))
+ checkLiteral();
+ else
+ literal = true;
+ break;
+ default:
+ checkLiteral();
+ }
+ }
+ if (iValue < value.length){
+ throw "Extra/unparsed characters found in date: " + value.substring(iValue);
+ }
+ if (year == -1)
+ year = new Date().getFullYear();
+ else if (year < 100)
+ year += new Date().getFullYear() - new Date().getFullYear() % 100 +
+ (year <= shortYearCutoff ? 0 : -100);
+ if (doy > -1) {
+ month = 1;
+ day = doy;
+ do {
+ var dim = this._getDaysInMonth(year, month - 1);
+ if (day <= dim)
+ break;
+ month++;
+ day -= dim;
+ } while (true);
+ }
+ var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
+ if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
+ throw 'Invalid date'; // E.g. 31/02/00
+ return date;
+ },
+
+ /* Standard date formats. */
+ ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
+ COOKIE: 'D, dd M yy',
+ ISO_8601: 'yy-mm-dd',
+ RFC_822: 'D, d M y',
+ RFC_850: 'DD, dd-M-y',
+ RFC_1036: 'D, d M y',
+ RFC_1123: 'D, d M yy',
+ RFC_2822: 'D, d M yy',
+ RSS: 'D, d M y', // RFC 822
+ TICKS: '!',
+ TIMESTAMP: '@',
+ W3C: 'yy-mm-dd', // ISO 8601
+
+ _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
+ Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
+
+ /* Format a date object into a string value.
+ The format can be combinations of the following:
+ d - day of month (no leading zero)
+ dd - day of month (two digit)
+ o - day of year (no leading zeros)
+ oo - day of year (three digit)
+ D - day name short
+ DD - day name long
+ m - month of year (no leading zero)
+ mm - month of year (two digit)
+ M - month name short
+ MM - month name long
+ y - year (two digit)
+ yy - year (four digit)
+ @ - Unix timestamp (ms since 01/01/1970)
+ ! - Windows ticks (100ns since 01/01/0001)
+ '...' - literal text
+ '' - single quote
+
+ @param format string - the desired format of the date
+ @param date Date - the date value to format
+ @param settings Object - attributes include:
+ dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
+ dayNames string[7] - names of the days from Sunday (optional)
+ monthNamesShort string[12] - abbreviated names of the months (optional)
+ monthNames string[12] - names of the months (optional)
+ @return string - the date in the above format */
+ formatDate: function (format, date, settings) {
+ if (!date)
+ return '';
+ var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
+ var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
+ var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
+ var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
+ // Check whether a format character is doubled
+ var lookAhead = function(match) {
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
+ if (matches)
+ iFormat++;
+ return matches;
+ };
+ // Format a number, with leading zero if necessary
+ var formatNumber = function(match, value, len) {
+ var num = '' + value;
+ if (lookAhead(match))
+ while (num.length < len)
+ num = '0' + num;
+ return num;
+ };
+ // Format a name, short or long as requested
+ var formatName = function(match, value, shortNames, longNames) {
+ return (lookAhead(match) ? longNames[value] : shortNames[value]);
+ };
+ var output = '';
+ var literal = false;
+ if (date)
+ for (var iFormat = 0; iFormat < format.length; iFormat++) {
+ if (literal)
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
+ literal = false;
+ else
+ output += format.charAt(iFormat);
+ else
+ switch (format.charAt(iFormat)) {
+ case 'd':
+ output += formatNumber('d', date.getDate(), 2);
+ break;
+ case 'D':
+ output += formatName('D', date.getDay(), dayNamesShort, dayNames);
+ break;
+ case 'o':
+ output += formatNumber('o',
+ Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
+ break;
+ case 'm':
+ output += formatNumber('m', date.getMonth() + 1, 2);
+ break;
+ case 'M':
+ output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
+ break;
+ case 'y':
+ output += (lookAhead('y') ? date.getFullYear() :
+ (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
+ break;
+ case '@':
+ output += date.getTime();
+ break;
+ case '!':
+ output += date.getTime() * 10000 + this._ticksTo1970;
+ break;
+ case "'":
+ if (lookAhead("'"))
+ output += "'";
+ else
+ literal = true;
+ break;
+ default:
+ output += format.charAt(iFormat);
+ }
+ }
+ return output;
+ },
+
+ /* Extract all possible characters from the date format. */
+ _possibleChars: function (format) {
+ var chars = '';
+ var literal = false;
+ // Check whether a format character is doubled
+ var lookAhead = function(match) {
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
+ if (matches)
+ iFormat++;
+ return matches;
+ };
+ for (var iFormat = 0; iFormat < format.length; iFormat++)
+ if (literal)
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
+ literal = false;
+ else
+ chars += format.charAt(iFormat);
+ else
+ switch (format.charAt(iFormat)) {
+ case 'd': case 'm': case 'y': case '@':
+ chars += '0123456789';
+ break;
+ case 'D': case 'M':
+ return null; // Accept anything
+ case "'":
+ if (lookAhead("'"))
+ chars += "'";
+ else
+ literal = true;
+ break;
+ default:
+ chars += format.charAt(iFormat);
+ }
+ return chars;
+ },
+
+ /* Get a setting value, defaulting if necessary. */
+ _get: function(inst, name) {
+ return inst.settings[name] !== undefined ?
+ inst.settings[name] : this._defaults[name];
+ },
+
+ /* Parse existing date and initialise date picker. */
+ _setDateFromField: function(inst, noDefault) {
+ if (inst.input.val() == inst.lastVal) {
+ return;
+ }
+ var dateFormat = this._get(inst, 'dateFormat');
+ var dates = inst.lastVal = inst.input ? inst.input.val() : null;
+ var date, defaultDate;
+ date = defaultDate = this._getDefaultDate(inst);
+ var settings = this._getFormatConfig(inst);
+ try {
+ date = this.parseDate(dateFormat, dates, settings) || defaultDate;
+ } catch (event) {
+ this.log(event);
+ dates = (noDefault ? '' : dates);
+ }
+ inst.selectedDay = date.getDate();
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
+ inst.drawYear = inst.selectedYear = date.getFullYear();
+ inst.currentDay = (dates ? date.getDate() : 0);
+ inst.currentMonth = (dates ? date.getMonth() : 0);
+ inst.currentYear = (dates ? date.getFullYear() : 0);
+ this._adjustInstDate(inst);
+ },
+
+ /* Retrieve the default date shown on opening. */
+ _getDefaultDate: function(inst) {
+ return this._restrictMinMax(inst,
+ this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
+ },
+
+ /* A date may be specified as an exact value or a relative one. */
+ _determineDate: function(inst, date, defaultDate) {
+ var offsetNumeric = function(offset) {
+ var date = new Date();
+ date.setDate(date.getDate() + offset);
+ return date;
+ };
+ var offsetString = function(offset) {
+ try {
+ return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
+ offset, $.datepicker._getFormatConfig(inst));
+ }
+ catch (e) {
+ // Ignore
+ }
+ var date = (offset.toLowerCase().match(/^c/) ?
+ $.datepicker._getDate(inst) : null) || new Date();
+ var year = date.getFullYear();
+ var month = date.getMonth();
+ var day = date.getDate();
+ var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
+ var matches = pattern.exec(offset);
+ while (matches) {
+ switch (matches[2] || 'd') {
+ case 'd' : case 'D' :
+ day += parseInt(matches[1],10); break;
+ case 'w' : case 'W' :
+ day += parseInt(matches[1],10) * 7; break;
+ case 'm' : case 'M' :
+ month += parseInt(matches[1],10);
+ day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
+ break;
+ case 'y': case 'Y' :
+ year += parseInt(matches[1],10);
+ day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
+ break;
+ }
+ matches = pattern.exec(offset);
+ }
+ return new Date(year, month, day);
+ };
+ var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
+ (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
+ newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
+ if (newDate) {
+ newDate.setHours(0);
+ newDate.setMinutes(0);
+ newDate.setSeconds(0);
+ newDate.setMilliseconds(0);
+ }
+ return this._daylightSavingAdjust(newDate);
+ },
+
+ /* Handle switch to/from daylight saving.
+ Hours may be non-zero on daylight saving cut-over:
+ > 12 when midnight changeover, but then cannot generate
+ midnight datetime, so jump to 1AM, otherwise reset.
+ @param date (Date) the date to check
+ @return (Date) the corrected date */
+ _daylightSavingAdjust: function(date) {
+ if (!date) return null;
+ date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
+ return date;
+ },
+
+ /* Set the date(s) directly. */
+ _setDate: function(inst, date, noChange) {
+ var clear = !date;
+ var origMonth = inst.selectedMonth;
+ var origYear = inst.selectedYear;
+ var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
+ inst.selectedDay = inst.currentDay = newDate.getDate();
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
+ inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
+ if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
+ this._notifyChange(inst);
+ this._adjustInstDate(inst);
+ if (inst.input) {
+ inst.input.val(clear ? '' : this._formatDate(inst));
+ }
+ },
+
+ /* Retrieve the date(s) directly. */
+ _getDate: function(inst) {
+ var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
+ this._daylightSavingAdjust(new Date(
+ inst.currentYear, inst.currentMonth, inst.currentDay)));
+ return startDate;
+ },
+
+ /* Generate the HTML for the current state of the date picker. */
+ _generateHTML: function(inst) {
+ var today = new Date();
+ today = this._daylightSavingAdjust(
+ new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
+ var isRTL = this._get(inst, 'isRTL');
+ var showButtonPanel = this._get(inst, 'showButtonPanel');
+ var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
+ var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
+ var numMonths = this._getNumberOfMonths(inst);
+ var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
+ var stepMonths = this._get(inst, 'stepMonths');
+ var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
+ var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
+ var minDate = this._getMinMaxDate(inst, 'min');
+ var maxDate = this._getMinMaxDate(inst, 'max');
+ var drawMonth = inst.drawMonth - showCurrentAtPos;
+ var drawYear = inst.drawYear;
+ if (drawMonth < 0) {
+ drawMonth += 12;
+ drawYear--;
+ }
+ if (maxDate) {
+ var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
+ maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
+ maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
+ while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
+ drawMonth--;
+ if (drawMonth < 0) {
+ drawMonth = 11;
+ drawYear--;
+ }
+ }
+ }
+ inst.drawMonth = drawMonth;
+ inst.drawYear = drawYear;
+ var prevText = this._get(inst, 'prevText');
+ prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
+ this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
+ this._getFormatConfig(inst)));
+ var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
+ '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
+ '.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
+ ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
+ (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
+ var nextText = this._get(inst, 'nextText');
+ nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
+ this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
+ this._getFormatConfig(inst)));
+ var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
+ '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
+ '.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
+ ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
+ (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
+ var currentText = this._get(inst, 'currentText');
+ var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
+ currentText = (!navigationAsDateFormat ? currentText :
+ this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
+ var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
+ '.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
+ var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
+ (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
+ '.datepicker._gotoToday(\'#' + inst.id + '\');"' +
+ '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
+ var firstDay = parseInt(this._get(inst, 'firstDay'),10);
+ firstDay = (isNaN(firstDay) ? 0 : firstDay);
+ var showWeek = this._get(inst, 'showWeek');
+ var dayNames = this._get(inst, 'dayNames');
+ var dayNamesShort = this._get(inst, 'dayNamesShort');
+ var dayNamesMin = this._get(inst, 'dayNamesMin');
+ var monthNames = this._get(inst, 'monthNames');
+ var monthNamesShort = this._get(inst, 'monthNamesShort');
+ var beforeShowDay = this._get(inst, 'beforeShowDay');
+ var showOtherMonths = this._get(inst, 'showOtherMonths');
+ var selectOtherMonths = this._get(inst, 'selectOtherMonths');
+ var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
+ var defaultDate = this._getDefaultDate(inst);
+ var html = '';
+ for (var row = 0; row < numMonths[0]; row++) {
+ var group = '';
+ this.maxRows = 4;
+ for (var col = 0; col < numMonths[1]; col++) {
+ var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
+ var cornerClass = ' ui-corner-all';
+ var calender = '';
+ if (isMultiMonth) {
+ calender += '<div class="ui-datepicker-group';
+ if (numMonths[1] > 1)
+ switch (col) {
+ case 0: calender += ' ui-datepicker-group-first';
+ cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
+ case numMonths[1]-1: calender += ' ui-datepicker-group-last';
+ cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
+ default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
+ }
+ calender += '">';
+ }
+ calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
+ (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
+ (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
+ this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
+ row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
+ '</div><table class="ui-datepicker-calendar"><thead>' +
+ '<tr>';
+ var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
+ for (var dow = 0; dow < 7; dow++) { // days of the week
+ var day = (dow + firstDay) % 7;
+ thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
+ '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
+ }
+ calender += thead + '</tr></thead><tbody>';
+ var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
+ if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
+ inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
+ var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
+ var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
+ var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
+ this.maxRows = numRows;
+ var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
+ for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
+ calender += '<tr>';
+ var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
+ this._get(inst, 'calculateWeek')(printDate) + '</td>');
+ for (var dow = 0; dow < 7; dow++) { // create date picker days
+ var daySettings = (beforeShowDay ?
+ beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
+ var otherMonth = (printDate.getMonth() != drawMonth);
+ var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
+ (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
+ tbody += '<td class="' +
+ ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
+ (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
+ ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
+ (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
+ // or defaultDate is current printedDate and defaultDate is selectedDate
+ ' ' + this._dayOverClass : '') + // highlight selected day
+ (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days
+ (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
+ (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
+ (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
+ ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
+ (unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
+ inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
+ (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
+ (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
+ (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
+ (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
+ (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
+ '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
+ printDate.setDate(printDate.getDate() + 1);
+ printDate = this._daylightSavingAdjust(printDate);
+ }
+ calender += tbody + '</tr>';
+ }
+ drawMonth++;
+ if (drawMonth > 11) {
+ drawMonth = 0;
+ drawYear++;
+ }
+ calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
+ ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
+ group += calender;
+ }
+ html += group;
+ }
+ html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
+ '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
+ inst._keyEvent = false;
+ return html;
+ },
+
+ /* Generate the month and year header. */
+ _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
+ secondary, monthNames, monthNamesShort) {
+ var changeMonth = this._get(inst, 'changeMonth');
+ var changeYear = this._get(inst, 'changeYear');
+ var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
+ var html = '<div class="ui-datepicker-title">';
+ var monthHtml = '';
+ // month selection
+ if (secondary || !changeMonth)
+ monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
+ else {
+ var inMinYear = (minDate && minDate.getFullYear() == drawYear);
+ var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
+ monthHtml += '<select class="ui-datepicker-month" ' +
+ 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
+ '>';
+ for (var month = 0; month < 12; month++) {
+ if ((!inMinYear || month >= minDate.getMonth()) &&
+ (!inMaxYear || month <= maxDate.getMonth()))
+ monthHtml += '<option value="' + month + '"' +
+ (month == drawMonth ? ' selected="selected"' : '') +
+ '>' + monthNamesShort[month] + '</option>';
+ }
+ monthHtml += '</select>';
+ }
+ if (!showMonthAfterYear)
+ html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
+ // year selection
+ if ( !inst.yearshtml ) {
+ inst.yearshtml = '';
+ if (secondary || !changeYear)
+ html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
+ else {
+ // determine range of years to display
+ var years = this._get(inst, 'yearRange').split(':');
+ var thisYear = new Date().getFullYear();
+ var determineYear = function(value) {
+ var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
+ (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
+ parseInt(value, 10)));
+ return (isNaN(year) ? thisYear : year);
+ };
+ var year = determineYear(years[0]);
+ var endYear = Math.max(year, determineYear(years[1] || ''));
+ year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
+ endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
+ inst.yearshtml += '<select class="ui-datepicker-year" ' +
+ 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
+ '>';
+ for (; year <= endYear; year++) {
+ inst.yearshtml += '<option value="' + year + '"' +
+ (year == drawYear ? ' selected="selected"' : '') +
+ '>' + year + '</option>';
+ }
+ inst.yearshtml += '</select>';
+
+ html += inst.yearshtml;
+ inst.yearshtml = null;
+ }
+ }
+ html += this._get(inst, 'yearSuffix');
+ if (showMonthAfterYear)
+ html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
+ html += '</div>'; // Close datepicker_header
+ return html;
+ },
+
+ /* Adjust one of the date sub-fields. */
+ _adjustInstDate: function(inst, offset, period) {
+ var year = inst.drawYear + (period == 'Y' ? offset : 0);
+ var month = inst.drawMonth + (period == 'M' ? offset : 0);
+ var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
+ (period == 'D' ? offset : 0);
+ var date = this._restrictMinMax(inst,
+ this._daylightSavingAdjust(new Date(year, month, day)));
+ inst.selectedDay = date.getDate();
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
+ inst.drawYear = inst.selectedYear = date.getFullYear();
+ if (period == 'M' || period == 'Y')
+ this._notifyChange(inst);
+ },
+
+ /* Ensure a date is within any min/max bounds. */
+ _restrictMinMax: function(inst, date) {
+ var minDate = this._getMinMaxDate(inst, 'min');
+ var maxDate = this._getMinMaxDate(inst, 'max');
+ var newDate = (minDate && date < minDate ? minDate : date);
+ newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
+ return newDate;
+ },
+
+ /* Notify change of month/year. */
+ _notifyChange: function(inst) {
+ var onChange = this._get(inst, 'onChangeMonthYear');
+ if (onChange)
+ onChange.apply((inst.input ? inst.input[0] : null),
+ [inst.selectedYear, inst.selectedMonth + 1, inst]);
+ },
+
+ /* Determine the number of months to show. */
+ _getNumberOfMonths: function(inst) {
+ var numMonths = this._get(inst, 'numberOfMonths');
+ return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
+ },
+
+ /* Determine the current maximum date - ensure no time components are set. */
+ _getMinMaxDate: function(inst, minMax) {
+ return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
+ },
+
+ /* Find the number of days in a given month. */
+ _getDaysInMonth: function(year, month) {
+ return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
+ },
+
+ /* Find the day of the week of the first of a month. */
+ _getFirstDayOfMonth: function(year, month) {
+ return new Date(year, month, 1).getDay();
+ },
+
+ /* Determines if we should allow a "next/prev" month display change. */
+ _canAdjustMonth: function(inst, offset, curYear, curMonth) {
+ var numMonths = this._getNumberOfMonths(inst);
+ var date = this._daylightSavingAdjust(new Date(curYear,
+ curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
+ if (offset < 0)
+ date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
+ return this._isInRange(inst, date);
+ },
+
+ /* Is the given date in the accepted range? */
+ _isInRange: function(inst, date) {
+ var minDate = this._getMinMaxDate(inst, 'min');
+ var maxDate = this._getMinMaxDate(inst, 'max');
+ return ((!minDate || date.getTime() >= minDate.getTime()) &&
+ (!maxDate || date.getTime() <= maxDate.getTime()));
+ },
+
+ /* Provide the configuration settings for formatting/parsing. */
+ _getFormatConfig: function(inst) {
+ var shortYearCutoff = this._get(inst, 'shortYearCutoff');
+ shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
+ new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
+ return {shortYearCutoff: shortYearCutoff,
+ dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
+ monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
+ },
+
+ /* Format the given date for display. */
+ _formatDate: function(inst, day, month, year) {
+ if (!day) {
+ inst.currentDay = inst.selectedDay;
+ inst.currentMonth = inst.selectedMonth;
+ inst.currentYear = inst.selectedYear;
+ }
+ var date = (day ? (typeof day == 'object' ? day :
+ this._daylightSavingAdjust(new Date(year, month, day))) :
+ this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
+ return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
+ }
+});
+
+/*
+ * Bind hover events for datepicker elements.
+ * Done via delegate so the binding only occurs once in the lifetime of the parent div.
+ * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
+ */
+function bindHover(dpDiv) {
+ var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
+ return dpDiv.bind('mouseout', function(event) {
+ var elem = $( event.target ).closest( selector );
+ if ( !elem.length ) {
+ return;
+ }
+ elem.removeClass( "ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover" );
+ })
+ .bind('mouseover', function(event) {
+ var elem = $( event.target ).closest( selector );
+ if ($.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0]) ||
+ !elem.length ) {
+ return;
+ }
+ elem.parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
+ elem.addClass('ui-state-hover');
+ if (elem.hasClass('ui-datepicker-prev')) elem.addClass('ui-datepicker-prev-hover');
+ if (elem.hasClass('ui-datepicker-next')) elem.addClass('ui-datepicker-next-hover');
+ });
+}
+
+/* jQuery extend now ignores nulls! */
+function extendRemove(target, props) {
+ $.extend(target, props);
+ for (var name in props)
+ if (props[name] == null || props[name] == undefined)
+ target[name] = props[name];
+ return target;
+};
+
+/* Determine whether an object is an array. */
+function isArray(a) {
+ return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
+ (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
+};
+
+/* Invoke the datepicker functionality.
+ @param options string - a command, optionally followed by additional parameters or
+ Object - settings for attaching new datepicker functionality
+ @return jQuery object */
+$.fn.datepicker = function(options){
+
+ /* Verify an empty collection wasn't passed - Fixes #6976 */
+ if ( !this.length ) {
+ return this;
+ }
+
+ /* Initialise the date picker. */
+ if (!$.datepicker.initialized) {
+ $(document).mousedown($.datepicker._checkExternalClick).
+ find('body').append($.datepicker.dpDiv);
+ $.datepicker.initialized = true;
+ }
+
+ var otherArgs = Array.prototype.slice.call(arguments, 1);
+ if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
+ return $.datepicker['_' + options + 'Datepicker'].
+ apply($.datepicker, [this[0]].concat(otherArgs));
+ if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
+ return $.datepicker['_' + options + 'Datepicker'].
+ apply($.datepicker, [this[0]].concat(otherArgs));
+ return this.each(function() {
+ typeof options == 'string' ?
+ $.datepicker['_' + options + 'Datepicker'].
+ apply($.datepicker, [this].concat(otherArgs)) :
+ $.datepicker._attachDatepicker(this, options);
+ });
+};
+
+$.datepicker = new Datepicker(); // singleton instance
+$.datepicker.initialized = false;
+$.datepicker.uuid = new Date().getTime();
+$.datepicker.version = "1.8.16";
+
+// Workaround for #4055
+// Add another global to avoid noConflict issues with inline event handlers
+window['DP_jQuery_' + dpuuid] = $;
+
+})(jQuery);
+/*
+ * jQuery UI Dialog 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ * jquery.ui.button.js
+ * jquery.ui.draggable.js
+ * jquery.ui.mouse.js
+ * jquery.ui.position.js
+ * jquery.ui.resizable.js
+ */
+(function( $, undefined ) {
+
+var uiDialogClasses =
+ 'ui-dialog ' +
+ 'ui-widget ' +
+ 'ui-widget-content ' +
+ 'ui-corner-all ',
+ sizeRelatedOptions = {
+ buttons: true,
+ height: true,
+ maxHeight: true,
+ maxWidth: true,
+ minHeight: true,
+ minWidth: true,
+ width: true
+ },
+ resizableRelatedOptions = {
+ maxHeight: true,
+ maxWidth: true,
+ minHeight: true,
+ minWidth: true
+ },
+ // support for jQuery 1.3.2 - handle common attrFn methods for dialog
+ attrFn = $.attrFn || {
+ val: true,
+ css: true,
+ html: true,
+ text: true,
+ data: true,
+ width: true,
+ height: true,
+ offset: true,
+ click: true
+ };
+
+$.widget("ui.dialog", {
+ options: {
+ autoOpen: true,
+ buttons: {},
+ closeOnEscape: true,
+ closeText: 'close',
+ dialogClass: '',
+ draggable: true,
+ hide: null,
+ height: 'auto',
+ maxHeight: false,
+ maxWidth: false,
+ minHeight: 150,
+ minWidth: 150,
+ modal: false,
+ position: {
+ my: 'center',
+ at: 'center',
+ collision: 'fit',
+ // ensure that the titlebar is never outside the document
+ using: function(pos) {
+ var topOffset = $(this).css(pos).offset().top;
+ if (topOffset < 0) {
+ $(this).css('top', pos.top - topOffset);
+ }
+ }
+ },
+ resizable: true,
+ show: null,
+ stack: true,
+ title: '',
+ width: 300,
+ zIndex: 1000
+ },
+
+ _create: function() {
+ this.originalTitle = this.element.attr('title');
+ // #5742 - .attr() might return a DOMElement
+ if ( typeof this.originalTitle !== "string" ) {
+ this.originalTitle = "";
+ }
+
+ this.options.title = this.options.title || this.originalTitle;
+ var self = this,
+ options = self.options,
+
+ title = options.title || '&#160;',
+ titleId = $.ui.dialog.getTitleId(self.element),
+
+ uiDialog = (self.uiDialog = $('<div></div>'))
+ .appendTo(document.body)
+ .hide()
+ .addClass(uiDialogClasses + options.dialogClass)
+ .css({
+ zIndex: options.zIndex
+ })
+ // setting tabIndex makes the div focusable
+ // setting outline to 0 prevents a border on focus in Mozilla
+ .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
+ if (options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
+ event.keyCode === $.ui.keyCode.ESCAPE) {
+
+ self.close(event);
+ event.preventDefault();
+ }
+ })
+ .attr({
+ role: 'dialog',
+ 'aria-labelledby': titleId
+ })
+ .mousedown(function(event) {
+ self.moveToTop(false, event);
+ }),
+
+ uiDialogContent = self.element
+ .show()
+ .removeAttr('title')
+ .addClass(
+ 'ui-dialog-content ' +
+ 'ui-widget-content')
+ .appendTo(uiDialog),
+
+ uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
+ .addClass(
+ 'ui-dialog-titlebar ' +
+ 'ui-widget-header ' +
+ 'ui-corner-all ' +
+ 'ui-helper-clearfix'
+ )
+ .prependTo(uiDialog),
+
+ uiDialogTitlebarClose = $('<a href="#"></a>')
+ .addClass(
+ 'ui-dialog-titlebar-close ' +
+ 'ui-corner-all'
+ )
+ .attr('role', 'button')
+ .hover(
+ function() {
+ uiDialogTitlebarClose.addClass('ui-state-hover');
+ },
+ function() {
+ uiDialogTitlebarClose.removeClass('ui-state-hover');
+ }
+ )
+ .focus(function() {
+ uiDialogTitlebarClose.addClass('ui-state-focus');
+ })
+ .blur(function() {
+ uiDialogTitlebarClose.removeClass('ui-state-focus');
+ })
+ .click(function(event) {
+ self.close(event);
+ return false;
+ })
+ .appendTo(uiDialogTitlebar),
+
+ uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
+ .addClass(
+ 'ui-icon ' +
+ 'ui-icon-closethick'
+ )
+ .text(options.closeText)
+ .appendTo(uiDialogTitlebarClose),
+
+ uiDialogTitle = $('<span></span>')
+ .addClass('ui-dialog-title')
+ .attr('id', titleId)
+ .html(title)
+ .prependTo(uiDialogTitlebar);
+
+ //handling of deprecated beforeclose (vs beforeClose) option
+ //Ticket #4669 http://dev.jqueryui.com/ticket/4669
+ //TODO: remove in 1.9pre
+ if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
+ options.beforeClose = options.beforeclose;
+ }
+
+ uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
+
+ if (options.draggable && $.fn.draggable) {
+ self._makeDraggable();
+ }
+ if (options.resizable && $.fn.resizable) {
+ self._makeResizable();
+ }
+
+ self._createButtons(options.buttons);
+ self._isOpen = false;
+
+ if ($.fn.bgiframe) {
+ uiDialog.bgiframe();
+ }
+ },
+
+ _init: function() {
+ if ( this.options.autoOpen ) {
+ this.open();
+ }
+ },
+
+ destroy: function() {
+ var self = this;
+
+ if (self.overlay) {
+ self.overlay.destroy();
+ }
+ self.uiDialog.hide();
+ self.element
+ .unbind('.dialog')
+ .removeData('dialog')
+ .removeClass('ui-dialog-content ui-widget-content')
+ .hide().appendTo('body');
+ self.uiDialog.remove();
+
+ if (self.originalTitle) {
+ self.element.attr('title', self.originalTitle);
+ }
+
+ return self;
+ },
+
+ widget: function() {
+ return this.uiDialog;
+ },
+
+ close: function(event) {
+ var self = this,
+ maxZ, thisZ;
+
+ if (false === self._trigger('beforeClose', event)) {
+ return;
+ }
+
+ if (self.overlay) {
+ self.overlay.destroy();
+ }
+ self.uiDialog.unbind('keypress.ui-dialog');
+
+ self._isOpen = false;
+
+ if (self.options.hide) {
+ self.uiDialog.hide(self.options.hide, function() {
+ self._trigger('close', event);
+ });
+ } else {
+ self.uiDialog.hide();
+ self._trigger('close', event);
+ }
+
+ $.ui.dialog.overlay.resize();
+
+ // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
+ if (self.options.modal) {
+ maxZ = 0;
+ $('.ui-dialog').each(function() {
+ if (this !== self.uiDialog[0]) {
+ thisZ = $(this).css('z-index');
+ if(!isNaN(thisZ)) {
+ maxZ = Math.max(maxZ, thisZ);
+ }
+ }
+ });
+ $.ui.dialog.maxZ = maxZ;
+ }
+
+ return self;
+ },
+
+ isOpen: function() {
+ return this._isOpen;
+ },
+
+ // the force parameter allows us to move modal dialogs to their correct
+ // position on open
+ moveToTop: function(force, event) {
+ var self = this,
+ options = self.options,
+ saveScroll;
+
+ if ((options.modal && !force) ||
+ (!options.stack && !options.modal)) {
+ return self._trigger('focus', event);
+ }
+
+ if (options.zIndex > $.ui.dialog.maxZ) {
+ $.ui.dialog.maxZ = options.zIndex;
+ }
+ if (self.overlay) {
+ $.ui.dialog.maxZ += 1;
+ self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
+ }
+
+ //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
+ // http://ui.jquery.com/bugs/ticket/3193
+ saveScroll = { scrollTop: self.element.scrollTop(), scrollLeft: self.element.scrollLeft() };
+ $.ui.dialog.maxZ += 1;
+ self.uiDialog.css('z-index', $.ui.dialog.maxZ);
+ self.element.attr(saveScroll);
+ self._trigger('focus', event);
+
+ return self;
+ },
+
+ open: function() {
+ if (this._isOpen) { return; }
+
+ var self = this,
+ options = self.options,
+ uiDialog = self.uiDialog;
+
+ self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
+ self._size();
+ self._position(options.position);
+ uiDialog.show(options.show);
+ self.moveToTop(true);
+
+ // prevent tabbing out of modal dialogs
+ if (options.modal) {
+ uiDialog.bind('keypress.ui-dialog', function(event) {
+ if (event.keyCode !== $.ui.keyCode.TAB) {
+ return;
+ }
+
+ var tabbables = $(':tabbable', this),
+ first = tabbables.filter(':first'),
+ last = tabbables.filter(':last');
+
+ if (event.target === last[0] && !event.shiftKey) {
+ first.focus(1);
+ return false;
+ } else if (event.target === first[0] && event.shiftKey) {
+ last.focus(1);
+ return false;
+ }
+ });
+ }
+
+ // set focus to the first tabbable element in the content area or the first button
+ // if there are no tabbable elements, set focus on the dialog itself
+ $(self.element.find(':tabbable').get().concat(
+ uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
+ uiDialog.get()))).eq(0).focus();
+
+ self._isOpen = true;
+ self._trigger('open');
+
+ return self;
+ },
+
+ _createButtons: function(buttons) {
+ var self = this,
+ hasButtons = false,
+ uiDialogButtonPane = $('<div></div>')
+ .addClass(
+ 'ui-dialog-buttonpane ' +
+ 'ui-widget-content ' +
+ 'ui-helper-clearfix'
+ ),
+ uiButtonSet = $( "<div></div>" )
+ .addClass( "ui-dialog-buttonset" )
+ .appendTo( uiDialogButtonPane );
+
+ // if we already have a button pane, remove it
+ self.uiDialog.find('.ui-dialog-buttonpane').remove();
+
+ if (typeof buttons === 'object' && buttons !== null) {
+ $.each(buttons, function() {
+ return !(hasButtons = true);
+ });
+ }
+ if (hasButtons) {
+ $.each(buttons, function(name, props) {
+ props = $.isFunction( props ) ?
+ { click: props, text: name } :
+ props;
+ var button = $('<button type="button"></button>')
+ .click(function() {
+ props.click.apply(self.element[0], arguments);
+ })
+ .appendTo(uiButtonSet);
+ // can't use .attr( props, true ) with jQuery 1.3.2.
+ $.each( props, function( key, value ) {
+ if ( key === "click" ) {
+ return;
+ }
+ if ( key in attrFn ) {
+ button[ key ]( value );
+ } else {
+ button.attr( key, value );
+ }
+ });
+ if ($.fn.button) {
+ button.button();
+ }
+ });
+ uiDialogButtonPane.appendTo(self.uiDialog);
+ }
+ },
+
+ _makeDraggable: function() {
+ var self = this,
+ options = self.options,
+ doc = $(document),
+ heightBeforeDrag;
+
+ function filteredUi(ui) {
+ return {
+ position: ui.position,
+ offset: ui.offset
+ };
+ }
+
+ self.uiDialog.draggable({
+ cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
+ handle: '.ui-dialog-titlebar',
+ containment: 'document',
+ start: function(event, ui) {
+ heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
+ $(this).height($(this).height()).addClass("ui-dialog-dragging");
+ self._trigger('dragStart', event, filteredUi(ui));
+ },
+ drag: function(event, ui) {
+ self._trigger('drag', event, filteredUi(ui));
+ },
+ stop: function(event, ui) {
+ options.position = [ui.position.left - doc.scrollLeft(),
+ ui.position.top - doc.scrollTop()];
+ $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
+ self._trigger('dragStop', event, filteredUi(ui));
+ $.ui.dialog.overlay.resize();
+ }
+ });
+ },
+
+ _makeResizable: function(handles) {
+ handles = (handles === undefined ? this.options.resizable : handles);
+ var self = this,
+ options = self.options,
+ // .ui-resizable has position: relative defined in the stylesheet
+ // but dialogs have to use absolute or fixed positioning
+ position = self.uiDialog.css('position'),
+ resizeHandles = (typeof handles === 'string' ?
+ handles :
+ 'n,e,s,w,se,sw,ne,nw'
+ );
+
+ function filteredUi(ui) {
+ return {
+ originalPosition: ui.originalPosition,
+ originalSize: ui.originalSize,
+ position: ui.position,
+ size: ui.size
+ };
+ }
+
+ self.uiDialog.resizable({
+ cancel: '.ui-dialog-content',
+ containment: 'document',
+ alsoResize: self.element,
+ maxWidth: options.maxWidth,
+ maxHeight: options.maxHeight,
+ minWidth: options.minWidth,
+ minHeight: self._minHeight(),
+ handles: resizeHandles,
+ start: function(event, ui) {
+ $(this).addClass("ui-dialog-resizing");
+ self._trigger('resizeStart', event, filteredUi(ui));
+ },
+ resize: function(event, ui) {
+ self._trigger('resize', event, filteredUi(ui));
+ },
+ stop: function(event, ui) {
+ $(this).removeClass("ui-dialog-resizing");
+ options.height = $(this).height();
+ options.width = $(this).width();
+ self._trigger('resizeStop', event, filteredUi(ui));
+ $.ui.dialog.overlay.resize();
+ }
+ })
+ .css('position', position)
+ .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
+ },
+
+ _minHeight: function() {
+ var options = this.options;
+
+ if (options.height === 'auto') {
+ return options.minHeight;
+ } else {
+ return Math.min(options.minHeight, options.height);
+ }
+ },
+
+ _position: function(position) {
+ var myAt = [],
+ offset = [0, 0],
+ isVisible;
+
+ if (position) {
+ // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
+ // if (typeof position == 'string' || $.isArray(position)) {
+ // myAt = $.isArray(position) ? position : position.split(' ');
+
+ if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
+ myAt = position.split ? position.split(' ') : [position[0], position[1]];
+ if (myAt.length === 1) {
+ myAt[1] = myAt[0];
+ }
+
+ $.each(['left', 'top'], function(i, offsetPosition) {
+ if (+myAt[i] === myAt[i]) {
+ offset[i] = myAt[i];
+ myAt[i] = offsetPosition;
+ }
+ });
+
+ position = {
+ my: myAt.join(" "),
+ at: myAt.join(" "),
+ offset: offset.join(" ")
+ };
+ }
+
+ position = $.extend({}, $.ui.dialog.prototype.options.position, position);
+ } else {
+ position = $.ui.dialog.prototype.options.position;
+ }
+
+ // need to show the dialog to get the actual offset in the position plugin
+ isVisible = this.uiDialog.is(':visible');
+ if (!isVisible) {
+ this.uiDialog.show();
+ }
+ this.uiDialog
+ // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
+ .css({ top: 0, left: 0 })
+ .position($.extend({ of: window }, position));
+ if (!isVisible) {
+ this.uiDialog.hide();
+ }
+ },
+
+ _setOptions: function( options ) {
+ var self = this,
+ resizableOptions = {},
+ resize = false;
+
+ $.each( options, function( key, value ) {
+ self._setOption( key, value );
+
+ if ( key in sizeRelatedOptions ) {
+ resize = true;
+ }
+ if ( key in resizableRelatedOptions ) {
+ resizableOptions[ key ] = value;
+ }
+ });
+
+ if ( resize ) {
+ this._size();
+ }
+ if ( this.uiDialog.is( ":data(resizable)" ) ) {
+ this.uiDialog.resizable( "option", resizableOptions );
+ }
+ },
+
+ _setOption: function(key, value){
+ var self = this,
+ uiDialog = self.uiDialog;
+
+ switch (key) {
+ //handling of deprecated beforeclose (vs beforeClose) option
+ //Ticket #4669 http://dev.jqueryui.com/ticket/4669
+ //TODO: remove in 1.9pre
+ case "beforeclose":
+ key = "beforeClose";
+ break;
+ case "buttons":
+ self._createButtons(value);
+ break;
+ case "closeText":
+ // ensure that we always pass a string
+ self.uiDialogTitlebarCloseText.text("" + value);
+ break;
+ case "dialogClass":
+ uiDialog
+ .removeClass(self.options.dialogClass)
+ .addClass(uiDialogClasses + value);
+ break;
+ case "disabled":
+ if (value) {
+ uiDialog.addClass('ui-dialog-disabled');
+ } else {
+ uiDialog.removeClass('ui-dialog-disabled');
+ }
+ break;
+ case "draggable":
+ var isDraggable = uiDialog.is( ":data(draggable)" );
+ if ( isDraggable && !value ) {
+ uiDialog.draggable( "destroy" );
+ }
+
+ if ( !isDraggable && value ) {
+ self._makeDraggable();
+ }
+ break;
+ case "position":
+ self._position(value);
+ break;
+ case "resizable":
+ // currently resizable, becoming non-resizable
+ var isResizable = uiDialog.is( ":data(resizable)" );
+ if (isResizable && !value) {
+ uiDialog.resizable('destroy');
+ }
+
+ // currently resizable, changing handles
+ if (isResizable && typeof value === 'string') {
+ uiDialog.resizable('option', 'handles', value);
+ }
+
+ // currently non-resizable, becoming resizable
+ if (!isResizable && value !== false) {
+ self._makeResizable(value);
+ }
+ break;
+ case "title":
+ // convert whatever was passed in o a string, for html() to not throw up
+ $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
+ break;
+ }
+
+ $.Widget.prototype._setOption.apply(self, arguments);
+ },
+
+ _size: function() {
+ /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
+ * divs will both have width and height set, so we need to reset them
+ */
+ var options = this.options,
+ nonContentHeight,
+ minContentHeight,
+ isVisible = this.uiDialog.is( ":visible" );
+
+ // reset content sizing
+ this.element.show().css({
+ width: 'auto',
+ minHeight: 0,
+ height: 0
+ });
+
+ if (options.minWidth > options.width) {
+ options.width = options.minWidth;
+ }
+
+ // reset wrapper sizing
+ // determine the height of all the non-content elements
+ nonContentHeight = this.uiDialog.css({
+ height: 'auto',
+ width: options.width
+ })
+ .height();
+ minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
+
+ if ( options.height === "auto" ) {
+ // only needed for IE6 support
+ if ( $.support.minHeight ) {
+ this.element.css({
+ minHeight: minContentHeight,
+ height: "auto"
+ });
+ } else {
+ this.uiDialog.show();
+ var autoHeight = this.element.css( "height", "auto" ).height();
+ if ( !isVisible ) {
+ this.uiDialog.hide();
+ }
+ this.element.height( Math.max( autoHeight, minContentHeight ) );
+ }
+ } else {
+ this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
+ }
+
+ if (this.uiDialog.is(':data(resizable)')) {
+ this.uiDialog.resizable('option', 'minHeight', this._minHeight());
+ }
+ }
+});
+
+$.extend($.ui.dialog, {
+ version: "1.8.16",
+
+ uuid: 0,
+ maxZ: 0,
+
+ getTitleId: function($el) {
+ var id = $el.attr('id');
+ if (!id) {
+ this.uuid += 1;
+ id = this.uuid;
+ }
+ return 'ui-dialog-title-' + id;
+ },
+
+ overlay: function(dialog) {
+ this.$el = $.ui.dialog.overlay.create(dialog);
+ }
+});
+
+$.extend($.ui.dialog.overlay, {
+ instances: [],
+ // reuse old instances due to IE memory leak with alpha transparency (see #5185)
+ oldInstances: [],
+ maxZ: 0,
+ events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
+ function(event) { return event + '.dialog-overlay'; }).join(' '),
+ create: function(dialog) {
+ if (this.instances.length === 0) {
+ // prevent use of anchors and inputs
+ // we use a setTimeout in case the overlay is created from an
+ // event that we're going to be cancelling (see #2804)
+ setTimeout(function() {
+ // handle $(el).dialog().dialog('close') (see #4065)
+ if ($.ui.dialog.overlay.instances.length) {
+ $(document).bind($.ui.dialog.overlay.events, function(event) {
+ // stop events if the z-index of the target is < the z-index of the overlay
+ // we cannot return true when we don't want to cancel the event (#3523)
+ if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
+ return false;
+ }
+ });
+ }
+ }, 1);
+
+ // allow closing by pressing the escape key
+ $(document).bind('keydown.dialog-overlay', function(event) {
+ if (dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
+ event.keyCode === $.ui.keyCode.ESCAPE) {
+
+ dialog.close(event);
+ event.preventDefault();
+ }
+ });
+
+ // handle window resize
+ $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
+ }
+
+ var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
+ .appendTo(document.body)
+ .css({
+ width: this.width(),
+ height: this.height()
+ });
+
+ if ($.fn.bgiframe) {
+ $el.bgiframe();
+ }
+
+ this.instances.push($el);
+ return $el;
+ },
+
+ destroy: function($el) {
+ var indexOf = $.inArray($el, this.instances);
+ if (indexOf != -1){
+ this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
+ }
+
+ if (this.instances.length === 0) {
+ $([document, window]).unbind('.dialog-overlay');
+ }
+
+ $el.remove();
+
+ // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
+ var maxZ = 0;
+ $.each(this.instances, function() {
+ maxZ = Math.max(maxZ, this.css('z-index'));
+ });
+ this.maxZ = maxZ;
+ },
+
+ height: function() {
+ var scrollHeight,
+ offsetHeight;
+ // handle IE 6
+ if ($.browser.msie && $.browser.version < 7) {
+ scrollHeight = Math.max(
+ document.documentElement.scrollHeight,
+ document.body.scrollHeight
+ );
+ offsetHeight = Math.max(
+ document.documentElement.offsetHeight,
+ document.body.offsetHeight
+ );
+
+ if (scrollHeight < offsetHeight) {
+ return $(window).height() + 'px';
+ } else {
+ return scrollHeight + 'px';
+ }
+ // handle "good" browsers
+ } else {
+ return $(document).height() + 'px';
+ }
+ },
+
+ width: function() {
+ var scrollWidth,
+ offsetWidth;
+ // handle IE
+ if ( $.browser.msie ) {
+ scrollWidth = Math.max(
+ document.documentElement.scrollWidth,
+ document.body.scrollWidth
+ );
+ offsetWidth = Math.max(
+ document.documentElement.offsetWidth,
+ document.body.offsetWidth
+ );
+
+ if (scrollWidth < offsetWidth) {
+ return $(window).width() + 'px';
+ } else {
+ return scrollWidth + 'px';
+ }
+ // handle "good" browsers
+ } else {
+ return $(document).width() + 'px';
+ }
+ },
+
+ resize: function() {
+ /* If the dialog is draggable and the user drags it past the
+ * right edge of the window, the document becomes wider so we
+ * need to stretch the overlay. If the user then drags the
+ * dialog back to the left, the document will become narrower,
+ * so we need to shrink the overlay to the appropriate size.
+ * This is handled by shrinking the overlay before setting it
+ * to the full document size.
+ */
+ var $overlays = $([]);
+ $.each($.ui.dialog.overlay.instances, function() {
+ $overlays = $overlays.add(this);
+ });
+
+ $overlays.css({
+ width: 0,
+ height: 0
+ }).css({
+ width: $.ui.dialog.overlay.width(),
+ height: $.ui.dialog.overlay.height()
+ });
+ }
+});
+
+$.extend($.ui.dialog.overlay.prototype, {
+ destroy: function() {
+ $.ui.dialog.overlay.destroy(this.$el);
+ }
+});
+
+}(jQuery));
+/*
+ * jQuery UI Position 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Position
+ */
+(function( $, undefined ) {
+
+$.ui = $.ui || {};
+
+var horizontalPositions = /left|center|right/,
+ verticalPositions = /top|center|bottom/,
+ center = "center",
+ _position = $.fn.position,
+ _offset = $.fn.offset;
+
+$.fn.position = function( options ) {
+ if ( !options || !options.of ) {
+ return _position.apply( this, arguments );
+ }
+
+ // make a copy, we don't want to modify arguments
+ options = $.extend( {}, options );
+
+ var target = $( options.of ),
+ targetElem = target[0],
+ collision = ( options.collision || "flip" ).split( " " ),
+ offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
+ targetWidth,
+ targetHeight,
+ basePosition;
+
+ if ( targetElem.nodeType === 9 ) {
+ targetWidth = target.width();
+ targetHeight = target.height();
+ basePosition = { top: 0, left: 0 };
+ // TODO: use $.isWindow() in 1.9
+ } else if ( targetElem.setTimeout ) {
+ targetWidth = target.width();
+ targetHeight = target.height();
+ basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
+ } else if ( targetElem.preventDefault ) {
+ // force left top to allow flipping
+ options.at = "left top";
+ targetWidth = targetHeight = 0;
+ basePosition = { top: options.of.pageY, left: options.of.pageX };
+ } else {
+ targetWidth = target.outerWidth();
+ targetHeight = target.outerHeight();
+ basePosition = target.offset();
+ }
+
+ // force my and at to have valid horizontal and veritcal positions
+ // if a value is missing or invalid, it will be converted to center
+ $.each( [ "my", "at" ], function() {
+ var pos = ( options[this] || "" ).split( " " );
+ if ( pos.length === 1) {
+ pos = horizontalPositions.test( pos[0] ) ?
+ pos.concat( [center] ) :
+ verticalPositions.test( pos[0] ) ?
+ [ center ].concat( pos ) :
+ [ center, center ];
+ }
+ pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
+ pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
+ options[ this ] = pos;
+ });
+
+ // normalize collision option
+ if ( collision.length === 1 ) {
+ collision[ 1 ] = collision[ 0 ];
+ }
+
+ // normalize offset option
+ offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
+ if ( offset.length === 1 ) {
+ offset[ 1 ] = offset[ 0 ];
+ }
+ offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
+
+ if ( options.at[0] === "right" ) {
+ basePosition.left += targetWidth;
+ } else if ( options.at[0] === center ) {
+ basePosition.left += targetWidth / 2;
+ }
+
+ if ( options.at[1] === "bottom" ) {
+ basePosition.top += targetHeight;
+ } else if ( options.at[1] === center ) {
+ basePosition.top += targetHeight / 2;
+ }
+
+ basePosition.left += offset[ 0 ];
+ basePosition.top += offset[ 1 ];
+
+ return this.each(function() {
+ var elem = $( this ),
+ elemWidth = elem.outerWidth(),
+ elemHeight = elem.outerHeight(),
+ marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
+ marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
+ collisionWidth = elemWidth + marginLeft +
+ ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
+ collisionHeight = elemHeight + marginTop +
+ ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
+ position = $.extend( {}, basePosition ),
+ collisionPosition;
+
+ if ( options.my[0] === "right" ) {
+ position.left -= elemWidth;
+ } else if ( options.my[0] === center ) {
+ position.left -= elemWidth / 2;
+ }
+
+ if ( options.my[1] === "bottom" ) {
+ position.top -= elemHeight;
+ } else if ( options.my[1] === center ) {
+ position.top -= elemHeight / 2;
+ }
+
+ // prevent fractions (see #5280)
+ position.left = Math.round( position.left );
+ position.top = Math.round( position.top );
+
+ collisionPosition = {
+ left: position.left - marginLeft,
+ top: position.top - marginTop
+ };
+
+ $.each( [ "left", "top" ], function( i, dir ) {
+ if ( $.ui.position[ collision[i] ] ) {
+ $.ui.position[ collision[i] ][ dir ]( position, {
+ targetWidth: targetWidth,
+ targetHeight: targetHeight,
+ elemWidth: elemWidth,
+ elemHeight: elemHeight,
+ collisionPosition: collisionPosition,
+ collisionWidth: collisionWidth,
+ collisionHeight: collisionHeight,
+ offset: offset,
+ my: options.my,
+ at: options.at
+ });
+ }
+ });
+
+ if ( $.fn.bgiframe ) {
+ elem.bgiframe();
+ }
+ elem.offset( $.extend( position, { using: options.using } ) );
+ });
+};
+
+$.ui.position = {
+ fit: {
+ left: function( position, data ) {
+ var win = $( window ),
+ over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
+ position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
+ },
+ top: function( position, data ) {
+ var win = $( window ),
+ over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
+ position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
+ }
+ },
+
+ flip: {
+ left: function( position, data ) {
+ if ( data.at[0] === center ) {
+ return;
+ }
+ var win = $( window ),
+ over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
+ myOffset = data.my[ 0 ] === "left" ?
+ -data.elemWidth :
+ data.my[ 0 ] === "right" ?
+ data.elemWidth :
+ 0,
+ atOffset = data.at[ 0 ] === "left" ?
+ data.targetWidth :
+ -data.targetWidth,
+ offset = -2 * data.offset[ 0 ];
+ position.left += data.collisionPosition.left < 0 ?
+ myOffset + atOffset + offset :
+ over > 0 ?
+ myOffset + atOffset + offset :
+ 0;
+ },
+ top: function( position, data ) {
+ if ( data.at[1] === center ) {
+ return;
+ }
+ var win = $( window ),
+ over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
+ myOffset = data.my[ 1 ] === "top" ?
+ -data.elemHeight :
+ data.my[ 1 ] === "bottom" ?
+ data.elemHeight :
+ 0,
+ atOffset = data.at[ 1 ] === "top" ?
+ data.targetHeight :
+ -data.targetHeight,
+ offset = -2 * data.offset[ 1 ];
+ position.top += data.collisionPosition.top < 0 ?
+ myOffset + atOffset + offset :
+ over > 0 ?
+ myOffset + atOffset + offset :
+ 0;
+ }
+ }
+};
+
+// offset setter from jQuery 1.4
+if ( !$.offset.setOffset ) {
+ $.offset.setOffset = function( elem, options ) {
+ // set position first, in-case top/left are set even on static elem
+ if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
+ elem.style.position = "relative";
+ }
+ var curElem = $( elem ),
+ curOffset = curElem.offset(),
+ curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,
+ curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,
+ props = {
+ top: (options.top - curOffset.top) + curTop,
+ left: (options.left - curOffset.left) + curLeft
+ };
+
+ if ( 'using' in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ };
+
+ $.fn.offset = function( options ) {
+ var elem = this[ 0 ];
+ if ( !elem || !elem.ownerDocument ) { return null; }
+ if ( options ) {
+ return this.each(function() {
+ $.offset.setOffset( this, options );
+ });
+ }
+ return _offset.call( this );
+ };
+}
+
+}( jQuery ));
+/*
+ * jQuery UI Progressbar 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Progressbar
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget( "ui.progressbar", {
+ options: {
+ value: 0,
+ max: 100
+ },
+
+ min: 0,
+
+ _create: function() {
+ this.element
+ .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
+ .attr({
+ role: "progressbar",
+ "aria-valuemin": this.min,
+ "aria-valuemax": this.options.max,
+ "aria-valuenow": this._value()
+ });
+
+ this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
+ .appendTo( this.element );
+
+ this.oldValue = this._value();
+ this._refreshValue();
+ },
+
+ destroy: function() {
+ this.element
+ .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
+ .removeAttr( "role" )
+ .removeAttr( "aria-valuemin" )
+ .removeAttr( "aria-valuemax" )
+ .removeAttr( "aria-valuenow" );
+
+ this.valueDiv.remove();
+
+ $.Widget.prototype.destroy.apply( this, arguments );
+ },
+
+ value: function( newValue ) {
+ if ( newValue === undefined ) {
+ return this._value();
+ }
+
+ this._setOption( "value", newValue );
+ return this;
+ },
+
+ _setOption: function( key, value ) {
+ if ( key === "value" ) {
+ this.options.value = value;
+ this._refreshValue();
+ if ( this._value() === this.options.max ) {
+ this._trigger( "complete" );
+ }
+ }
+
+ $.Widget.prototype._setOption.apply( this, arguments );
+ },
+
+ _value: function() {
+ var val = this.options.value;
+ // normalize invalid value
+ if ( typeof val !== "number" ) {
+ val = 0;
+ }
+ return Math.min( this.options.max, Math.max( this.min, val ) );
+ },
+
+ _percentage: function() {
+ return 100 * this._value() / this.options.max;
+ },
+
+ _refreshValue: function() {
+ var value = this.value();
+ var percentage = this._percentage();
+
+ if ( this.oldValue !== value ) {
+ this.oldValue = value;
+ this._trigger( "change" );
+ }
+
+ this.valueDiv
+ .toggle( value > this.min )
+ .toggleClass( "ui-corner-right", value === this.options.max )
+ .width( percentage.toFixed(0) + "%" );
+ this.element.attr( "aria-valuenow", value );
+ }
+});
+
+$.extend( $.ui.progressbar, {
+ version: "1.8.16"
+});
+
+})( jQuery );
+/*
+ * jQuery UI Slider 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.mouse.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+// number of pages in a slider
+// (how many times can you page up/down to go through the whole range)
+var numPages = 5;
+
+$.widget( "ui.slider", $.ui.mouse, {
+
+ widgetEventPrefix: "slide",
+
+ options: {
+ animate: false,
+ distance: 0,
+ max: 100,
+ min: 0,
+ orientation: "horizontal",
+ range: false,
+ step: 1,
+ value: 0,
+ values: null
+ },
+
+ _create: function() {
+ var self = this,
+ o = this.options,
+ existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
+ handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
+ handleCount = ( o.values && o.values.length ) || 1,
+ handles = [];
+
+ this._keySliding = false;
+ this._mouseSliding = false;
+ this._animateOff = true;
+ this._handleIndex = null;
+ this._detectOrientation();
+ this._mouseInit();
+
+ this.element
+ .addClass( "ui-slider" +
+ " ui-slider-" + this.orientation +
+ " ui-widget" +
+ " ui-widget-content" +
+ " ui-corner-all" +
+ ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
+
+ this.range = $([]);
+
+ if ( o.range ) {
+ if ( o.range === true ) {
+ if ( !o.values ) {
+ o.values = [ this._valueMin(), this._valueMin() ];
+ }
+ if ( o.values.length && o.values.length !== 2 ) {
+ o.values = [ o.values[0], o.values[0] ];
+ }
+ }
+
+ this.range = $( "<div></div>" )
+ .appendTo( this.element )
+ .addClass( "ui-slider-range" +
+ // note: this isn't the most fittingly semantic framework class for this element,
+ // but worked best visually with a variety of themes
+ " ui-widget-header" +
+ ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
+ }
+
+ for ( var i = existingHandles.length; i < handleCount; i += 1 ) {
+ handles.push( handle );
+ }
+
+ this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( self.element ) );
+
+ this.handle = this.handles.eq( 0 );
+
+ this.handles.add( this.range ).filter( "a" )
+ .click(function( event ) {
+ event.preventDefault();
+ })
+ .hover(function() {
+ if ( !o.disabled ) {
+ $( this ).addClass( "ui-state-hover" );
+ }
+ }, function() {
+ $( this ).removeClass( "ui-state-hover" );
+ })
+ .focus(function() {
+ if ( !o.disabled ) {
+ $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
+ $( this ).addClass( "ui-state-focus" );
+ } else {
+ $( this ).blur();
+ }
+ })
+ .blur(function() {
+ $( this ).removeClass( "ui-state-focus" );
+ });
+
+ this.handles.each(function( i ) {
+ $( this ).data( "index.ui-slider-handle", i );
+ });
+
+ this.handles
+ .keydown(function( event ) {
+ var ret = true,
+ index = $( this ).data( "index.ui-slider-handle" ),
+ allowed,
+ curVal,
+ newVal,
+ step;
+
+ if ( self.options.disabled ) {
+ return;
+ }
+
+ switch ( event.keyCode ) {
+ case $.ui.keyCode.HOME:
+ case $.ui.keyCode.END:
+ case $.ui.keyCode.PAGE_UP:
+ case $.ui.keyCode.PAGE_DOWN:
+ case $.ui.keyCode.UP:
+ case $.ui.keyCode.RIGHT:
+ case $.ui.keyCode.DOWN:
+ case $.ui.keyCode.LEFT:
+ ret = false;
+ if ( !self._keySliding ) {
+ self._keySliding = true;
+ $( this ).addClass( "ui-state-active" );
+ allowed = self._start( event, index );
+ if ( allowed === false ) {
+ return;
+ }
+ }
+ break;
+ }
+
+ step = self.options.step;
+ if ( self.options.values && self.options.values.length ) {
+ curVal = newVal = self.values( index );
+ } else {
+ curVal = newVal = self.value();
+ }
+
+ switch ( event.keyCode ) {
+ case $.ui.keyCode.HOME:
+ newVal = self._valueMin();
+ break;
+ case $.ui.keyCode.END:
+ newVal = self._valueMax();
+ break;
+ case $.ui.keyCode.PAGE_UP:
+ newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
+ break;
+ case $.ui.keyCode.PAGE_DOWN:
+ newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
+ break;
+ case $.ui.keyCode.UP:
+ case $.ui.keyCode.RIGHT:
+ if ( curVal === self._valueMax() ) {
+ return;
+ }
+ newVal = self._trimAlignValue( curVal + step );
+ break;
+ case $.ui.keyCode.DOWN:
+ case $.ui.keyCode.LEFT:
+ if ( curVal === self._valueMin() ) {
+ return;
+ }
+ newVal = self._trimAlignValue( curVal - step );
+ break;
+ }
+
+ self._slide( event, index, newVal );
+
+ return ret;
+
+ })
+ .keyup(function( event ) {
+ var index = $( this ).data( "index.ui-slider-handle" );
+
+ if ( self._keySliding ) {
+ self._keySliding = false;
+ self._stop( event, index );
+ self._change( event, index );
+ $( this ).removeClass( "ui-state-active" );
+ }
+
+ });
+
+ this._refreshValue();
+
+ this._animateOff = false;
+ },
+
+ destroy: function() {
+ this.handles.remove();
+ this.range.remove();
+
+ this.element
+ .removeClass( "ui-slider" +
+ " ui-slider-horizontal" +
+ " ui-slider-vertical" +
+ " ui-slider-disabled" +
+ " ui-widget" +
+ " ui-widget-content" +
+ " ui-corner-all" )
+ .removeData( "slider" )
+ .unbind( ".slider" );
+
+ this._mouseDestroy();
+
+ return this;
+ },
+
+ _mouseCapture: function( event ) {
+ var o = this.options,
+ position,
+ normValue,
+ distance,
+ closestHandle,
+ self,
+ index,
+ allowed,
+ offset,
+ mouseOverHandle;
+
+ if ( o.disabled ) {
+ return false;
+ }
+
+ this.elementSize = {
+ width: this.element.outerWidth(),
+ height: this.element.outerHeight()
+ };
+ this.elementOffset = this.element.offset();
+
+ position = { x: event.pageX, y: event.pageY };
+ normValue = this._normValueFromMouse( position );
+ distance = this._valueMax() - this._valueMin() + 1;
+ self = this;
+ this.handles.each(function( i ) {
+ var thisDistance = Math.abs( normValue - self.values(i) );
+ if ( distance > thisDistance ) {
+ distance = thisDistance;
+ closestHandle = $( this );
+ index = i;
+ }
+ });
+
+ // workaround for bug #3736 (if both handles of a range are at 0,
+ // the first is always used as the one with least distance,
+ // and moving it is obviously prevented by preventing negative ranges)
+ if( o.range === true && this.values(1) === o.min ) {
+ index += 1;
+ closestHandle = $( this.handles[index] );
+ }
+
+ allowed = this._start( event, index );
+ if ( allowed === false ) {
+ return false;
+ }
+ this._mouseSliding = true;
+
+ self._handleIndex = index;
+
+ closestHandle
+ .addClass( "ui-state-active" )
+ .focus();
+
+ offset = closestHandle.offset();
+ mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
+ this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
+ left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
+ top: event.pageY - offset.top -
+ ( closestHandle.height() / 2 ) -
+ ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
+ ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
+ ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
+ };
+
+ if ( !this.handles.hasClass( "ui-state-hover" ) ) {
+ this._slide( event, index, normValue );
+ }
+ this._animateOff = true;
+ return true;
+ },
+
+ _mouseStart: function( event ) {
+ return true;
+ },
+
+ _mouseDrag: function( event ) {
+ var position = { x: event.pageX, y: event.pageY },
+ normValue = this._normValueFromMouse( position );
+
+ this._slide( event, this._handleIndex, normValue );
+
+ return false;
+ },
+
+ _mouseStop: function( event ) {
+ this.handles.removeClass( "ui-state-active" );
+ this._mouseSliding = false;
+
+ this._stop( event, this._handleIndex );
+ this._change( event, this._handleIndex );
+
+ this._handleIndex = null;
+ this._clickOffset = null;
+ this._animateOff = false;
+
+ return false;
+ },
+
+ _detectOrientation: function() {
+ this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
+ },
+
+ _normValueFromMouse: function( position ) {
+ var pixelTotal,
+ pixelMouse,
+ percentMouse,
+ valueTotal,
+ valueMouse;
+
+ if ( this.orientation === "horizontal" ) {
+ pixelTotal = this.elementSize.width;
+ pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
+ } else {
+ pixelTotal = this.elementSize.height;
+ pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
+ }
+
+ percentMouse = ( pixelMouse / pixelTotal );
+ if ( percentMouse > 1 ) {
+ percentMouse = 1;
+ }
+ if ( percentMouse < 0 ) {
+ percentMouse = 0;
+ }
+ if ( this.orientation === "vertical" ) {
+ percentMouse = 1 - percentMouse;
+ }
+
+ valueTotal = this._valueMax() - this._valueMin();
+ valueMouse = this._valueMin() + percentMouse * valueTotal;
+
+ return this._trimAlignValue( valueMouse );
+ },
+
+ _start: function( event, index ) {
+ var uiHash = {
+ handle: this.handles[ index ],
+ value: this.value()
+ };
+ if ( this.options.values && this.options.values.length ) {
+ uiHash.value = this.values( index );
+ uiHash.values = this.values();
+ }
+ return this._trigger( "start", event, uiHash );
+ },
+
+ _slide: function( event, index, newVal ) {
+ var otherVal,
+ newValues,
+ allowed;
+
+ if ( this.options.values && this.options.values.length ) {
+ otherVal = this.values( index ? 0 : 1 );
+
+ if ( ( this.options.values.length === 2 && this.options.range === true ) &&
+ ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
+ ) {
+ newVal = otherVal;
+ }
+
+ if ( newVal !== this.values( index ) ) {
+ newValues = this.values();
+ newValues[ index ] = newVal;
+ // A slide can be canceled by returning false from the slide callback
+ allowed = this._trigger( "slide", event, {
+ handle: this.handles[ index ],
+ value: newVal,
+ values: newValues
+ } );
+ otherVal = this.values( index ? 0 : 1 );
+ if ( allowed !== false ) {
+ this.values( index, newVal, true );
+ }
+ }
+ } else {
+ if ( newVal !== this.value() ) {
+ // A slide can be canceled by returning false from the slide callback
+ allowed = this._trigger( "slide", event, {
+ handle: this.handles[ index ],
+ value: newVal
+ } );
+ if ( allowed !== false ) {
+ this.value( newVal );
+ }
+ }
+ }
+ },
+
+ _stop: function( event, index ) {
+ var uiHash = {
+ handle: this.handles[ index ],
+ value: this.value()
+ };
+ if ( this.options.values && this.options.values.length ) {
+ uiHash.value = this.values( index );
+ uiHash.values = this.values();
+ }
+
+ this._trigger( "stop", event, uiHash );
+ },
+
+ _change: function( event, index ) {
+ if ( !this._keySliding && !this._mouseSliding ) {
+ var uiHash = {
+ handle: this.handles[ index ],
+ value: this.value()
+ };
+ if ( this.options.values && this.options.values.length ) {
+ uiHash.value = this.values( index );
+ uiHash.values = this.values();
+ }
+
+ this._trigger( "change", event, uiHash );
+ }
+ },
+
+ value: function( newValue ) {
+ if ( arguments.length ) {
+ this.options.value = this._trimAlignValue( newValue );
+ this._refreshValue();
+ this._change( null, 0 );
+ return;
+ }
+
+ return this._value();
+ },
+
+ values: function( index, newValue ) {
+ var vals,
+ newValues,
+ i;
+
+ if ( arguments.length > 1 ) {
+ this.options.values[ index ] = this._trimAlignValue( newValue );
+ this._refreshValue();
+ this._change( null, index );
+ return;
+ }
+
+ if ( arguments.length ) {
+ if ( $.isArray( arguments[ 0 ] ) ) {
+ vals = this.options.values;
+ newValues = arguments[ 0 ];
+ for ( i = 0; i < vals.length; i += 1 ) {
+ vals[ i ] = this._trimAlignValue( newValues[ i ] );
+ this._change( null, i );
+ }
+ this._refreshValue();
+ } else {
+ if ( this.options.values && this.options.values.length ) {
+ return this._values( index );
+ } else {
+ return this.value();
+ }
+ }
+ } else {
+ return this._values();
+ }
+ },
+
+ _setOption: function( key, value ) {
+ var i,
+ valsLength = 0;
+
+ if ( $.isArray( this.options.values ) ) {
+ valsLength = this.options.values.length;
+ }
+
+ $.Widget.prototype._setOption.apply( this, arguments );
+
+ switch ( key ) {
+ case "disabled":
+ if ( value ) {
+ this.handles.filter( ".ui-state-focus" ).blur();
+ this.handles.removeClass( "ui-state-hover" );
+ this.handles.propAttr( "disabled", true );
+ this.element.addClass( "ui-disabled" );
+ } else {
+ this.handles.propAttr( "disabled", false );
+ this.element.removeClass( "ui-disabled" );
+ }
+ break;
+ case "orientation":
+ this._detectOrientation();
+ this.element
+ .removeClass( "ui-slider-horizontal ui-slider-vertical" )
+ .addClass( "ui-slider-" + this.orientation );
+ this._refreshValue();
+ break;
+ case "value":
+ this._animateOff = true;
+ this._refreshValue();
+ this._change( null, 0 );
+ this._animateOff = false;
+ break;
+ case "values":
+ this._animateOff = true;
+ this._refreshValue();
+ for ( i = 0; i < valsLength; i += 1 ) {
+ this._change( null, i );
+ }
+ this._animateOff = false;
+ break;
+ }
+ },
+
+ //internal value getter
+ // _value() returns value trimmed by min and max, aligned by step
+ _value: function() {
+ var val = this.options.value;
+ val = this._trimAlignValue( val );
+
+ return val;
+ },
+
+ //internal values getter
+ // _values() returns array of values trimmed by min and max, aligned by step
+ // _values( index ) returns single value trimmed by min and max, aligned by step
+ _values: function( index ) {
+ var val,
+ vals,
+ i;
+
+ if ( arguments.length ) {
+ val = this.options.values[ index ];
+ val = this._trimAlignValue( val );
+
+ return val;
+ } else {
+ // .slice() creates a copy of the array
+ // this copy gets trimmed by min and max and then returned
+ vals = this.options.values.slice();
+ for ( i = 0; i < vals.length; i+= 1) {
+ vals[ i ] = this._trimAlignValue( vals[ i ] );
+ }
+
+ return vals;
+ }
+ },
+
+ // returns the step-aligned value that val is closest to, between (inclusive) min and max
+ _trimAlignValue: function( val ) {
+ if ( val <= this._valueMin() ) {
+ return this._valueMin();
+ }
+ if ( val >= this._valueMax() ) {
+ return this._valueMax();
+ }
+ var step = ( this.options.step > 0 ) ? this.options.step : 1,
+ valModStep = (val - this._valueMin()) % step,
+ alignValue = val - valModStep;
+
+ if ( Math.abs(valModStep) * 2 >= step ) {
+ alignValue += ( valModStep > 0 ) ? step : ( -step );
+ }
+
+ // Since JavaScript has problems with large floats, round
+ // the final value to 5 digits after the decimal point (see #4124)
+ return parseFloat( alignValue.toFixed(5) );
+ },
+
+ _valueMin: function() {
+ return this.options.min;
+ },
+
+ _valueMax: function() {
+ return this.options.max;
+ },
+
+ _refreshValue: function() {
+ var oRange = this.options.range,
+ o = this.options,
+ self = this,
+ animate = ( !this._animateOff ) ? o.animate : false,
+ valPercent,
+ _set = {},
+ lastValPercent,
+ value,
+ valueMin,
+ valueMax;
+
+ if ( this.options.values && this.options.values.length ) {
+ this.handles.each(function( i, j ) {
+ valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
+ _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
+ $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
+ if ( self.options.range === true ) {
+ if ( self.orientation === "horizontal" ) {
+ if ( i === 0 ) {
+ self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
+ }
+ if ( i === 1 ) {
+ self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
+ }
+ } else {
+ if ( i === 0 ) {
+ self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
+ }
+ if ( i === 1 ) {
+ self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
+ }
+ }
+ }
+ lastValPercent = valPercent;
+ });
+ } else {
+ value = this.value();
+ valueMin = this._valueMin();
+ valueMax = this._valueMax();
+ valPercent = ( valueMax !== valueMin ) ?
+ ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
+ 0;
+ _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
+ this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
+
+ if ( oRange === "min" && this.orientation === "horizontal" ) {
+ this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
+ }
+ if ( oRange === "max" && this.orientation === "horizontal" ) {
+ this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
+ }
+ if ( oRange === "min" && this.orientation === "vertical" ) {
+ this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
+ }
+ if ( oRange === "max" && this.orientation === "vertical" ) {
+ this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
+ }
+ }
+ }
+
+});
+
+$.extend( $.ui.slider, {
+ version: "1.8.16"
+});
+
+}(jQuery));
+/*
+ * jQuery UI Tabs 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Tabs
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+var tabId = 0,
+ listId = 0;
+
+function getNextTabId() {
+ return ++tabId;
+}
+
+function getNextListId() {
+ return ++listId;
+}
+
+$.widget( "ui.tabs", {
+ options: {
+ add: null,
+ ajaxOptions: null,
+ cache: false,
+ cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
+ collapsible: false,
+ disable: null,
+ disabled: [],
+ enable: null,
+ event: "click",
+ fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
+ idPrefix: "ui-tabs-",
+ load: null,
+ panelTemplate: "<div></div>",
+ remove: null,
+ select: null,
+ show: null,
+ spinner: "<em>Loading&#8230;</em>",
+ tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
+ },
+
+ _create: function() {
+ this._tabify( true );
+ },
+
+ _setOption: function( key, value ) {
+ if ( key == "selected" ) {
+ if (this.options.collapsible && value == this.options.selected ) {
+ return;
+ }
+ this.select( value );
+ } else {
+ this.options[ key ] = value;
+ this._tabify();
+ }
+ },
+
+ _tabId: function( a ) {
+ return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
+ this.options.idPrefix + getNextTabId();
+ },
+
+ _sanitizeSelector: function( hash ) {
+ // we need this because an id may contain a ":"
+ return hash.replace( /:/g, "\\:" );
+ },
+
+ _cookie: function() {
+ var cookie = this.cookie ||
+ ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
+ return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
+ },
+
+ _ui: function( tab, panel ) {
+ return {
+ tab: tab,
+ panel: panel,
+ index: this.anchors.index( tab )
+ };
+ },
+
+ _cleanup: function() {
+ // restore all former loading tabs labels
+ this.lis.filter( ".ui-state-processing" )
+ .removeClass( "ui-state-processing" )
+ .find( "span:data(label.tabs)" )
+ .each(function() {
+ var el = $( this );
+ el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
+ });
+ },
+
+ _tabify: function( init ) {
+ var self = this,
+ o = this.options,
+ fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
+
+ this.list = this.element.find( "ol,ul" ).eq( 0 );
+ this.lis = $( " > li:has(a[href])", this.list );
+ this.anchors = this.lis.map(function() {
+ return $( "a", this )[ 0 ];
+ });
+ this.panels = $( [] );
+
+ this.anchors.each(function( i, a ) {
+ var href = $( a ).attr( "href" );
+ // For dynamically created HTML that contains a hash as href IE < 8 expands
+ // such href to the full page url with hash and then misinterprets tab as ajax.
+ // Same consideration applies for an added tab with a fragment identifier
+ // since a[href=#fragment-identifier] does unexpectedly not match.
+ // Thus normalize href attribute...
+ var hrefBase = href.split( "#" )[ 0 ],
+ baseEl;
+ if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
+ ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
+ href = a.hash;
+ a.href = href;
+ }
+
+ // inline tab
+ if ( fragmentId.test( href ) ) {
+ self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
+ // remote tab
+ // prevent loading the page itself if href is just "#"
+ } else if ( href && href !== "#" ) {
+ // required for restore on destroy
+ $.data( a, "href.tabs", href );
+
+ // TODO until #3808 is fixed strip fragment identifier from url
+ // (IE fails to load from such url)
+ $.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
+
+ var id = self._tabId( a );
+ a.href = "#" + id;
+ var $panel = self.element.find( "#" + id );
+ if ( !$panel.length ) {
+ $panel = $( o.panelTemplate )
+ .attr( "id", id )
+ .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
+ .insertAfter( self.panels[ i - 1 ] || self.list );
+ $panel.data( "destroy.tabs", true );
+ }
+ self.panels = self.panels.add( $panel );
+ // invalid tab href
+ } else {
+ o.disabled.push( i );
+ }
+ });
+
+ // initialization from scratch
+ if ( init ) {
+ // attach necessary classes for styling
+ this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
+ this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
+ this.lis.addClass( "ui-state-default ui-corner-top" );
+ this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
+
+ // Selected tab
+ // use "selected" option or try to retrieve:
+ // 1. from fragment identifier in url
+ // 2. from cookie
+ // 3. from selected class attribute on <li>
+ if ( o.selected === undefined ) {
+ if ( location.hash ) {
+ this.anchors.each(function( i, a ) {
+ if ( a.hash == location.hash ) {
+ o.selected = i;
+ return false;
+ }
+ });
+ }
+ if ( typeof o.selected !== "number" && o.cookie ) {
+ o.selected = parseInt( self._cookie(), 10 );
+ }
+ if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
+ o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
+ }
+ o.selected = o.selected || ( this.lis.length ? 0 : -1 );
+ } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
+ o.selected = -1;
+ }
+
+ // sanity check - default to first tab...
+ o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
+ ? o.selected
+ : 0;
+
+ // Take disabling tabs via class attribute from HTML
+ // into account and update option properly.
+ // A selected tab cannot become disabled.
+ o.disabled = $.unique( o.disabled.concat(
+ $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
+ return self.lis.index( n );
+ })
+ ) ).sort();
+
+ if ( $.inArray( o.selected, o.disabled ) != -1 ) {
+ o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
+ }
+
+ // highlight selected tab
+ this.panels.addClass( "ui-tabs-hide" );
+ this.lis.removeClass( "ui-tabs-selected ui-state-active" );
+ // check for length avoids error when initializing empty list
+ if ( o.selected >= 0 && this.anchors.length ) {
+ self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
+ this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
+
+ // seems to be expected behavior that the show callback is fired
+ self.element.queue( "tabs", function() {
+ self._trigger( "show", null,
+ self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
+ });
+
+ this.load( o.selected );
+ }
+
+ // clean up to avoid memory leaks in certain versions of IE 6
+ // TODO: namespace this event
+ $( window ).bind( "unload", function() {
+ self.lis.add( self.anchors ).unbind( ".tabs" );
+ self.lis = self.anchors = self.panels = null;
+ });
+ // update selected after add/remove
+ } else {
+ o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
+ }
+
+ // update collapsible
+ // TODO: use .toggleClass()
+ this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
+
+ // set or update cookie after init and add/remove respectively
+ if ( o.cookie ) {
+ this._cookie( o.selected, o.cookie );
+ }
+
+ // disable tabs
+ for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
+ $( li )[ $.inArray( i, o.disabled ) != -1 &&
+ // TODO: use .toggleClass()
+ !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
+ }
+
+ // reset cache if switching from cached to not cached
+ if ( o.cache === false ) {
+ this.anchors.removeData( "cache.tabs" );
+ }
+
+ // remove all handlers before, tabify may run on existing tabs after add or option change
+ this.lis.add( this.anchors ).unbind( ".tabs" );
+
+ if ( o.event !== "mouseover" ) {
+ var addState = function( state, el ) {
+ if ( el.is( ":not(.ui-state-disabled)" ) ) {
+ el.addClass( "ui-state-" + state );
+ }
+ };
+ var removeState = function( state, el ) {
+ el.removeClass( "ui-state-" + state );
+ };
+ this.lis.bind( "mouseover.tabs" , function() {
+ addState( "hover", $( this ) );
+ });
+ this.lis.bind( "mouseout.tabs", function() {
+ removeState( "hover", $( this ) );
+ });
+ this.anchors.bind( "focus.tabs", function() {
+ addState( "focus", $( this ).closest( "li" ) );
+ });
+ this.anchors.bind( "blur.tabs", function() {
+ removeState( "focus", $( this ).closest( "li" ) );
+ });
+ }
+
+ // set up animations
+ var hideFx, showFx;
+ if ( o.fx ) {
+ if ( $.isArray( o.fx ) ) {
+ hideFx = o.fx[ 0 ];
+ showFx = o.fx[ 1 ];
+ } else {
+ hideFx = showFx = o.fx;
+ }
+ }
+
+ // Reset certain styles left over from animation
+ // and prevent IE's ClearType bug...
+ function resetStyle( $el, fx ) {
+ $el.css( "display", "" );
+ if ( !$.support.opacity && fx.opacity ) {
+ $el[ 0 ].style.removeAttribute( "filter" );
+ }
+ }
+
+ // Show a tab...
+ var showTab = showFx
+ ? function( clicked, $show ) {
+ $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
+ $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
+ .animate( showFx, showFx.duration || "normal", function() {
+ resetStyle( $show, showFx );
+ self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
+ });
+ }
+ : function( clicked, $show ) {
+ $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
+ $show.removeClass( "ui-tabs-hide" );
+ self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
+ };
+
+ // Hide a tab, $show is optional...
+ var hideTab = hideFx
+ ? function( clicked, $hide ) {
+ $hide.animate( hideFx, hideFx.duration || "normal", function() {
+ self.lis.removeClass( "ui-tabs-selected ui-state-active" );
+ $hide.addClass( "ui-tabs-hide" );
+ resetStyle( $hide, hideFx );
+ self.element.dequeue( "tabs" );
+ });
+ }
+ : function( clicked, $hide, $show ) {
+ self.lis.removeClass( "ui-tabs-selected ui-state-active" );
+ $hide.addClass( "ui-tabs-hide" );
+ self.element.dequeue( "tabs" );
+ };
+
+ // attach tab event handler, unbind to avoid duplicates from former tabifying...
+ this.anchors.bind( o.event + ".tabs", function() {
+ var el = this,
+ $li = $(el).closest( "li" ),
+ $hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
+ $show = self.element.find( self._sanitizeSelector( el.hash ) );
+
+ // If tab is already selected and not collapsible or tab disabled or
+ // or is already loading or click callback returns false stop here.
+ // Check if click handler returns false last so that it is not executed
+ // for a disabled or loading tab!
+ if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
+ $li.hasClass( "ui-state-disabled" ) ||
+ $li.hasClass( "ui-state-processing" ) ||
+ self.panels.filter( ":animated" ).length ||
+ self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
+ this.blur();
+ return false;
+ }
+
+ o.selected = self.anchors.index( this );
+
+ self.abort();
+
+ // if tab may be closed
+ if ( o.collapsible ) {
+ if ( $li.hasClass( "ui-tabs-selected" ) ) {
+ o.selected = -1;
+
+ if ( o.cookie ) {
+ self._cookie( o.selected, o.cookie );
+ }
+
+ self.element.queue( "tabs", function() {
+ hideTab( el, $hide );
+ }).dequeue( "tabs" );
+
+ this.blur();
+ return false;
+ } else if ( !$hide.length ) {
+ if ( o.cookie ) {
+ self._cookie( o.selected, o.cookie );
+ }
+
+ self.element.queue( "tabs", function() {
+ showTab( el, $show );
+ });
+
+ // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
+ self.load( self.anchors.index( this ) );
+
+ this.blur();
+ return false;
+ }
+ }
+
+ if ( o.cookie ) {
+ self._cookie( o.selected, o.cookie );
+ }
+
+ // show new tab
+ if ( $show.length ) {
+ if ( $hide.length ) {
+ self.element.queue( "tabs", function() {
+ hideTab( el, $hide );
+ });
+ }
+ self.element.queue( "tabs", function() {
+ showTab( el, $show );
+ });
+
+ self.load( self.anchors.index( this ) );
+ } else {
+ throw "jQuery UI Tabs: Mismatching fragment identifier.";
+ }
+
+ // Prevent IE from keeping other link focussed when using the back button
+ // and remove dotted border from clicked link. This is controlled via CSS
+ // in modern browsers; blur() removes focus from address bar in Firefox
+ // which can become a usability and annoying problem with tabs('rotate').
+ if ( $.browser.msie ) {
+ this.blur();
+ }
+ });
+
+ // disable click in any case
+ this.anchors.bind( "click.tabs", function(){
+ return false;
+ });
+ },
+
+ _getIndex: function( index ) {
+ // meta-function to give users option to provide a href string instead of a numerical index.
+ // also sanitizes numerical indexes to valid values.
+ if ( typeof index == "string" ) {
+ index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) );
+ }
+
+ return index;
+ },
+
+ destroy: function() {
+ var o = this.options;
+
+ this.abort();
+
+ this.element
+ .unbind( ".tabs" )
+ .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
+ .removeData( "tabs" );
+
+ this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
+
+ this.anchors.each(function() {
+ var href = $.data( this, "href.tabs" );
+ if ( href ) {
+ this.href = href;
+ }
+ var $this = $( this ).unbind( ".tabs" );
+ $.each( [ "href", "load", "cache" ], function( i, prefix ) {
+ $this.removeData( prefix + ".tabs" );
+ });
+ });
+
+ this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
+ if ( $.data( this, "destroy.tabs" ) ) {
+ $( this ).remove();
+ } else {
+ $( this ).removeClass([
+ "ui-state-default",
+ "ui-corner-top",
+ "ui-tabs-selected",
+ "ui-state-active",
+ "ui-state-hover",
+ "ui-state-focus",
+ "ui-state-disabled",
+ "ui-tabs-panel",
+ "ui-widget-content",
+ "ui-corner-bottom",
+ "ui-tabs-hide"
+ ].join( " " ) );
+ }
+ });
+
+ if ( o.cookie ) {
+ this._cookie( null, o.cookie );
+ }
+
+ return this;
+ },
+
+ add: function( url, label, index ) {
+ if ( index === undefined ) {
+ index = this.anchors.length;
+ }
+
+ var self = this,
+ o = this.options,
+ $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
+ id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
+
+ $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
+
+ // try to find an existing element before creating a new one
+ var $panel = self.element.find( "#" + id );
+ if ( !$panel.length ) {
+ $panel = $( o.panelTemplate )
+ .attr( "id", id )
+ .data( "destroy.tabs", true );
+ }
+ $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
+
+ if ( index >= this.lis.length ) {
+ $li.appendTo( this.list );
+ $panel.appendTo( this.list[ 0 ].parentNode );
+ } else {
+ $li.insertBefore( this.lis[ index ] );
+ $panel.insertBefore( this.panels[ index ] );
+ }
+
+ o.disabled = $.map( o.disabled, function( n, i ) {
+ return n >= index ? ++n : n;
+ });
+
+ this._tabify();
+
+ if ( this.anchors.length == 1 ) {
+ o.selected = 0;
+ $li.addClass( "ui-tabs-selected ui-state-active" );
+ $panel.removeClass( "ui-tabs-hide" );
+ this.element.queue( "tabs", function() {
+ self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
+ });
+
+ this.load( 0 );
+ }
+
+ this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
+ return this;
+ },
+
+ remove: function( index ) {
+ index = this._getIndex( index );
+ var o = this.options,
+ $li = this.lis.eq( index ).remove(),
+ $panel = this.panels.eq( index ).remove();
+
+ // If selected tab was removed focus tab to the right or
+ // in case the last tab was removed the tab to the left.
+ if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
+ this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
+ }
+
+ o.disabled = $.map(
+ $.grep( o.disabled, function(n, i) {
+ return n != index;
+ }),
+ function( n, i ) {
+ return n >= index ? --n : n;
+ });
+
+ this._tabify();
+
+ this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
+ return this;
+ },
+
+ enable: function( index ) {
+ index = this._getIndex( index );
+ var o = this.options;
+ if ( $.inArray( index, o.disabled ) == -1 ) {
+ return;
+ }
+
+ this.lis.eq( index ).removeClass( "ui-state-disabled" );
+ o.disabled = $.grep( o.disabled, function( n, i ) {
+ return n != index;
+ });
+
+ this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
+ return this;
+ },
+
+ disable: function( index ) {
+ index = this._getIndex( index );
+ var self = this, o = this.options;
+ // cannot disable already selected tab
+ if ( index != o.selected ) {
+ this.lis.eq( index ).addClass( "ui-state-disabled" );
+
+ o.disabled.push( index );
+ o.disabled.sort();
+
+ this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
+ }
+
+ return this;
+ },
+
+ select: function( index ) {
+ index = this._getIndex( index );
+ if ( index == -1 ) {
+ if ( this.options.collapsible && this.options.selected != -1 ) {
+ index = this.options.selected;
+ } else {
+ return this;
+ }
+ }
+ this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
+ return this;
+ },
+
+ load: function( index ) {
+ index = this._getIndex( index );
+ var self = this,
+ o = this.options,
+ a = this.anchors.eq( index )[ 0 ],
+ url = $.data( a, "load.tabs" );
+
+ this.abort();
+
+ // not remote or from cache
+ if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
+ this.element.dequeue( "tabs" );
+ return;
+ }
+
+ // load remote from here on
+ this.lis.eq( index ).addClass( "ui-state-processing" );
+
+ if ( o.spinner ) {
+ var span = $( "span", a );
+ span.data( "label.tabs", span.html() ).html( o.spinner );
+ }
+
+ this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
+ url: url,
+ success: function( r, s ) {
+ self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
+
+ // take care of tab labels
+ self._cleanup();
+
+ if ( o.cache ) {
+ $.data( a, "cache.tabs", true );
+ }
+
+ self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
+ try {
+ o.ajaxOptions.success( r, s );
+ }
+ catch ( e ) {}
+ },
+ error: function( xhr, s, e ) {
+ // take care of tab labels
+ self._cleanup();
+
+ self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
+ try {
+ // Passing index avoid a race condition when this method is
+ // called after the user has selected another tab.
+ // Pass the anchor that initiated this request allows
+ // loadError to manipulate the tab content panel via $(a.hash)
+ o.ajaxOptions.error( xhr, s, index, a );
+ }
+ catch ( e ) {}
+ }
+ } ) );
+
+ // last, so that load event is fired before show...
+ self.element.dequeue( "tabs" );
+
+ return this;
+ },
+
+ abort: function() {
+ // stop possibly running animations
+ this.element.queue( [] );
+ this.panels.stop( false, true );
+
+ // "tabs" queue must not contain more than two elements,
+ // which are the callbacks for the latest clicked tab...
+ this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
+
+ // terminate pending requests from other tabs
+ if ( this.xhr ) {
+ this.xhr.abort();
+ delete this.xhr;
+ }
+
+ // take care of tab labels
+ this._cleanup();
+ return this;
+ },
+
+ url: function( index, url ) {
+ this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
+ return this;
+ },
+
+ length: function() {
+ return this.anchors.length;
+ }
+});
+
+$.extend( $.ui.tabs, {
+ version: "1.8.16"
+});
+
+/*
+ * Tabs Extensions
+ */
+
+/*
+ * Rotate
+ */
+$.extend( $.ui.tabs.prototype, {
+ rotation: null,
+ rotate: function( ms, continuing ) {
+ var self = this,
+ o = this.options;
+
+ var rotate = self._rotate || ( self._rotate = function( e ) {
+ clearTimeout( self.rotation );
+ self.rotation = setTimeout(function() {
+ var t = o.selected;
+ self.select( ++t < self.anchors.length ? t : 0 );
+ }, ms );
+
+ if ( e ) {
+ e.stopPropagation();
+ }
+ });
+
+ var stop = self._unrotate || ( self._unrotate = !continuing
+ ? function(e) {
+ if (e.clientX) { // in case of a true click
+ self.rotate(null);
+ }
+ }
+ : function( e ) {
+ t = o.selected;
+ rotate();
+ });
+
+ // start rotation
+ if ( ms ) {
+ this.element.bind( "tabsshow", rotate );
+ this.anchors.bind( o.event + ".tabs", stop );
+ rotate();
+ // stop rotation
+ } else {
+ clearTimeout( self.rotation );
+ this.element.unbind( "tabsshow", rotate );
+ this.anchors.unbind( o.event + ".tabs", stop );
+ delete this._rotate;
+ delete this._unrotate;
+ }
+
+ return this;
+ }
+});
+
+})( jQuery );
diff --git a/lib/scripts/jquery/jquery-ui.min.js b/lib/scripts/jquery/jquery-ui.min.js
new file mode 100644
index 000000000..0202506b5
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui.min.js
@@ -0,0 +1,414 @@
+/*!
+ * jQuery UI 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function(a,d){function c(h,g){var i=h.nodeName.toLowerCase();if("area"===i){g=h.parentNode;i=g.name;if(!h.href||!i||g.nodeName.toLowerCase()!=="map")return false;h=a("img[usemap=#"+i+"]")[0];return!!h&&e(h)}return(/input|select|textarea|button|object/.test(i)?!h.disabled:"a"==i?h.href||g:g)&&e(h)}function e(h){return!a(h).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.ui=a.ui||{};if(!a.ui.version){a.extend(a.ui,{version:"1.8.16",
+keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(h,g){return typeof h==="number"?this.each(function(){var i=
+this;setTimeout(function(){a(i).focus();g&&g.call(i)},h)}):this._focus.apply(this,arguments)},scrollParent:function(){var h;h=a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,
+"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!h.length?a(document):h},zIndex:function(h){if(h!==d)return this.css("zIndex",h);if(this.length){h=a(this[0]);for(var g;h.length&&h[0]!==document;){g=h.css("position");if(g==="absolute"||g==="relative"||g==="fixed"){g=parseInt(h.css("zIndex"),10);if(!isNaN(g)&&g!==0)return g}h=h.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":
+"mousedown")+".ui-disableSelection",function(h){h.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(h,g){function i(l,o,n,k){a.each(b,function(){o-=parseFloat(a.curCSS(l,"padding"+this,true))||0;if(n)o-=parseFloat(a.curCSS(l,"border"+this+"Width",true))||0;if(k)o-=parseFloat(a.curCSS(l,"margin"+this,true))||0});return o}var b=g==="Width"?["Left","Right"]:["Top","Bottom"],f=g.toLowerCase(),j={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,
+outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+g]=function(l){if(l===d)return j["inner"+g].call(this);return this.each(function(){a(this).css(f,i(this,l)+"px")})};a.fn["outer"+g]=function(l,o){if(typeof l!=="number")return j["outer"+g].call(this,l);return this.each(function(){a(this).css(f,i(this,l,true,o)+"px")})}});a.extend(a.expr[":"],{data:function(h,g,i){return!!a.data(h,i[3])},focusable:function(h){return c(h,!isNaN(a.attr(h,"tabindex")))},tabbable:function(h){var g=a.attr(h,
+"tabindex"),i=isNaN(g);return(i||g>=0)&&c(h,!i)}});a(function(){var h=document.body,g=h.appendChild(g=document.createElement("div"));a.extend(g.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=g.offsetHeight===100;a.support.selectstart="onselectstart"in g;h.removeChild(g).style.display="none"});a.extend(a.ui,{plugin:{add:function(h,g,i){h=a.ui[h].prototype;for(var b in i){h.plugins[b]=h.plugins[b]||[];h.plugins[b].push([g,i[b]])}},call:function(h,g,i){if((g=h.plugins[g])&&
+h.element[0].parentNode)for(var b=0;b<g.length;b++)h.options[g[b][0]]&&g[b][1].apply(h.element,i)}},contains:function(h,g){return document.compareDocumentPosition?h.compareDocumentPosition(g)&16:h!==g&&h.contains(g)},hasScroll:function(h,g){if(a(h).css("overflow")==="hidden")return false;g=g&&g==="left"?"scrollLeft":"scrollTop";var i=false;if(h[g]>0)return true;h[g]=1;i=h[g]>0;h[g]=0;return i},isOverAxis:function(h,g,i){return h>g&&h<g+i},isOver:function(h,g,i,b,f,j){return a.ui.isOverAxis(h,i,f)&&
+a.ui.isOverAxis(g,b,j)}})}})(jQuery);
+(function(a,d){if(a.cleanData){var c=a.cleanData;a.cleanData=function(h){for(var g=0,i;(i=h[g])!=null;g++)try{a(i).triggerHandler("remove")}catch(b){}c(h)}}else{var e=a.fn.remove;a.fn.remove=function(h,g){return this.each(function(){if(!g)if(!h||a.filter(h,[this]).length)a("*",this).add([this]).each(function(){try{a(this).triggerHandler("remove")}catch(i){}});return e.call(a(this),h,g)})}}a.widget=function(h,g,i){var b=h.split(".")[0],f;h=h.split(".")[1];f=b+"-"+h;if(!i){i=g;g=a.Widget}a.expr[":"][f]=
+function(j){return!!a.data(j,h)};a[b]=a[b]||{};a[b][h]=function(j,l){arguments.length&&this._createWidget(j,l)};g=new g;g.options=a.extend(true,{},g.options);a[b][h].prototype=a.extend(true,g,{namespace:b,widgetName:h,widgetEventPrefix:a[b][h].prototype.widgetEventPrefix||h,widgetBaseClass:f},i);a.widget.bridge(h,a[b][h])};a.widget.bridge=function(h,g){a.fn[h]=function(i){var b=typeof i==="string",f=Array.prototype.slice.call(arguments,1),j=this;i=!b&&f.length?a.extend.apply(null,[true,i].concat(f)):
+i;if(b&&i.charAt(0)==="_")return j;b?this.each(function(){var l=a.data(this,h),o=l&&a.isFunction(l[i])?l[i].apply(l,f):l;if(o!==l&&o!==d){j=o;return false}}):this.each(function(){var l=a.data(this,h);l?l.option(i||{})._init():a.data(this,h,new g(i,this))});return j}};a.Widget=function(h,g){arguments.length&&this._createWidget(h,g)};a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(h,g){a.data(g,this.widgetName,this);this.element=a(g);this.options=
+a.extend(true,{},this.options,this._getCreateOptions(),h);var i=this;this.element.bind("remove."+this.widgetName,function(){i.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return a.metadata&&a.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+
+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(h,g){var i=h;if(arguments.length===0)return a.extend({},this.options);if(typeof h==="string"){if(g===d)return this.options[h];i={};i[h]=g}this._setOptions(i);return this},_setOptions:function(h){var g=this;a.each(h,function(i,b){g._setOption(i,b)});return this},_setOption:function(h,g){this.options[h]=g;if(h==="disabled")this.widget()[g?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",
+g);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(h,g,i){var b=this.options[h];g=a.Event(g);g.type=(h===this.widgetEventPrefix?h:this.widgetEventPrefix+h).toLowerCase();i=i||{};if(g.originalEvent){h=a.event.props.length;for(var f;h;){f=a.event.props[--h];g[f]=g.originalEvent[f]}}this.element.trigger(g,i);return!(a.isFunction(b)&&b.call(this.element[0],g,i)===false||g.isDefaultPrevented())}}})(jQuery);
+(function(a){var d=false;a(document).mouseup(function(){d=false});a.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var c=this;this.element.bind("mousedown."+this.widgetName,function(e){return c._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===a.data(e.target,c.widgetName+".preventClickEvent")){a.removeData(e.target,c.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+
+this.widgetName)},_mouseDown:function(c){if(!d){this._mouseStarted&&this._mouseUp(c);this._mouseDownEvent=c;var e=this,h=c.which==1,g=typeof this.options.cancel=="string"&&c.target.nodeName?a(c.target).closest(this.options.cancel).length:false;if(!h||g||!this._mouseCapture(c))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(c)&&this._mouseDelayMet(c)){this._mouseStarted=
+this._mouseStart(c)!==false;if(!this._mouseStarted){c.preventDefault();return true}}true===a.data(c.target,this.widgetName+".preventClickEvent")&&a.removeData(c.target,this.widgetName+".preventClickEvent");this._mouseMoveDelegate=function(i){return e._mouseMove(i)};this._mouseUpDelegate=function(i){return e._mouseUp(i)};a(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.preventDefault();return d=true}},_mouseMove:function(c){if(a.browser.msie&&
+!(document.documentMode>=9)&&!c.button)return this._mouseUp(c);if(this._mouseStarted){this._mouseDrag(c);return c.preventDefault()}if(this._mouseDistanceMet(c)&&this._mouseDelayMet(c))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,c)!==false)?this._mouseDrag(c):this._mouseUp(c);return!this._mouseStarted},_mouseUp:function(c){a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=
+false;c.target==this._mouseDownEvent.target&&a.data(c.target,this.widgetName+".preventClickEvent",true);this._mouseStop(c)}return false},_mouseDistanceMet:function(c){return Math.max(Math.abs(this._mouseDownEvent.pageX-c.pageX),Math.abs(this._mouseDownEvent.pageY-c.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
+(function(a){a.widget("ui.draggable",a.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper==
+"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(d){var c=
+this.options;if(this.helper||c.disabled||a(d.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(d);if(!this.handle)return false;if(c.iframeFix)a(c.iframeFix===true?"iframe":c.iframeFix).each(function(){a('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(a(this).offset()).appendTo("body")});return true},_mouseStart:function(d){var c=this.options;
+this.helper=this._createHelper(d);this._cacheHelperProportions();if(a.ui.ddmanager)a.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};a.extend(this.offset,{click:{left:d.pageX-this.offset.left,top:d.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});
+this.originalPosition=this.position=this._generatePosition(d);this.originalPageX=d.pageX;this.originalPageY=d.pageY;c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt);c.containment&&this._setContainment();if(this._trigger("start",d)===false){this._clear();return false}this._cacheHelperProportions();a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,d);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(d,true);a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,d);return true},
+_mouseDrag:function(d,c){this.position=this._generatePosition(d);this.positionAbs=this._convertPositionTo("absolute");if(!c){c=this._uiHash();if(this._trigger("drag",d,c)===false){this._mouseUp({});return false}this.position=c.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";a.ui.ddmanager&&a.ui.ddmanager.drag(this,d);return false},_mouseStop:function(d){var c=
+false;if(a.ui.ddmanager&&!this.options.dropBehaviour)c=a.ui.ddmanager.drop(this,d);if(this.dropped){c=this.dropped;this.dropped=false}if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return false;if(this.options.revert=="invalid"&&!c||this.options.revert=="valid"&&c||this.options.revert===true||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var e=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,
+10),function(){e._trigger("stop",d)!==false&&e._clear()})}else this._trigger("stop",d)!==false&&this._clear();return false},_mouseUp:function(d){this.options.iframeFix===true&&a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,d);return a.ui.mouse.prototype._mouseUp.call(this,d)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(d){var c=!this.options.handle||
+!a(this.options.handle,this.element).length?true:false;a(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==d.target)c=true});return c},_createHelper:function(d){var c=this.options;d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[d])):c.helper=="clone"?this.element.clone().removeAttr("id"):this.element;d.parents("body").length||d.appendTo(c.appendTo=="parent"?this.element[0].parentNode:c.appendTo);d[0]!=this.element[0]&&!/(fixed|absolute)/.test(d.css("position"))&&
+d.css("position","absolute");return d},_adjustOffsetFromHelper:function(d){if(typeof d=="string")d=d.split(" ");if(a.isArray(d))d={left:+d[0],top:+d[1]||0};if("left"in d)this.offset.click.left=d.left+this.margins.left;if("right"in d)this.offset.click.left=this.helperProportions.width-d.right+this.margins.left;if("top"in d)this.offset.click.top=d.top+this.margins.top;if("bottom"in d)this.offset.click.top=this.helperProportions.height-d.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=
+this.helper.offsetParent();var d=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])){d.left+=this.scrollParent.scrollLeft();d.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)d={top:0,left:0};return{top:d.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:d.left+(parseInt(this.offsetParent.css("borderLeftWidth"),
+10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var d=this.element.position();return{top:d.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:d.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),
+10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var d=this.options;if(d.containment=="parent")d.containment=this.helper[0].parentNode;if(d.containment=="document"||d.containment=="window")this.containment=[d.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,d.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,
+(d.containment=="document"?0:a(window).scrollLeft())+a(d.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(d.containment=="document"?0:a(window).scrollTop())+(a(d.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(d.containment)&&d.containment.constructor!=Array){d=a(d.containment);var c=d[0];if(c){d.offset();var e=a(c).css("overflow")!=
+"hidden";this.containment=[(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0),(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0),(e?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),
+10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom];this.relative_container=d}}else if(d.containment.constructor==Array)this.containment=d.containment},_convertPositionTo:function(d,c){if(!c)c=this.position;d=d=="absolute"?1:-1;var e=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,h=/(html|body)/i.test(e[0].tagName);return{top:c.top+
+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():h?0:e.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():h?0:e.scrollLeft())*d)}},_generatePosition:function(d){var c=this.options,e=this.cssPosition=="absolute"&&
+!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,h=/(html|body)/i.test(e[0].tagName),g=d.pageX,i=d.pageY;if(this.originalPosition){var b;if(this.containment){if(this.relative_container){b=this.relative_container.offset();b=[this.containment[0]+b.left,this.containment[1]+b.top,this.containment[2]+b.left,this.containment[3]+b.top]}else b=this.containment;if(d.pageX-this.offset.click.left<b[0])g=b[0]+this.offset.click.left;
+if(d.pageY-this.offset.click.top<b[1])i=b[1]+this.offset.click.top;if(d.pageX-this.offset.click.left>b[2])g=b[2]+this.offset.click.left;if(d.pageY-this.offset.click.top>b[3])i=b[3]+this.offset.click.top}if(c.grid){i=c.grid[1]?this.originalPageY+Math.round((i-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY;i=b?!(i-this.offset.click.top<b[1]||i-this.offset.click.top>b[3])?i:!(i-this.offset.click.top<b[1])?i-c.grid[1]:i+c.grid[1]:i;g=c.grid[0]?this.originalPageX+Math.round((g-this.originalPageX)/
+c.grid[0])*c.grid[0]:this.originalPageX;g=b?!(g-this.offset.click.left<b[0]||g-this.offset.click.left>b[2])?g:!(g-this.offset.click.left<b[0])?g-c.grid[0]:g+c.grid[0]:g}}return{top:i-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():h?0:e.scrollTop()),left:g-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&a.browser.version<
+526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():h?0:e.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=false},_trigger:function(d,c,e){e=e||this._uiHash();a.ui.plugin.call(this,d,[c,e]);if(d=="drag")this.positionAbs=this._convertPositionTo("absolute");return a.Widget.prototype._trigger.call(this,d,c,
+e)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});a.extend(a.ui.draggable,{version:"1.8.16"});a.ui.plugin.add("draggable","connectToSortable",{start:function(d,c){var e=a(this).data("draggable"),h=e.options,g=a.extend({},c,{item:e.element});e.sortables=[];a(h.connectToSortable).each(function(){var i=a.data(this,"sortable");if(i&&!i.options.disabled){e.sortables.push({instance:i,shouldRevert:i.options.revert});
+i.refreshPositions();i._trigger("activate",d,g)}})},stop:function(d,c){var e=a(this).data("draggable"),h=a.extend({},c,{item:e.element});a.each(e.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;e.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert)this.instance.options.revert=true;this.instance._mouseStop(d);this.instance.options.helper=this.instance.options._helper;e.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})}else{this.instance.cancelHelperRemoval=
+false;this.instance._trigger("deactivate",d,h)}})},drag:function(d,c){var e=a(this).data("draggable"),h=this;a.each(e.sortables,function(){this.instance.positionAbs=e.positionAbs;this.instance.helperProportions=e.helperProportions;this.instance.offset.click=e.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=a(h).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",true);
+this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return c.helper[0]};d.target=this.instance.currentItem[0];this.instance._mouseCapture(d,true);this.instance._mouseStart(d,true,true);this.instance.offset.click.top=e.offset.click.top;this.instance.offset.click.left=e.offset.click.left;this.instance.offset.parent.left-=e.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=e.offset.parent.top-this.instance.offset.parent.top;
+e._trigger("toSortable",d);e.dropped=this.instance.element;e.currentItem=e.element;this.instance.fromOutside=e}this.instance.currentItem&&this.instance._mouseDrag(d)}else if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",d,this.instance._uiHash(this.instance));this.instance._mouseStop(d,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();this.instance.placeholder&&
+this.instance.placeholder.remove();e._trigger("fromSortable",d);e.dropped=false}})}});a.ui.plugin.add("draggable","cursor",{start:function(){var d=a("body"),c=a(this).data("draggable").options;if(d.css("cursor"))c._cursor=d.css("cursor");d.css("cursor",c.cursor)},stop:function(){var d=a(this).data("draggable").options;d._cursor&&a("body").css("cursor",d._cursor)}});a.ui.plugin.add("draggable","opacity",{start:function(d,c){d=a(c.helper);c=a(this).data("draggable").options;if(d.css("opacity"))c._opacity=
+d.css("opacity");d.css("opacity",c.opacity)},stop:function(d,c){d=a(this).data("draggable").options;d._opacity&&a(c.helper).css("opacity",d._opacity)}});a.ui.plugin.add("draggable","scroll",{start:function(){var d=a(this).data("draggable");if(d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML")d.overflowOffset=d.scrollParent.offset()},drag:function(d){var c=a(this).data("draggable"),e=c.options,h=false;if(c.scrollParent[0]!=document&&c.scrollParent[0].tagName!="HTML"){if(!e.axis||e.axis!=
+"x")if(c.overflowOffset.top+c.scrollParent[0].offsetHeight-d.pageY<e.scrollSensitivity)c.scrollParent[0].scrollTop=h=c.scrollParent[0].scrollTop+e.scrollSpeed;else if(d.pageY-c.overflowOffset.top<e.scrollSensitivity)c.scrollParent[0].scrollTop=h=c.scrollParent[0].scrollTop-e.scrollSpeed;if(!e.axis||e.axis!="y")if(c.overflowOffset.left+c.scrollParent[0].offsetWidth-d.pageX<e.scrollSensitivity)c.scrollParent[0].scrollLeft=h=c.scrollParent[0].scrollLeft+e.scrollSpeed;else if(d.pageX-c.overflowOffset.left<
+e.scrollSensitivity)c.scrollParent[0].scrollLeft=h=c.scrollParent[0].scrollLeft-e.scrollSpeed}else{if(!e.axis||e.axis!="x")if(d.pageY-a(document).scrollTop()<e.scrollSensitivity)h=a(document).scrollTop(a(document).scrollTop()-e.scrollSpeed);else if(a(window).height()-(d.pageY-a(document).scrollTop())<e.scrollSensitivity)h=a(document).scrollTop(a(document).scrollTop()+e.scrollSpeed);if(!e.axis||e.axis!="y")if(d.pageX-a(document).scrollLeft()<e.scrollSensitivity)h=a(document).scrollLeft(a(document).scrollLeft()-
+e.scrollSpeed);else if(a(window).width()-(d.pageX-a(document).scrollLeft())<e.scrollSensitivity)h=a(document).scrollLeft(a(document).scrollLeft()+e.scrollSpeed)}h!==false&&a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(c,d)}});a.ui.plugin.add("draggable","snap",{start:function(){var d=a(this).data("draggable"),c=d.options;d.snapElements=[];a(c.snap.constructor!=String?c.snap.items||":data(draggable)":c.snap).each(function(){var e=a(this),h=e.offset();this!=d.element[0]&&d.snapElements.push({item:this,
+width:e.outerWidth(),height:e.outerHeight(),top:h.top,left:h.left})})},drag:function(d,c){for(var e=a(this).data("draggable"),h=e.options,g=h.snapTolerance,i=c.offset.left,b=i+e.helperProportions.width,f=c.offset.top,j=f+e.helperProportions.height,l=e.snapElements.length-1;l>=0;l--){var o=e.snapElements[l].left,n=o+e.snapElements[l].width,k=e.snapElements[l].top,m=k+e.snapElements[l].height;if(o-g<i&&i<n+g&&k-g<f&&f<m+g||o-g<i&&i<n+g&&k-g<j&&j<m+g||o-g<b&&b<n+g&&k-g<f&&f<m+g||o-g<b&&b<n+g&&k-g<j&&
+j<m+g){if(h.snapMode!="inner"){var p=Math.abs(k-j)<=g,q=Math.abs(m-f)<=g,s=Math.abs(o-b)<=g,r=Math.abs(n-i)<=g;if(p)c.position.top=e._convertPositionTo("relative",{top:k-e.helperProportions.height,left:0}).top-e.margins.top;if(q)c.position.top=e._convertPositionTo("relative",{top:m,left:0}).top-e.margins.top;if(s)c.position.left=e._convertPositionTo("relative",{top:0,left:o-e.helperProportions.width}).left-e.margins.left;if(r)c.position.left=e._convertPositionTo("relative",{top:0,left:n}).left-e.margins.left}var u=
+p||q||s||r;if(h.snapMode!="outer"){p=Math.abs(k-f)<=g;q=Math.abs(m-j)<=g;s=Math.abs(o-i)<=g;r=Math.abs(n-b)<=g;if(p)c.position.top=e._convertPositionTo("relative",{top:k,left:0}).top-e.margins.top;if(q)c.position.top=e._convertPositionTo("relative",{top:m-e.helperProportions.height,left:0}).top-e.margins.top;if(s)c.position.left=e._convertPositionTo("relative",{top:0,left:o}).left-e.margins.left;if(r)c.position.left=e._convertPositionTo("relative",{top:0,left:n-e.helperProportions.width}).left-e.margins.left}if(!e.snapElements[l].snapping&&
+(p||q||s||r||u))e.options.snap.snap&&e.options.snap.snap.call(e.element,d,a.extend(e._uiHash(),{snapItem:e.snapElements[l].item}));e.snapElements[l].snapping=p||q||s||r||u}else{e.snapElements[l].snapping&&e.options.snap.release&&e.options.snap.release.call(e.element,d,a.extend(e._uiHash(),{snapItem:e.snapElements[l].item}));e.snapElements[l].snapping=false}}}});a.ui.plugin.add("draggable","stack",{start:function(){var d=a(this).data("draggable").options;d=a.makeArray(a(d.stack)).sort(function(e,h){return(parseInt(a(e).css("zIndex"),
+10)||0)-(parseInt(a(h).css("zIndex"),10)||0)});if(d.length){var c=parseInt(d[0].style.zIndex)||0;a(d).each(function(e){this.style.zIndex=c+e});this[0].style.zIndex=c+d.length}}});a.ui.plugin.add("draggable","zIndex",{start:function(d,c){d=a(c.helper);c=a(this).data("draggable").options;if(d.css("zIndex"))c._zIndex=d.css("zIndex");d.css("zIndex",c.zIndex)},stop:function(d,c){d=a(this).data("draggable").options;d._zIndex&&a(c.helper).css("zIndex",d._zIndex)}})})(jQuery);
+(function(a){a.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:false,addClasses:true,greedy:false,hoverClass:false,scope:"default",tolerance:"intersect"},_create:function(){var d=this.options,c=d.accept;this.isover=0;this.isout=1;this.accept=a.isFunction(c)?c:function(e){return e.is(c)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};a.ui.ddmanager.droppables[d.scope]=a.ui.ddmanager.droppables[d.scope]||[];a.ui.ddmanager.droppables[d.scope].push(this);
+d.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){for(var d=a.ui.ddmanager.droppables[this.options.scope],c=0;c<d.length;c++)d[c]==this&&d.splice(c,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(d,c){if(d=="accept")this.accept=a.isFunction(c)?c:function(e){return e.is(c)};a.Widget.prototype._setOption.apply(this,arguments)},_activate:function(d){var c=a.ui.ddmanager.current;this.options.activeClass&&
+this.element.addClass(this.options.activeClass);c&&this._trigger("activate",d,this.ui(c))},_deactivate:function(d){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass);c&&this._trigger("deactivate",d,this.ui(c))},_over:function(d){var c=a.ui.ddmanager.current;if(!(!c||(c.currentItem||c.element)[0]==this.element[0]))if(this.accept.call(this.element[0],c.currentItem||c.element)){this.options.hoverClass&&this.element.addClass(this.options.hoverClass);
+this._trigger("over",d,this.ui(c))}},_out:function(d){var c=a.ui.ddmanager.current;if(!(!c||(c.currentItem||c.element)[0]==this.element[0]))if(this.accept.call(this.element[0],c.currentItem||c.element)){this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("out",d,this.ui(c))}},_drop:function(d,c){var e=c||a.ui.ddmanager.current;if(!e||(e.currentItem||e.element)[0]==this.element[0])return false;var h=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var g=
+a.data(this,"droppable");if(g.options.greedy&&!g.options.disabled&&g.options.scope==e.options.scope&&g.accept.call(g.element[0],e.currentItem||e.element)&&a.ui.intersect(e,a.extend(g,{offset:g.element.offset()}),g.options.tolerance)){h=true;return false}});if(h)return false;if(this.accept.call(this.element[0],e.currentItem||e.element)){this.options.activeClass&&this.element.removeClass(this.options.activeClass);this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("drop",
+d,this.ui(e));return this.element}return false},ui:function(d){return{draggable:d.currentItem||d.element,helper:d.helper,position:d.position,offset:d.positionAbs}}});a.extend(a.ui.droppable,{version:"1.8.16"});a.ui.intersect=function(d,c,e){if(!c.offset)return false;var h=(d.positionAbs||d.position.absolute).left,g=h+d.helperProportions.width,i=(d.positionAbs||d.position.absolute).top,b=i+d.helperProportions.height,f=c.offset.left,j=f+c.proportions.width,l=c.offset.top,o=l+c.proportions.height;
+switch(e){case "fit":return f<=h&&g<=j&&l<=i&&b<=o;case "intersect":return f<h+d.helperProportions.width/2&&g-d.helperProportions.width/2<j&&l<i+d.helperProportions.height/2&&b-d.helperProportions.height/2<o;case "pointer":return a.ui.isOver((d.positionAbs||d.position.absolute).top+(d.clickOffset||d.offset.click).top,(d.positionAbs||d.position.absolute).left+(d.clickOffset||d.offset.click).left,l,f,c.proportions.height,c.proportions.width);case "touch":return(i>=l&&i<=o||b>=l&&b<=o||i<l&&b>o)&&(h>=
+f&&h<=j||g>=f&&g<=j||h<f&&g>j);default:return false}};a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(d,c){var e=a.ui.ddmanager.droppables[d.options.scope]||[],h=c?c.type:null,g=(d.currentItem||d.element).find(":data(droppable)").andSelf(),i=0;a:for(;i<e.length;i++)if(!(e[i].options.disabled||d&&!e[i].accept.call(e[i].element[0],d.currentItem||d.element))){for(var b=0;b<g.length;b++)if(g[b]==e[i].element[0]){e[i].proportions.height=0;continue a}e[i].visible=e[i].element.css("display")!=
+"none";if(e[i].visible){h=="mousedown"&&e[i]._activate.call(e[i],c);e[i].offset=e[i].element.offset();e[i].proportions={width:e[i].element[0].offsetWidth,height:e[i].element[0].offsetHeight}}}},drop:function(d,c){var e=false;a.each(a.ui.ddmanager.droppables[d.options.scope]||[],function(){if(this.options){if(!this.options.disabled&&this.visible&&a.ui.intersect(d,this,this.options.tolerance))e=e||this._drop.call(this,c);if(!this.options.disabled&&this.visible&&this.accept.call(this.element[0],d.currentItem||
+d.element)){this.isout=1;this.isover=0;this._deactivate.call(this,c)}}});return e},dragStart:function(d,c){d.element.parents(":not(body,html)").bind("scroll.droppable",function(){d.options.refreshPositions||a.ui.ddmanager.prepareOffsets(d,c)})},drag:function(d,c){d.options.refreshPositions&&a.ui.ddmanager.prepareOffsets(d,c);a.each(a.ui.ddmanager.droppables[d.options.scope]||[],function(){if(!(this.options.disabled||this.greedyChild||!this.visible)){var e=a.ui.intersect(d,this,this.options.tolerance);
+if(e=!e&&this.isover==1?"isout":e&&this.isover==0?"isover":null){var h;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");if(g.length){h=a.data(g[0],"droppable");h.greedyChild=e=="isover"?1:0}}if(h&&e=="isover"){h.isover=0;h.isout=1;h._out.call(h,c)}this[e]=1;this[e=="isout"?"isover":"isout"]=0;this[e=="isover"?"_over":"_out"].call(this,c);if(h&&e=="isout"){h.isout=0;h.isover=1;h._over.call(h,c)}}}})},dragStop:function(d,c){d.element.parents(":not(body,html)").unbind("scroll.droppable");
+d.options.refreshPositions||a.ui.ddmanager.prepareOffsets(d,c)}}})(jQuery);
+(function(a){a.widget("ui.resizable",a.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var e=this,h=this.options;this.element.addClass("ui-resizable");a.extend(this,{_aspectRatio:!!h.aspectRatio,aspectRatio:h.aspectRatio,originalElement:this.element,
+_proportionallyResizeElements:[],_helper:h.helper||h.ghost||h.animate?h.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&a.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"});this.element.wrap(a('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),
+top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=
+this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=h.handles||(!a(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",
+nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var g=this.handles.split(",");this.handles={};for(var i=0;i<g.length;i++){var b=a.trim(g[i]),f=a('<div class="ui-resizable-handle '+("ui-resizable-"+b)+'"></div>');/sw|se|ne|nw/.test(b)&&f.css({zIndex:++h.zIndex});"se"==b&&f.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[b]=".ui-resizable-"+b;this.element.append(f)}}this._renderAxis=function(j){j=j||this.element;for(var l in this.handles){if(this.handles[l].constructor==
+String)this.handles[l]=a(this.handles[l],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=a(this.handles[l],this.element),n=0;n=/sw|ne|nw|se|n|s/.test(l)?o.outerHeight():o.outerWidth();o=["padding",/ne|nw|n/.test(l)?"Top":/se|sw|s/.test(l)?"Bottom":/^e$/.test(l)?"Right":"Left"].join("");j.css(o,n);this._proportionallyResize()}a(this.handles[l])}};this._renderAxis(this.element);this._handles=a(".ui-resizable-handle",this.element).disableSelection();
+this._handles.mouseover(function(){if(!e.resizing){if(this.className)var j=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);e.axis=j&&j[1]?j[1]:"se"}});if(h.autoHide){this._handles.hide();a(this.element).addClass("ui-resizable-autohide").hover(function(){if(!h.disabled){a(this).removeClass("ui-resizable-autohide");e._handles.show()}},function(){if(!h.disabled)if(!e.resizing){a(this).addClass("ui-resizable-autohide");e._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();
+var e=function(g){a(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var h=this.element;h.after(this.originalElement.css({position:h.css("position"),width:h.outerWidth(),height:h.outerHeight(),top:h.css("top"),left:h.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(e){var h=
+false;for(var g in this.handles)if(a(this.handles[g])[0]==e.target)h=true;return!this.options.disabled&&h},_mouseStart:function(e){var h=this.options,g=this.element.position(),i=this.element;this.resizing=true;this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()};if(i.is(".ui-draggable")||/absolute/.test(i.css("position")))i.css({position:"absolute",top:g.top,left:g.left});a.browser.opera&&/relative/.test(i.css("position"))&&i.css({position:"relative",top:"auto",left:"auto"});
+this._renderProxy();g=d(this.helper.css("left"));var b=d(this.helper.css("top"));if(h.containment){g+=a(h.containment).scrollLeft()||0;b+=a(h.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:g,top:b};this.size=this._helper?{width:i.outerWidth(),height:i.outerHeight()}:{width:i.width(),height:i.height()};this.originalSize=this._helper?{width:i.outerWidth(),height:i.outerHeight()}:{width:i.width(),height:i.height()};this.originalPosition={left:g,top:b};this.sizeDiff=
+{width:i.outerWidth()-i.width(),height:i.outerHeight()-i.height()};this.originalMousePosition={left:e.pageX,top:e.pageY};this.aspectRatio=typeof h.aspectRatio=="number"?h.aspectRatio:this.originalSize.width/this.originalSize.height||1;h=a(".ui-resizable-"+this.axis).css("cursor");a("body").css("cursor",h=="auto"?this.axis+"-resize":h);i.addClass("ui-resizable-resizing");this._propagate("start",e);return true},_mouseDrag:function(e){var h=this.helper,g=this.originalMousePosition,i=this._change[this.axis];
+if(!i)return false;g=i.apply(this,[e,e.pageX-g.left||0,e.pageY-g.top||0]);this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey)g=this._updateRatio(g,e);g=this._respectSize(g,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(g);this._trigger("resize",e,this.ui());return false},
+_mouseStop:function(e){this.resizing=false;var h=this.options,g=this;if(this._helper){var i=this._proportionallyResizeElements,b=i.length&&/textarea/i.test(i[0].nodeName);i=b&&a.ui.hasScroll(i[0],"left")?0:g.sizeDiff.height;b=b?0:g.sizeDiff.width;b={width:g.helper.width()-b,height:g.helper.height()-i};i=parseInt(g.element.css("left"),10)+(g.position.left-g.originalPosition.left)||null;var f=parseInt(g.element.css("top"),10)+(g.position.top-g.originalPosition.top)||null;h.animate||this.element.css(a.extend(b,
+{top:f,left:i}));g.helper.height(g.size.height);g.helper.width(g.size.width);this._helper&&!h.animate&&this._proportionallyResize()}a("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",e);this._helper&&this.helper.remove();return false},_updateVirtualBoundaries:function(e){var h=this.options,g,i,b;h={minWidth:c(h.minWidth)?h.minWidth:0,maxWidth:c(h.maxWidth)?h.maxWidth:Infinity,minHeight:c(h.minHeight)?h.minHeight:0,maxHeight:c(h.maxHeight)?h.maxHeight:
+Infinity};if(this._aspectRatio||e){e=h.minHeight*this.aspectRatio;i=h.minWidth/this.aspectRatio;g=h.maxHeight*this.aspectRatio;b=h.maxWidth/this.aspectRatio;if(e>h.minWidth)h.minWidth=e;if(i>h.minHeight)h.minHeight=i;if(g<h.maxWidth)h.maxWidth=g;if(b<h.maxHeight)h.maxHeight=b}this._vBoundaries=h},_updateCache:function(e){this.offset=this.helper.offset();if(c(e.left))this.position.left=e.left;if(c(e.top))this.position.top=e.top;if(c(e.height))this.size.height=e.height;if(c(e.width))this.size.width=
+e.width},_updateRatio:function(e){var h=this.position,g=this.size,i=this.axis;if(c(e.height))e.width=e.height*this.aspectRatio;else if(c(e.width))e.height=e.width/this.aspectRatio;if(i=="sw"){e.left=h.left+(g.width-e.width);e.top=null}if(i=="nw"){e.top=h.top+(g.height-e.height);e.left=h.left+(g.width-e.width)}return e},_respectSize:function(e){var h=this._vBoundaries,g=this.axis,i=c(e.width)&&h.maxWidth&&h.maxWidth<e.width,b=c(e.height)&&h.maxHeight&&h.maxHeight<e.height,f=c(e.width)&&h.minWidth&&
+h.minWidth>e.width,j=c(e.height)&&h.minHeight&&h.minHeight>e.height;if(f)e.width=h.minWidth;if(j)e.height=h.minHeight;if(i)e.width=h.maxWidth;if(b)e.height=h.maxHeight;var l=this.originalPosition.left+this.originalSize.width,o=this.position.top+this.size.height,n=/sw|nw|w/.test(g);g=/nw|ne|n/.test(g);if(f&&n)e.left=l-h.minWidth;if(i&&n)e.left=l-h.maxWidth;if(j&&g)e.top=o-h.minHeight;if(b&&g)e.top=o-h.maxHeight;if((h=!e.width&&!e.height)&&!e.left&&e.top)e.top=null;else if(h&&!e.top&&e.left)e.left=
+null;return e},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var e=this.helper||this.element,h=0;h<this._proportionallyResizeElements.length;h++){var g=this._proportionallyResizeElements[h];if(!this.borderDif){var i=[g.css("borderTopWidth"),g.css("borderRightWidth"),g.css("borderBottomWidth"),g.css("borderLeftWidth")],b=[g.css("paddingTop"),g.css("paddingRight"),g.css("paddingBottom"),g.css("paddingLeft")];this.borderDif=a.map(i,function(f,j){f=parseInt(f,10)||
+0;j=parseInt(b[j],10)||0;return f+j})}a.browser.msie&&(a(e).is(":hidden")||a(e).parents(":hidden").length)||g.css({height:e.height()-this.borderDif[0]-this.borderDif[2]||0,width:e.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var e=this.options;this.elementOffset=this.element.offset();if(this._helper){this.helper=this.helper||a('<div style="overflow:hidden;"></div>');var h=a.browser.msie&&a.browser.version<7,g=h?1:0;h=h?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+
+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++e.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(e,h){return{width:this.originalSize.width+h}},w:function(e,h){return{left:this.originalPosition.left+h,width:this.originalSize.width-h}},n:function(e,h,g){return{top:this.originalPosition.top+g,height:this.originalSize.height-g}},s:function(e,h,g){return{height:this.originalSize.height+
+g}},se:function(e,h,g){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,h,g]))},sw:function(e,h,g){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,h,g]))},ne:function(e,h,g){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,h,g]))},nw:function(e,h,g){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,h,g]))}},_propagate:function(e,h){a.ui.plugin.call(this,e,[h,this.ui()]);
+e!="resize"&&this._trigger(e,h,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});a.extend(a.ui.resizable,{version:"1.8.16"});a.ui.plugin.add("resizable","alsoResize",{start:function(){var e=a(this).data("resizable").options,h=function(g){a(g).each(function(){var i=a(this);i.data("resizable-alsoresize",{width:parseInt(i.width(),
+10),height:parseInt(i.height(),10),left:parseInt(i.css("left"),10),top:parseInt(i.css("top"),10),position:i.css("position")})})};if(typeof e.alsoResize=="object"&&!e.alsoResize.parentNode)if(e.alsoResize.length){e.alsoResize=e.alsoResize[0];h(e.alsoResize)}else a.each(e.alsoResize,function(g){h(g)});else h(e.alsoResize)},resize:function(e,h){var g=a(this).data("resizable");e=g.options;var i=g.originalSize,b=g.originalPosition,f={height:g.size.height-i.height||0,width:g.size.width-i.width||0,top:g.position.top-
+b.top||0,left:g.position.left-b.left||0},j=function(l,o){a(l).each(function(){var n=a(this),k=a(this).data("resizable-alsoresize"),m={},p=o&&o.length?o:n.parents(h.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(p,function(q,s){if((q=(k[s]||0)+(f[s]||0))&&q>=0)m[s]=q||null});if(a.browser.opera&&/relative/.test(n.css("position"))){g._revertToRelativePosition=true;n.css({position:"absolute",top:"auto",left:"auto"})}n.css(m)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?
+a.each(e.alsoResize,function(l,o){j(l,o)}):j(e.alsoResize)},stop:function(){var e=a(this).data("resizable"),h=e.options,g=function(i){a(i).each(function(){var b=a(this);b.css({position:b.data("resizable-alsoresize").position})})};if(e._revertToRelativePosition){e._revertToRelativePosition=false;typeof h.alsoResize=="object"&&!h.alsoResize.nodeType?a.each(h.alsoResize,function(i){g(i)}):g(h.alsoResize)}a(this).removeData("resizable-alsoresize")}});a.ui.plugin.add("resizable","animate",{stop:function(e){var h=
+a(this).data("resizable"),g=h.options,i=h._proportionallyResizeElements,b=i.length&&/textarea/i.test(i[0].nodeName),f=b&&a.ui.hasScroll(i[0],"left")?0:h.sizeDiff.height;b={width:h.size.width-(b?0:h.sizeDiff.width),height:h.size.height-f};f=parseInt(h.element.css("left"),10)+(h.position.left-h.originalPosition.left)||null;var j=parseInt(h.element.css("top"),10)+(h.position.top-h.originalPosition.top)||null;h.element.animate(a.extend(b,j&&f?{top:j,left:f}:{}),{duration:g.animateDuration,easing:g.animateEasing,
+step:function(){var l={width:parseInt(h.element.css("width"),10),height:parseInt(h.element.css("height"),10),top:parseInt(h.element.css("top"),10),left:parseInt(h.element.css("left"),10)};i&&i.length&&a(i[0]).css({width:l.width,height:l.height});h._updateCache(l);h._propagate("resize",e)}})}});a.ui.plugin.add("resizable","containment",{start:function(){var e=a(this).data("resizable"),h=e.element,g=e.options.containment;if(h=g instanceof a?g.get(0):/parent/.test(g)?h.parent().get(0):g){e.containerElement=
+a(h);if(/document/.test(g)||g==document){e.containerOffset={left:0,top:0};e.containerPosition={left:0,top:0};e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight}}else{var i=a(h),b=[];a(["Top","Right","Left","Bottom"]).each(function(l,o){b[l]=d(i.css("padding"+o))});e.containerOffset=i.offset();e.containerPosition=i.position();e.containerSize={height:i.innerHeight()-b[3],width:i.innerWidth()-b[1]};g=e.containerOffset;
+var f=e.containerSize.height,j=e.containerSize.width;j=a.ui.hasScroll(h,"left")?h.scrollWidth:j;f=a.ui.hasScroll(h)?h.scrollHeight:f;e.parentData={element:h,left:g.left,top:g.top,width:j,height:f}}}},resize:function(e){var h=a(this).data("resizable"),g=h.options,i=h.containerOffset,b=h.position;e=h._aspectRatio||e.shiftKey;var f={top:0,left:0},j=h.containerElement;if(j[0]!=document&&/static/.test(j.css("position")))f=i;if(b.left<(h._helper?i.left:0)){h.size.width+=h._helper?h.position.left-i.left:
+h.position.left-f.left;if(e)h.size.height=h.size.width/g.aspectRatio;h.position.left=g.helper?i.left:0}if(b.top<(h._helper?i.top:0)){h.size.height+=h._helper?h.position.top-i.top:h.position.top;if(e)h.size.width=h.size.height*g.aspectRatio;h.position.top=h._helper?i.top:0}h.offset.left=h.parentData.left+h.position.left;h.offset.top=h.parentData.top+h.position.top;g=Math.abs((h._helper?h.offset.left-f.left:h.offset.left-f.left)+h.sizeDiff.width);i=Math.abs((h._helper?h.offset.top-f.top:h.offset.top-
+i.top)+h.sizeDiff.height);b=h.containerElement.get(0)==h.element.parent().get(0);f=/relative|absolute/.test(h.containerElement.css("position"));if(b&&f)g-=h.parentData.left;if(g+h.size.width>=h.parentData.width){h.size.width=h.parentData.width-g;if(e)h.size.height=h.size.width/h.aspectRatio}if(i+h.size.height>=h.parentData.height){h.size.height=h.parentData.height-i;if(e)h.size.width=h.size.height*h.aspectRatio}},stop:function(){var e=a(this).data("resizable"),h=e.options,g=e.containerOffset,i=e.containerPosition,
+b=e.containerElement,f=a(e.helper),j=f.offset(),l=f.outerWidth()-e.sizeDiff.width;f=f.outerHeight()-e.sizeDiff.height;e._helper&&!h.animate&&/relative/.test(b.css("position"))&&a(this).css({left:j.left-i.left-g.left,width:l,height:f});e._helper&&!h.animate&&/static/.test(b.css("position"))&&a(this).css({left:j.left-i.left-g.left,width:l,height:f})}});a.ui.plugin.add("resizable","ghost",{start:function(){var e=a(this).data("resizable"),h=e.options,g=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,
+display:"block",position:"relative",height:g.height,width:g.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof h.ghost=="string"?h.ghost:"");e.ghost.appendTo(e.helper)},resize:function(){var e=a(this).data("resizable");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=a(this).data("resizable");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}});a.ui.plugin.add("resizable","grid",{resize:function(){var e=
+a(this).data("resizable"),h=e.options,g=e.size,i=e.originalSize,b=e.originalPosition,f=e.axis;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var j=Math.round((g.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1);h=Math.round((g.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(f)){e.size.width=i.width+j;e.size.height=i.height+h}else if(/^(ne)$/.test(f)){e.size.width=i.width+j;e.size.height=i.height+h;e.position.top=b.top-h}else{if(/^(sw)$/.test(f)){e.size.width=i.width+j;e.size.height=
+i.height+h}else{e.size.width=i.width+j;e.size.height=i.height+h;e.position.top=b.top-h}e.position.left=b.left-j}}});var d=function(e){return parseInt(e,10)||0},c=function(e){return!isNaN(parseInt(e,10))}})(jQuery);
+(function(a){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var d=this;this.element.addClass("ui-selectable");this.dragged=false;var c;this.refresh=function(){c=a(d.options.filter,d.element[0]);c.each(function(){var e=a(this),h=e.offset();a.data(this,"selectable-item",{element:this,$element:e,left:h.left,top:h.top,right:h.left+e.outerWidth(),bottom:h.top+e.outerHeight(),startselected:false,selected:e.hasClass("ui-selected"),
+selecting:e.hasClass("ui-selecting"),unselecting:e.hasClass("ui-unselecting")})})};this.refresh();this.selectees=c.addClass("ui-selectee");this._mouseInit();this.helper=a("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(d){var c=this;this.opos=[d.pageX,
+d.pageY];if(!this.options.disabled){var e=this.options;this.selectees=a(e.filter,this.element[0]);this._trigger("start",d);a(e.appendTo).append(this.helper);this.helper.css({left:d.clientX,top:d.clientY,width:0,height:0});e.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var h=a.data(this,"selectable-item");h.startselected=true;if(!d.metaKey){h.$element.removeClass("ui-selected");h.selected=false;h.$element.addClass("ui-unselecting");h.unselecting=true;c._trigger("unselecting",
+d,{unselecting:h.element})}});a(d.target).parents().andSelf().each(function(){var h=a.data(this,"selectable-item");if(h){var g=!d.metaKey||!h.$element.hasClass("ui-selected");h.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");h.unselecting=!g;h.selecting=g;(h.selected=g)?c._trigger("selecting",d,{selecting:h.element}):c._trigger("unselecting",d,{unselecting:h.element});return false}})}},_mouseDrag:function(d){var c=this;this.dragged=true;if(!this.options.disabled){var e=
+this.options,h=this.opos[0],g=this.opos[1],i=d.pageX,b=d.pageY;if(h>i){var f=i;i=h;h=f}if(g>b){f=b;b=g;g=f}this.helper.css({left:h,top:g,width:i-h,height:b-g});this.selectees.each(function(){var j=a.data(this,"selectable-item");if(!(!j||j.element==c.element[0])){var l=false;if(e.tolerance=="touch")l=!(j.left>i||j.right<h||j.top>b||j.bottom<g);else if(e.tolerance=="fit")l=j.left>h&&j.right<i&&j.top>g&&j.bottom<b;if(l){if(j.selected){j.$element.removeClass("ui-selected");j.selected=false}if(j.unselecting){j.$element.removeClass("ui-unselecting");
+j.unselecting=false}if(!j.selecting){j.$element.addClass("ui-selecting");j.selecting=true;c._trigger("selecting",d,{selecting:j.element})}}else{if(j.selecting)if(d.metaKey&&j.startselected){j.$element.removeClass("ui-selecting");j.selecting=false;j.$element.addClass("ui-selected");j.selected=true}else{j.$element.removeClass("ui-selecting");j.selecting=false;if(j.startselected){j.$element.addClass("ui-unselecting");j.unselecting=true}c._trigger("unselecting",d,{unselecting:j.element})}if(j.selected)if(!d.metaKey&&
+!j.startselected){j.$element.removeClass("ui-selected");j.selected=false;j.$element.addClass("ui-unselecting");j.unselecting=true;c._trigger("unselecting",d,{unselecting:j.element})}}}});return false}},_mouseStop:function(d){var c=this;this.dragged=false;a(".ui-unselecting",this.element[0]).each(function(){var e=a.data(this,"selectable-item");e.$element.removeClass("ui-unselecting");e.unselecting=false;e.startselected=false;c._trigger("unselected",d,{unselected:e.element})});a(".ui-selecting",this.element[0]).each(function(){var e=
+a.data(this,"selectable-item");e.$element.removeClass("ui-selecting").addClass("ui-selected");e.selecting=false;e.selected=true;e.startselected=true;c._trigger("selected",d,{selected:e.element})});this._trigger("stop",d);this.helper.remove();return false}});a.extend(a.ui.selectable,{version:"1.8.16"})})(jQuery);
+(function(a){a.widget("ui.sortable",a.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var d=this.options;this.containerCache={};this.element.addClass("ui-sortable");
+this.refresh();this.floating=this.items.length?d.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var d=this.items.length-1;d>=0;d--)this.items[d].item.removeData("sortable-item");return this},_setOption:function(d,c){if(d===
+"disabled"){this.options[d]=c;this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")}else a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(d,c){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(d);var e=null,h=this;a(d.target).parents().each(function(){if(a.data(this,"sortable-item")==h){e=a(this);return false}});if(a.data(d.target,"sortable-item")==h)e=a(d.target);if(!e)return false;if(this.options.handle&&
+!c){var g=false;a(this.options.handle,e).find("*").andSelf().each(function(){if(this==d.target)g=true});if(!g)return false}this.currentItem=e;this._removeCurrentsFromItems();return true},_mouseStart:function(d,c,e){c=this.options;var h=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(d);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,
+left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");a.extend(this.offset,{click:{left:d.pageX-this.offset.left,top:d.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(d);this.originalPageX=d.pageX;this.originalPageY=d.pageY;c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};
+this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();c.containment&&this._setContainment();if(c.cursor){if(a("body").css("cursor"))this._storedCursor=a("body").css("cursor");a("body").css("cursor",c.cursor)}if(c.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",c.opacity)}if(c.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",c.zIndex)}if(this.scrollParent[0]!=
+document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",d,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!e)for(e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("activate",d,h._uiHash(this));if(a.ui.ddmanager)a.ui.ddmanager.current=this;a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,d);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(d);
+return true},_mouseDrag:function(d){this.position=this._generatePosition(d);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var c=this.options,e=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-d.pageY<c.scrollSensitivity)this.scrollParent[0].scrollTop=e=this.scrollParent[0].scrollTop+c.scrollSpeed;else if(d.pageY-this.overflowOffset.top<
+c.scrollSensitivity)this.scrollParent[0].scrollTop=e=this.scrollParent[0].scrollTop-c.scrollSpeed;if(this.overflowOffset.left+this.scrollParent[0].offsetWidth-d.pageX<c.scrollSensitivity)this.scrollParent[0].scrollLeft=e=this.scrollParent[0].scrollLeft+c.scrollSpeed;else if(d.pageX-this.overflowOffset.left<c.scrollSensitivity)this.scrollParent[0].scrollLeft=e=this.scrollParent[0].scrollLeft-c.scrollSpeed}else{if(d.pageY-a(document).scrollTop()<c.scrollSensitivity)e=a(document).scrollTop(a(document).scrollTop()-
+c.scrollSpeed);else if(a(window).height()-(d.pageY-a(document).scrollTop())<c.scrollSensitivity)e=a(document).scrollTop(a(document).scrollTop()+c.scrollSpeed);if(d.pageX-a(document).scrollLeft()<c.scrollSensitivity)e=a(document).scrollLeft(a(document).scrollLeft()-c.scrollSpeed);else if(a(window).width()-(d.pageX-a(document).scrollLeft())<c.scrollSensitivity)e=a(document).scrollLeft(a(document).scrollLeft()+c.scrollSpeed)}e!==false&&a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,
+d)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(c=this.items.length-1;c>=0;c--){e=this.items[c];var h=e.item[0],g=this._intersectsWithPointer(e);if(g)if(h!=this.currentItem[0]&&this.placeholder[g==1?"next":"prev"]()[0]!=h&&!a.ui.contains(this.placeholder[0],h)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],
+h):true)){this.direction=g==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(e))this._rearrange(d,e);else break;this._trigger("change",d,this._uiHash());break}}this._contactContainers(d);a.ui.ddmanager&&a.ui.ddmanager.drag(this,d);this._trigger("sort",d,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(d,c){if(d){a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,d);if(this.options.revert){var e=this;c=e.placeholder.offset();
+e.reverting=true;a(this.helper).animate({left:c.left-this.offset.parent.left-e.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:c.top-this.offset.parent.top-e.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){e._clear(d)})}else this._clear(d,c);return false}},cancel:function(){var d=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):
+this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--){this.containers[c]._trigger("deactivate",null,d._uiHash(this));if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",null,d._uiHash(this));this.containers[c].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();a.extend(this,{helper:null,
+dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(d){var c=this._getItemsAsjQuery(d&&d.connected),e=[];d=d||{};a(c).each(function(){var h=(a(d.item||this).attr(d.attribute||"id")||"").match(d.expression||/(.+)[-=_](.+)/);if(h)e.push((d.key||h[1]+"[]")+"="+(d.key&&d.expression?h[1]:h[2]))});!e.length&&d.key&&e.push(d.key+"=");return e.join("&")},
+toArray:function(d){var c=this._getItemsAsjQuery(d&&d.connected),e=[];d=d||{};c.each(function(){e.push(a(d.item||this).attr(d.attribute||"id")||"")});return e},_intersectsWith:function(d){var c=this.positionAbs.left,e=c+this.helperProportions.width,h=this.positionAbs.top,g=h+this.helperProportions.height,i=d.left,b=i+d.width,f=d.top,j=f+d.height,l=this.offset.click.top,o=this.offset.click.left;l=h+l>f&&h+l<j&&c+o>i&&c+o<b;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||
+this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>d[this.floating?"width":"height"]?l:i<c+this.helperProportions.width/2&&e-this.helperProportions.width/2<b&&f<h+this.helperProportions.height/2&&g-this.helperProportions.height/2<j},_intersectsWithPointer:function(d){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,d.top,d.height);d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,d.left,d.width);c=c&&d;d=this._getDragVerticalDirection();
+var e=this._getDragHorizontalDirection();if(!c)return false;return this.floating?e&&e=="right"||d=="down"?2:1:d&&(d=="down"?2:1)},_intersectsWithSides:function(d){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,d.top+d.height/2,d.height);d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,d.left+d.width/2,d.width);var e=this._getDragVerticalDirection(),h=this._getDragHorizontalDirection();return this.floating&&h?h=="right"&&d||h=="left"&&!d:e&&(e=="down"&&c||e=="up"&&!c)},
+_getDragVerticalDirection:function(){var d=this.positionAbs.top-this.lastPositionAbs.top;return d!=0&&(d>0?"down":"up")},_getDragHorizontalDirection:function(){var d=this.positionAbs.left-this.lastPositionAbs.left;return d!=0&&(d>0?"right":"left")},refresh:function(d){this._refreshItems(d);this.refreshPositions();return this},_connectWith:function(){var d=this.options;return d.connectWith.constructor==String?[d.connectWith]:d.connectWith},_getItemsAsjQuery:function(d){var c=[],e=[],h=this._connectWith();
+if(h&&d)for(d=h.length-1;d>=0;d--)for(var g=a(h[d]),i=g.length-1;i>=0;i--){var b=a.data(g[i],"sortable");if(b&&b!=this&&!b.options.disabled)e.push([a.isFunction(b.options.items)?b.options.items.call(b.element):a(b.options.items,b.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),b])}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),
+this]);for(d=e.length-1;d>=0;d--)e[d][0].each(function(){c.push(this)});return a(c)},_removeCurrentsFromItems:function(){for(var d=this.currentItem.find(":data(sortable-item)"),c=0;c<this.items.length;c++)for(var e=0;e<d.length;e++)d[e]==this.items[c].item[0]&&this.items.splice(c,1)},_refreshItems:function(d){this.items=[];this.containers=[this];var c=this.items,e=[[a.isFunction(this.options.items)?this.options.items.call(this.element[0],d,{item:this.currentItem}):a(this.options.items,this.element),
+this]],h=this._connectWith();if(h)for(var g=h.length-1;g>=0;g--)for(var i=a(h[g]),b=i.length-1;b>=0;b--){var f=a.data(i[b],"sortable");if(f&&f!=this&&!f.options.disabled){e.push([a.isFunction(f.options.items)?f.options.items.call(f.element[0],d,{item:this.currentItem}):a(f.options.items,f.element),f]);this.containers.push(f)}}for(g=e.length-1;g>=0;g--){d=e[g][1];h=e[g][0];b=0;for(i=h.length;b<i;b++){f=a(h[b]);f.data("sortable-item",d);c.push({item:f,instance:d,width:0,height:0,left:0,top:0})}}},refreshPositions:function(d){if(this.offsetParent&&
+this.helper)this.offset.parent=this._getParentOffset();for(var c=this.items.length-1;c>=0;c--){var e=this.items[c];if(!(e.instance!=this.currentContainer&&this.currentContainer&&e.item[0]!=this.currentItem[0])){var h=this.options.toleranceElement?a(this.options.toleranceElement,e.item):e.item;if(!d){e.width=h.outerWidth();e.height=h.outerHeight()}h=h.offset();e.left=h.left;e.top=h.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(c=
+this.containers.length-1;c>=0;c--){h=this.containers[c].element.offset();this.containers[c].containerCache.left=h.left;this.containers[c].containerCache.top=h.top;this.containers[c].containerCache.width=this.containers[c].element.outerWidth();this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(d){var c=d||this,e=c.options;if(!e.placeholder||e.placeholder.constructor==String){var h=e.placeholder;e.placeholder={element:function(){var g=
+a(document.createElement(c.currentItem[0].nodeName)).addClass(h||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!h)g.style.visibility="hidden";return g},update:function(g,i){if(!(h&&!e.forcePlaceholderSize)){i.height()||i.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10));i.width()||i.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||
+0,10))}}}}c.placeholder=a(e.placeholder.element.call(c.element,c.currentItem));c.currentItem.after(c.placeholder);e.placeholder.update(c,c.placeholder)},_contactContainers:function(d){for(var c=null,e=null,h=this.containers.length-1;h>=0;h--)if(!a.ui.contains(this.currentItem[0],this.containers[h].element[0]))if(this._intersectsWith(this.containers[h].containerCache)){if(!(c&&a.ui.contains(this.containers[h].element[0],c.element[0]))){c=this.containers[h];e=h}}else if(this.containers[h].containerCache.over){this.containers[h]._trigger("out",
+d,this._uiHash(this));this.containers[h].containerCache.over=0}if(c)if(this.containers.length===1){this.containers[e]._trigger("over",d,this._uiHash(this));this.containers[e].containerCache.over=1}else if(this.currentContainer!=this.containers[e]){c=1E4;h=null;for(var g=this.positionAbs[this.containers[e].floating?"left":"top"],i=this.items.length-1;i>=0;i--)if(a.ui.contains(this.containers[e].element[0],this.items[i].item[0])){var b=this.items[i][this.containers[e].floating?"left":"top"];if(Math.abs(b-
+g)<c){c=Math.abs(b-g);h=this.items[i]}}if(h||this.options.dropOnEmpty){this.currentContainer=this.containers[e];h?this._rearrange(d,h,null,true):this._rearrange(d,null,this.containers[e].element,true);this._trigger("change",d,this._uiHash());this.containers[e]._trigger("change",d,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder);this.containers[e]._trigger("over",d,this._uiHash(this));this.containers[e].containerCache.over=1}}},_createHelper:function(d){var c=
+this.options;d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[d,this.currentItem])):c.helper=="clone"?this.currentItem.clone():this.currentItem;d.parents("body").length||a(c.appendTo!="parent"?c.appendTo:this.currentItem[0].parentNode)[0].appendChild(d[0]);if(d[0]==this.currentItem[0])this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")};if(d[0].style.width==
+""||c.forceHelperSize)d.width(this.currentItem.width());if(d[0].style.height==""||c.forceHelperSize)d.height(this.currentItem.height());return d},_adjustOffsetFromHelper:function(d){if(typeof d=="string")d=d.split(" ");if(a.isArray(d))d={left:+d[0],top:+d[1]||0};if("left"in d)this.offset.click.left=d.left+this.margins.left;if("right"in d)this.offset.click.left=this.helperProportions.width-d.right+this.margins.left;if("top"in d)this.offset.click.top=d.top+this.margins.top;if("bottom"in d)this.offset.click.top=
+this.helperProportions.height-d.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var d=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])){d.left+=this.scrollParent.scrollLeft();d.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)d=
+{top:0,left:0};return{top:d.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:d.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var d=this.currentItem.position();return{top:d.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:d.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),
+10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var d=this.options;if(d.containment=="parent")d.containment=this.helper[0].parentNode;if(d.containment=="document"||d.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(d.containment=="document"?
+document:window).width()-this.helperProportions.width-this.margins.left,(a(d.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(d.containment)){var c=a(d.containment)[0];d=a(d.containment).offset();var e=a(c).css("overflow")!="hidden";this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),
+10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(e?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(e?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(d,c){if(!c)c=
+this.position;d=d=="absolute"?1:-1;var e=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,h=/(html|body)/i.test(e[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():h?0:e.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&
+this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():h?0:e.scrollLeft())*d)}},_generatePosition:function(d){var c=this.options,e=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,h=/(html|body)/i.test(e[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0]))this.offset.relative=this._getRelativeOffset();
+var g=d.pageX,i=d.pageY;if(this.originalPosition){if(this.containment){if(d.pageX-this.offset.click.left<this.containment[0])g=this.containment[0]+this.offset.click.left;if(d.pageY-this.offset.click.top<this.containment[1])i=this.containment[1]+this.offset.click.top;if(d.pageX-this.offset.click.left>this.containment[2])g=this.containment[2]+this.offset.click.left;if(d.pageY-this.offset.click.top>this.containment[3])i=this.containment[3]+this.offset.click.top}if(c.grid){i=this.originalPageY+Math.round((i-
+this.originalPageY)/c.grid[1])*c.grid[1];i=this.containment?!(i-this.offset.click.top<this.containment[1]||i-this.offset.click.top>this.containment[3])?i:!(i-this.offset.click.top<this.containment[1])?i-c.grid[1]:i+c.grid[1]:i;g=this.originalPageX+Math.round((g-this.originalPageX)/c.grid[0])*c.grid[0];g=this.containment?!(g-this.offset.click.left<this.containment[0]||g-this.offset.click.left>this.containment[2])?g:!(g-this.offset.click.left<this.containment[0])?g-c.grid[0]:g+c.grid[0]:g}}return{top:i-
+this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():h?0:e.scrollTop()),left:g-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():h?0:e.scrollLeft())}},_rearrange:function(d,c,e,h){e?e[0].appendChild(this.placeholder[0]):c.item[0].parentNode.insertBefore(this.placeholder[0],
+this.direction=="down"?c.item[0]:c.item[0].nextSibling);this.counter=this.counter?++this.counter:1;var g=this,i=this.counter;window.setTimeout(function(){i==g.counter&&g.refreshPositions(!h)},0)},_clear:function(d,c){this.reverting=false;var e=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem);this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var h in this._storedCSS)if(this._storedCSS[h]=="auto"||this._storedCSS[h]=="static")this._storedCSS[h]=
+"";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!c&&e.push(function(g){this._trigger("receive",g,this._uiHash(this.fromOutside))});if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!c)e.push(function(g){this._trigger("update",g,this._uiHash())});if(!a.ui.contains(this.element[0],this.currentItem[0])){c||e.push(function(g){this._trigger("remove",
+g,this._uiHash())});for(h=this.containers.length-1;h>=0;h--)if(a.ui.contains(this.containers[h].element[0],this.currentItem[0])&&!c){e.push(function(g){return function(i){g._trigger("receive",i,this._uiHash(this))}}.call(this,this.containers[h]));e.push(function(g){return function(i){g._trigger("update",i,this._uiHash(this))}}.call(this,this.containers[h]))}}for(h=this.containers.length-1;h>=0;h--){c||e.push(function(g){return function(i){g._trigger("deactivate",i,this._uiHash(this))}}.call(this,
+this.containers[h]));if(this.containers[h].containerCache.over){e.push(function(g){return function(i){g._trigger("out",i,this._uiHash(this))}}.call(this,this.containers[h]));this.containers[h].containerCache.over=0}}this._storedCursor&&a("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",
+d,this._uiHash());for(h=0;h<e.length;h++)e[h].call(this,d);this._trigger("stop",d,this._uiHash())}return false}c||this._trigger("beforeStop",d,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!c){for(h=0;h<e.length;h++)e[h].call(this,d);this._trigger("stop",d,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){a.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()},
+_uiHash:function(d){var c=d||this;return{helper:c.helper,placeholder:c.placeholder||a([]),position:c.position,originalPosition:c.originalPosition,offset:c.positionAbs,item:c.currentItem,sender:d?d.element:null}}});a.extend(a.ui.sortable,{version:"1.8.16"})})(jQuery);
+jQuery.effects||function(a,d){function c(n){var k;if(n&&n.constructor==Array&&n.length==3)return n;if(k=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(n))return[parseInt(k[1],10),parseInt(k[2],10),parseInt(k[3],10)];if(k=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(n))return[parseFloat(k[1])*2.55,parseFloat(k[2])*2.55,parseFloat(k[3])*2.55];if(k=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(n))return[parseInt(k[1],
+16),parseInt(k[2],16),parseInt(k[3],16)];if(k=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(n))return[parseInt(k[1]+k[1],16),parseInt(k[2]+k[2],16),parseInt(k[3]+k[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(n))return j.transparent;return j[a.trim(n).toLowerCase()]}function e(n,k){var m;do{m=a.curCSS(n,k);if(m!=""&&m!="transparent"||a.nodeName(n,"body"))break;k="backgroundColor"}while(n=n.parentNode);return c(m)}function h(){var n=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,
+k={},m,p;if(n&&n.length&&n[0]&&n[n[0]])for(var q=n.length;q--;){m=n[q];if(typeof n[m]=="string"){p=m.replace(/\-(\w)/g,function(s,r){return r.toUpperCase()});k[p]=n[m]}}else for(m in n)if(typeof n[m]==="string")k[m]=n[m];return k}function g(n){var k,m;for(k in n){m=n[k];if(m==null||a.isFunction(m)||k in o||/scrollbar/.test(k)||!/color/i.test(k)&&isNaN(parseFloat(m)))delete n[k]}return n}function i(n,k){var m={_:0},p;for(p in k)if(n[p]!=k[p])m[p]=k[p];return m}function b(n,k,m,p){if(typeof n=="object"){p=
+k;m=null;k=n;n=k.effect}if(a.isFunction(k)){p=k;m=null;k={}}if(typeof k=="number"||a.fx.speeds[k]){p=m;m=k;k={}}if(a.isFunction(m)){p=m;m=null}k=k||{};m=m||k.duration;m=a.fx.off?0:typeof m=="number"?m:m in a.fx.speeds?a.fx.speeds[m]:a.fx.speeds._default;p=p||k.complete;return[n,k,m,p]}function f(n){if(!n||typeof n==="number"||a.fx.speeds[n])return true;if(typeof n==="string"&&!a.effects[n])return true;return false}a.effects={};a.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor",
+"borderTopColor","borderColor","color","outlineColor"],function(n,k){a.fx.step[k]=function(m){if(!m.colorInit){m.start=e(m.elem,k);m.end=c(m.end);m.colorInit=true}m.elem.style[k]="rgb("+Math.max(Math.min(parseInt(m.pos*(m.end[0]-m.start[0])+m.start[0],10),255),0)+","+Math.max(Math.min(parseInt(m.pos*(m.end[1]-m.start[1])+m.start[1],10),255),0)+","+Math.max(Math.min(parseInt(m.pos*(m.end[2]-m.start[2])+m.start[2],10),255),0)+")"}});var j={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,
+0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,
+211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},l=["add","remove","toggle"],o={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.effects.animateClass=function(n,k,m,
+p){if(a.isFunction(m)){p=m;m=null}return this.queue(function(){var q=a(this),s=q.attr("style")||" ",r=g(h.call(this)),u,v=q.attr("class");a.each(l,function(w,x){n[x]&&q[x+"Class"](n[x])});u=g(h.call(this));q.attr("class",v);q.animate(i(r,u),{queue:false,duration:k,easing:m,complete:function(){a.each(l,function(w,x){n[x]&&q[x+"Class"](n[x])});if(typeof q.attr("style")=="object"){q.attr("style").cssText="";q.attr("style").cssText=s}else q.attr("style",s);p&&p.apply(this,arguments);a.dequeue(this)}})})};
+a.fn.extend({_addClass:a.fn.addClass,addClass:function(n,k,m,p){return k?a.effects.animateClass.apply(this,[{add:n},k,m,p]):this._addClass(n)},_removeClass:a.fn.removeClass,removeClass:function(n,k,m,p){return k?a.effects.animateClass.apply(this,[{remove:n},k,m,p]):this._removeClass(n)},_toggleClass:a.fn.toggleClass,toggleClass:function(n,k,m,p,q){return typeof k=="boolean"||k===d?m?a.effects.animateClass.apply(this,[k?{add:n}:{remove:n},m,p,q]):this._toggleClass(n,k):a.effects.animateClass.apply(this,
+[{toggle:n},k,m,p])},switchClass:function(n,k,m,p,q){return a.effects.animateClass.apply(this,[{add:k,remove:n},m,p,q])}});a.extend(a.effects,{version:"1.8.16",save:function(n,k){for(var m=0;m<k.length;m++)k[m]!==null&&n.data("ec.storage."+k[m],n[0].style[k[m]])},restore:function(n,k){for(var m=0;m<k.length;m++)k[m]!==null&&n.css(k[m],n.data("ec.storage."+k[m]))},setMode:function(n,k){if(k=="toggle")k=n.is(":hidden")?"show":"hide";return k},getBaseline:function(n,k){var m;switch(n[0]){case "top":m=
+0;break;case "middle":m=0.5;break;case "bottom":m=1;break;default:m=n[0]/k.height}switch(n[1]){case "left":n=0;break;case "center":n=0.5;break;case "right":n=1;break;default:n=n[1]/k.width}return{x:n,y:m}},createWrapper:function(n){if(n.parent().is(".ui-effects-wrapper"))return n.parent();var k={width:n.outerWidth(true),height:n.outerHeight(true),"float":n.css("float")},m=a("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),
+p=document.activeElement;n.wrap(m);if(n[0]===p||a.contains(n[0],p))a(p).focus();m=n.parent();if(n.css("position")=="static"){m.css({position:"relative"});n.css({position:"relative"})}else{a.extend(k,{position:n.css("position"),zIndex:n.css("z-index")});a.each(["top","left","bottom","right"],function(q,s){k[s]=n.css(s);if(isNaN(parseInt(k[s],10)))k[s]="auto"});n.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return m.css(k).show()},removeWrapper:function(n){var k,m=document.activeElement;
+if(n.parent().is(".ui-effects-wrapper")){k=n.parent().replaceWith(n);if(n[0]===m||a.contains(n[0],m))a(m).focus();return k}return n},setTransition:function(n,k,m,p){p=p||{};a.each(k,function(q,s){unit=n.cssUnit(s);if(unit[0]>0)p[s]=unit[0]*m+unit[1]});return p}});a.fn.extend({effect:function(n){var k=b.apply(this,arguments),m={options:k[1],duration:k[2],callback:k[3]};k=m.options.mode;var p=a.effects[n];if(a.fx.off||!p)return k?this[k](m.duration,m.callback):this.each(function(){m.callback&&m.callback.call(this)});
+return p.call(this,m)},_show:a.fn.show,show:function(n){if(f(n))return this._show.apply(this,arguments);else{var k=b.apply(this,arguments);k[1].mode="show";return this.effect.apply(this,k)}},_hide:a.fn.hide,hide:function(n){if(f(n))return this._hide.apply(this,arguments);else{var k=b.apply(this,arguments);k[1].mode="hide";return this.effect.apply(this,k)}},__toggle:a.fn.toggle,toggle:function(n){if(f(n)||typeof n==="boolean"||a.isFunction(n))return this.__toggle.apply(this,arguments);else{var k=b.apply(this,
+arguments);k[1].mode="toggle";return this.effect.apply(this,k)}},cssUnit:function(n){var k=this.css(n),m=[];a.each(["em","px","%","pt"],function(p,q){if(k.indexOf(q)>0)m=[parseFloat(k),q]});return m}});a.easing.jswing=a.easing.swing;a.extend(a.easing,{def:"easeOutQuad",swing:function(n,k,m,p,q){return a.easing[a.easing.def](n,k,m,p,q)},easeInQuad:function(n,k,m,p,q){return p*(k/=q)*k+m},easeOutQuad:function(n,k,m,p,q){return-p*(k/=q)*(k-2)+m},easeInOutQuad:function(n,k,m,p,q){if((k/=q/2)<1)return p/
+2*k*k+m;return-p/2*(--k*(k-2)-1)+m},easeInCubic:function(n,k,m,p,q){return p*(k/=q)*k*k+m},easeOutCubic:function(n,k,m,p,q){return p*((k=k/q-1)*k*k+1)+m},easeInOutCubic:function(n,k,m,p,q){if((k/=q/2)<1)return p/2*k*k*k+m;return p/2*((k-=2)*k*k+2)+m},easeInQuart:function(n,k,m,p,q){return p*(k/=q)*k*k*k+m},easeOutQuart:function(n,k,m,p,q){return-p*((k=k/q-1)*k*k*k-1)+m},easeInOutQuart:function(n,k,m,p,q){if((k/=q/2)<1)return p/2*k*k*k*k+m;return-p/2*((k-=2)*k*k*k-2)+m},easeInQuint:function(n,k,m,
+p,q){return p*(k/=q)*k*k*k*k+m},easeOutQuint:function(n,k,m,p,q){return p*((k=k/q-1)*k*k*k*k+1)+m},easeInOutQuint:function(n,k,m,p,q){if((k/=q/2)<1)return p/2*k*k*k*k*k+m;return p/2*((k-=2)*k*k*k*k+2)+m},easeInSine:function(n,k,m,p,q){return-p*Math.cos(k/q*(Math.PI/2))+p+m},easeOutSine:function(n,k,m,p,q){return p*Math.sin(k/q*(Math.PI/2))+m},easeInOutSine:function(n,k,m,p,q){return-p/2*(Math.cos(Math.PI*k/q)-1)+m},easeInExpo:function(n,k,m,p,q){return k==0?m:p*Math.pow(2,10*(k/q-1))+m},easeOutExpo:function(n,
+k,m,p,q){return k==q?m+p:p*(-Math.pow(2,-10*k/q)+1)+m},easeInOutExpo:function(n,k,m,p,q){if(k==0)return m;if(k==q)return m+p;if((k/=q/2)<1)return p/2*Math.pow(2,10*(k-1))+m;return p/2*(-Math.pow(2,-10*--k)+2)+m},easeInCirc:function(n,k,m,p,q){return-p*(Math.sqrt(1-(k/=q)*k)-1)+m},easeOutCirc:function(n,k,m,p,q){return p*Math.sqrt(1-(k=k/q-1)*k)+m},easeInOutCirc:function(n,k,m,p,q){if((k/=q/2)<1)return-p/2*(Math.sqrt(1-k*k)-1)+m;return p/2*(Math.sqrt(1-(k-=2)*k)+1)+m},easeInElastic:function(n,k,m,
+p,q){n=1.70158;var s=0,r=p;if(k==0)return m;if((k/=q)==1)return m+p;s||(s=q*0.3);if(r<Math.abs(p)){r=p;n=s/4}else n=s/(2*Math.PI)*Math.asin(p/r);return-(r*Math.pow(2,10*(k-=1))*Math.sin((k*q-n)*2*Math.PI/s))+m},easeOutElastic:function(n,k,m,p,q){n=1.70158;var s=0,r=p;if(k==0)return m;if((k/=q)==1)return m+p;s||(s=q*0.3);if(r<Math.abs(p)){r=p;n=s/4}else n=s/(2*Math.PI)*Math.asin(p/r);return r*Math.pow(2,-10*k)*Math.sin((k*q-n)*2*Math.PI/s)+p+m},easeInOutElastic:function(n,k,m,p,q){n=1.70158;var s=
+0,r=p;if(k==0)return m;if((k/=q/2)==2)return m+p;s||(s=q*0.3*1.5);if(r<Math.abs(p)){r=p;n=s/4}else n=s/(2*Math.PI)*Math.asin(p/r);if(k<1)return-0.5*r*Math.pow(2,10*(k-=1))*Math.sin((k*q-n)*2*Math.PI/s)+m;return r*Math.pow(2,-10*(k-=1))*Math.sin((k*q-n)*2*Math.PI/s)*0.5+p+m},easeInBack:function(n,k,m,p,q,s){if(s==d)s=1.70158;return p*(k/=q)*k*((s+1)*k-s)+m},easeOutBack:function(n,k,m,p,q,s){if(s==d)s=1.70158;return p*((k=k/q-1)*k*((s+1)*k+s)+1)+m},easeInOutBack:function(n,k,m,p,q,s){if(s==d)s=1.70158;
+if((k/=q/2)<1)return p/2*k*k*(((s*=1.525)+1)*k-s)+m;return p/2*((k-=2)*k*(((s*=1.525)+1)*k+s)+2)+m},easeInBounce:function(n,k,m,p,q){return p-a.easing.easeOutBounce(n,q-k,0,p,q)+m},easeOutBounce:function(n,k,m,p,q){return(k/=q)<1/2.75?p*7.5625*k*k+m:k<2/2.75?p*(7.5625*(k-=1.5/2.75)*k+0.75)+m:k<2.5/2.75?p*(7.5625*(k-=2.25/2.75)*k+0.9375)+m:p*(7.5625*(k-=2.625/2.75)*k+0.984375)+m},easeInOutBounce:function(n,k,m,p,q){if(k<q/2)return a.easing.easeInBounce(n,k*2,0,p,q)*0.5+m;return a.easing.easeOutBounce(n,
+k*2-q,0,p,q)*0.5+p*0.5+m}})}(jQuery);
+(function(a){a.effects.blind=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right"],h=a.effects.setMode(c,d.options.mode||"hide"),g=d.options.direction||"vertical";a.effects.save(c,e);c.show();var i=a.effects.createWrapper(c).css({overflow:"hidden"}),b=g=="vertical"?"height":"width";g=g=="vertical"?i.height():i.width();h=="show"&&i.css(b,0);var f={};f[b]=h=="show"?g:0;i.animate(f,d.duration,d.options.easing,function(){h=="hide"&&c.hide();a.effects.restore(c,
+e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(c[0],arguments);c.dequeue()})})}})(jQuery);
+(function(a){a.effects.bounce=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right"],h=a.effects.setMode(c,d.options.mode||"effect"),g=d.options.direction||"up",i=d.options.distance||20,b=d.options.times||5,f=d.duration||250;/show|hide/.test(h)&&e.push("opacity");a.effects.save(c,e);c.show();a.effects.createWrapper(c);var j=g=="up"||g=="down"?"top":"left";g=g=="up"||g=="left"?"pos":"neg";i=d.options.distance||(j=="top"?c.outerHeight({margin:true})/3:c.outerWidth({margin:true})/
+3);if(h=="show")c.css("opacity",0).css(j,g=="pos"?-i:i);if(h=="hide")i/=b*2;h!="hide"&&b--;if(h=="show"){var l={opacity:1};l[j]=(g=="pos"?"+=":"-=")+i;c.animate(l,f/2,d.options.easing);i/=2;b--}for(l=0;l<b;l++){var o={},n={};o[j]=(g=="pos"?"-=":"+=")+i;n[j]=(g=="pos"?"+=":"-=")+i;c.animate(o,f/2,d.options.easing).animate(n,f/2,d.options.easing);i=h=="hide"?i*2:i/2}if(h=="hide"){l={opacity:0};l[j]=(g=="pos"?"-=":"+=")+i;c.animate(l,f/2,d.options.easing,function(){c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);
+d.callback&&d.callback.apply(this,arguments)})}else{o={};n={};o[j]=(g=="pos"?"-=":"+=")+i;n[j]=(g=="pos"?"+=":"-=")+i;c.animate(o,f/2,d.options.easing).animate(n,f/2,d.options.easing,function(){a.effects.restore(c,e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(this,arguments)})}c.queue("fx",function(){c.dequeue()});c.dequeue()})}})(jQuery);
+(function(a){a.effects.clip=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right","height","width"],h=a.effects.setMode(c,d.options.mode||"hide"),g=d.options.direction||"vertical";a.effects.save(c,e);c.show();var i=a.effects.createWrapper(c).css({overflow:"hidden"});i=c[0].tagName=="IMG"?i:c;var b={size:g=="vertical"?"height":"width",position:g=="vertical"?"top":"left"};g=g=="vertical"?i.height():i.width();if(h=="show"){i.css(b.size,0);i.css(b.position,
+g/2)}var f={};f[b.size]=h=="show"?g:0;f[b.position]=h=="show"?0:g/2;i.animate(f,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){h=="hide"&&c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(c[0],arguments);c.dequeue()}})})}})(jQuery);
+(function(a){a.effects.drop=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right","opacity"],h=a.effects.setMode(c,d.options.mode||"hide"),g=d.options.direction||"left";a.effects.save(c,e);c.show();a.effects.createWrapper(c);var i=g=="up"||g=="down"?"top":"left";g=g=="up"||g=="left"?"pos":"neg";var b=d.options.distance||(i=="top"?c.outerHeight({margin:true})/2:c.outerWidth({margin:true})/2);if(h=="show")c.css("opacity",0).css(i,g=="pos"?-b:b);var f={opacity:h==
+"show"?1:0};f[i]=(h=="show"?g=="pos"?"+=":"-=":g=="pos"?"-=":"+=")+b;c.animate(f,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){h=="hide"&&c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(a){a.effects.explode=function(d){return this.queue(function(){var c=d.options.pieces?Math.round(Math.sqrt(d.options.pieces)):3,e=d.options.pieces?Math.round(Math.sqrt(d.options.pieces)):3;d.options.mode=d.options.mode=="toggle"?a(this).is(":visible")?"hide":"show":d.options.mode;var h=a(this).show().css("visibility","hidden"),g=h.offset();g.top-=parseInt(h.css("marginTop"),10)||0;g.left-=parseInt(h.css("marginLeft"),10)||0;for(var i=h.outerWidth(true),b=h.outerHeight(true),f=0;f<c;f++)for(var j=
+0;j<e;j++)h.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-j*(i/e),top:-f*(b/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:i/e,height:b/c,left:g.left+j*(i/e)+(d.options.mode=="show"?(j-Math.floor(e/2))*(i/e):0),top:g.top+f*(b/c)+(d.options.mode=="show"?(f-Math.floor(c/2))*(b/c):0),opacity:d.options.mode=="show"?0:1}).animate({left:g.left+j*(i/e)+(d.options.mode=="show"?0:(j-Math.floor(e/2))*(i/e)),top:g.top+
+f*(b/c)+(d.options.mode=="show"?0:(f-Math.floor(c/2))*(b/c)),opacity:d.options.mode=="show"?1:0},d.duration||500);setTimeout(function(){d.options.mode=="show"?h.css({visibility:"visible"}):h.css({visibility:"visible"}).hide();d.callback&&d.callback.apply(h[0]);h.dequeue();a("div.ui-effects-explode").remove()},d.duration||500)})}})(jQuery);
+(function(a){a.effects.fade=function(d){return this.queue(function(){var c=a(this),e=a.effects.setMode(c,d.options.mode||"hide");c.animate({opacity:e},{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){d.callback&&d.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(a){a.effects.fold=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right"],h=a.effects.setMode(c,d.options.mode||"hide"),g=d.options.size||15,i=!!d.options.horizFirst,b=d.duration?d.duration/2:a.fx.speeds._default/2;a.effects.save(c,e);c.show();var f=a.effects.createWrapper(c).css({overflow:"hidden"}),j=h=="show"!=i,l=j?["width","height"]:["height","width"];j=j?[f.width(),f.height()]:[f.height(),f.width()];var o=/([0-9]+)%/.exec(g);if(o)g=parseInt(o[1],
+10)/100*j[h=="hide"?0:1];if(h=="show")f.css(i?{height:0,width:g}:{height:g,width:0});i={};o={};i[l[0]]=h=="show"?j[0]:g;o[l[1]]=h=="show"?j[1]:0;f.animate(i,b,d.options.easing).animate(o,b,d.options.easing,function(){h=="hide"&&c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(c[0],arguments);c.dequeue()})})}})(jQuery);
+(function(a){a.effects.highlight=function(d){return this.queue(function(){var c=a(this),e=["backgroundImage","backgroundColor","opacity"],h=a.effects.setMode(c,d.options.mode||"show"),g={backgroundColor:c.css("backgroundColor")};if(h=="hide")g.opacity=0;a.effects.save(c,e);c.show().css({backgroundImage:"none",backgroundColor:d.options.color||"#ffff99"}).animate(g,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){h=="hide"&&c.hide();a.effects.restore(c,e);h=="show"&&!a.support.opacity&&
+this.style.removeAttribute("filter");d.callback&&d.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(a){a.effects.pulsate=function(d){return this.queue(function(){var c=a(this),e=a.effects.setMode(c,d.options.mode||"show");times=(d.options.times||5)*2-1;duration=d.duration?d.duration/2:a.fx.speeds._default/2;isVisible=c.is(":visible");animateTo=0;if(!isVisible){c.css("opacity",0).show();animateTo=1}if(e=="hide"&&isVisible||e=="show"&&!isVisible)times--;for(e=0;e<times;e++){c.animate({opacity:animateTo},duration,d.options.easing);animateTo=(animateTo+1)%2}c.animate({opacity:animateTo},duration,
+d.options.easing,function(){animateTo==0&&c.hide();d.callback&&d.callback.apply(this,arguments)});c.queue("fx",function(){c.dequeue()}).dequeue()})}})(jQuery);
+(function(a){a.effects.puff=function(d){return this.queue(function(){var c=a(this),e=a.effects.setMode(c,d.options.mode||"hide"),h=parseInt(d.options.percent,10)||150,g=h/100,i={height:c.height(),width:c.width()};a.extend(d.options,{fade:true,mode:e,percent:e=="hide"?h:100,from:e=="hide"?i:{height:i.height*g,width:i.width*g}});c.effect("scale",d.options,d.duration,d.callback);c.dequeue()})};a.effects.scale=function(d){return this.queue(function(){var c=a(this),e=a.extend(true,{},d.options),h=a.effects.setMode(c,
+d.options.mode||"effect"),g=parseInt(d.options.percent,10)||(parseInt(d.options.percent,10)==0?0:h=="hide"?0:100),i=d.options.direction||"both",b=d.options.origin;if(h!="effect"){e.origin=b||["middle","center"];e.restore=true}b={height:c.height(),width:c.width()};c.from=d.options.from||(h=="show"?{height:0,width:0}:b);g={y:i!="horizontal"?g/100:1,x:i!="vertical"?g/100:1};c.to={height:b.height*g.y,width:b.width*g.x};if(d.options.fade){if(h=="show"){c.from.opacity=0;c.to.opacity=1}if(h=="hide"){c.from.opacity=
+1;c.to.opacity=0}}e.from=c.from;e.to=c.to;e.mode=h;c.effect("size",e,d.duration,d.callback);c.dequeue()})};a.effects.size=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right","width","height","overflow","opacity"],h=["position","top","bottom","left","right","overflow","opacity"],g=["width","height","overflow"],i=["fontSize"],b=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],f=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],
+j=a.effects.setMode(c,d.options.mode||"effect"),l=d.options.restore||false,o=d.options.scale||"both",n=d.options.origin,k={height:c.height(),width:c.width()};c.from=d.options.from||k;c.to=d.options.to||k;if(n){n=a.effects.getBaseline(n,k);c.from.top=(k.height-c.from.height)*n.y;c.from.left=(k.width-c.from.width)*n.x;c.to.top=(k.height-c.to.height)*n.y;c.to.left=(k.width-c.to.width)*n.x}var m={from:{y:c.from.height/k.height,x:c.from.width/k.width},to:{y:c.to.height/k.height,x:c.to.width/k.width}};
+if(o=="box"||o=="both"){if(m.from.y!=m.to.y){e=e.concat(b);c.from=a.effects.setTransition(c,b,m.from.y,c.from);c.to=a.effects.setTransition(c,b,m.to.y,c.to)}if(m.from.x!=m.to.x){e=e.concat(f);c.from=a.effects.setTransition(c,f,m.from.x,c.from);c.to=a.effects.setTransition(c,f,m.to.x,c.to)}}if(o=="content"||o=="both")if(m.from.y!=m.to.y){e=e.concat(i);c.from=a.effects.setTransition(c,i,m.from.y,c.from);c.to=a.effects.setTransition(c,i,m.to.y,c.to)}a.effects.save(c,l?e:h);c.show();a.effects.createWrapper(c);
+c.css("overflow","hidden").css(c.from);if(o=="content"||o=="both"){b=b.concat(["marginTop","marginBottom"]).concat(i);f=f.concat(["marginLeft","marginRight"]);g=e.concat(b).concat(f);c.find("*[width]").each(function(){child=a(this);l&&a.effects.save(child,g);var p={height:child.height(),width:child.width()};child.from={height:p.height*m.from.y,width:p.width*m.from.x};child.to={height:p.height*m.to.y,width:p.width*m.to.x};if(m.from.y!=m.to.y){child.from=a.effects.setTransition(child,b,m.from.y,child.from);
+child.to=a.effects.setTransition(child,b,m.to.y,child.to)}if(m.from.x!=m.to.x){child.from=a.effects.setTransition(child,f,m.from.x,child.from);child.to=a.effects.setTransition(child,f,m.to.x,child.to)}child.css(child.from);child.animate(child.to,d.duration,d.options.easing,function(){l&&a.effects.restore(child,g)})})}c.animate(c.to,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){c.to.opacity===0&&c.css("opacity",c.from.opacity);j=="hide"&&c.hide();a.effects.restore(c,
+l?e:h);a.effects.removeWrapper(c);d.callback&&d.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(a){a.effects.shake=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right"];a.effects.setMode(c,d.options.mode||"effect");var h=d.options.direction||"left",g=d.options.distance||20,i=d.options.times||3,b=d.duration||d.options.duration||140;a.effects.save(c,e);c.show();a.effects.createWrapper(c);var f=h=="up"||h=="down"?"top":"left",j=h=="up"||h=="left"?"pos":"neg";h={};var l={},o={};h[f]=(j=="pos"?"-=":"+=")+g;l[f]=(j=="pos"?"+=":"-=")+g*2;o[f]=
+(j=="pos"?"-=":"+=")+g*2;c.animate(h,b,d.options.easing);for(g=1;g<i;g++)c.animate(l,b,d.options.easing).animate(o,b,d.options.easing);c.animate(l,b,d.options.easing).animate(h,b/2,d.options.easing,function(){a.effects.restore(c,e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(this,arguments)});c.queue("fx",function(){c.dequeue()});c.dequeue()})}})(jQuery);
+(function(a){a.effects.slide=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right"],h=a.effects.setMode(c,d.options.mode||"show"),g=d.options.direction||"left";a.effects.save(c,e);c.show();a.effects.createWrapper(c).css({overflow:"hidden"});var i=g=="up"||g=="down"?"top":"left";g=g=="up"||g=="left"?"pos":"neg";var b=d.options.distance||(i=="top"?c.outerHeight({margin:true}):c.outerWidth({margin:true}));if(h=="show")c.css(i,g=="pos"?isNaN(b)?"-"+b:-b:b);
+var f={};f[i]=(h=="show"?g=="pos"?"+=":"-=":g=="pos"?"-=":"+=")+b;c.animate(f,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){h=="hide"&&c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(a){a.effects.transfer=function(d){return this.queue(function(){var c=a(this),e=a(d.options.to),h=e.offset();e={top:h.top,left:h.left,height:e.innerHeight(),width:e.innerWidth()};h=c.offset();var g=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(d.options.className).css({top:h.top,left:h.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(e,d.duration,d.options.easing,function(){g.remove();d.callback&&d.callback.apply(c[0],arguments);
+c.dequeue()})})}})(jQuery);
+(function(a){a.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var d=this,c=d.options;d.running=0;d.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix");d.headers=
+d.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){c.disabled||a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){c.disabled||a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){c.disabled||a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){c.disabled||a(this).removeClass("ui-state-focus")});d.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");
+if(c.navigation){var e=d.element.find("a").filter(c.navigationFilter).eq(0);if(e.length){var h=e.closest(".ui-accordion-header");d.active=h.length?h:e.closest(".ui-accordion-content").prev()}}d.active=d._findActive(d.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");d.active.next().addClass("ui-accordion-content-active");d._createIcons();d.resize();d.element.attr("role","tablist");d.headers.attr("role","tab").bind("keydown.accordion",
+function(g){return d._keydown(g)}).next().attr("role","tabpanel");d.headers.not(d.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();d.active.length?d.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):d.headers.eq(0).attr("tabIndex",0);a.browser.safari||d.headers.find("a").attr("tabIndex",-1);c.event&&d.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(g){d._clickHandler.call(d,g,this);g.preventDefault()})},_createIcons:function(){var d=
+this.options;if(d.icons){a("<span></span>").addClass("ui-icon "+d.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(d.icons.header).toggleClass(d.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var d=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex");
+this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(d.autoHeight||d.fillHeight)c.css("height","");return a.Widget.prototype.destroy.call(this)},_setOption:function(d,c){a.Widget.prototype._setOption.apply(this,arguments);d=="active"&&this.activate(c);if(d=="icons"){this._destroyIcons();
+c&&this._createIcons()}if(d=="disabled")this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(d){if(!(this.options.disabled||d.altKey||d.ctrlKey)){var c=a.ui.keyCode,e=this.headers.length,h=this.headers.index(d.target),g=false;switch(d.keyCode){case c.RIGHT:case c.DOWN:g=this.headers[(h+1)%e];break;case c.LEFT:case c.UP:g=this.headers[(h-1+e)%e];break;case c.SPACE:case c.ENTER:this._clickHandler({target:d.target},d.target);
+d.preventDefault()}if(g){a(d.target).attr("tabIndex",-1);a(g).attr("tabIndex",0);g.focus();return false}return true}},resize:function(){var d=this.options,c;if(d.fillSpace){if(a.browser.msie){var e=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height();a.browser.msie&&this.element.parent().css("overflow",e);this.headers.each(function(){c-=a(this).outerHeight(true)});this.headers.next().each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+
+a(this).height()))}).css("overflow","auto")}else if(d.autoHeight){c=0;this.headers.next().each(function(){c=Math.max(c,a(this).height("").height())}).height(c)}return this},activate:function(d){this.options.active=d;d=this._findActive(d)[0];this._clickHandler({target:d},d);return this},_findActive:function(d){return d?typeof d==="number"?this.headers.filter(":eq("+d+")"):this.headers.not(this.headers.not(d)):d===false?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(d,c){var e=this.options;
+if(!e.disabled)if(d.target){d=a(d.currentTarget||c);c=d[0]===this.active[0];e.active=e.collapsible&&c?false:this.headers.index(d);if(!(this.running||!e.collapsible&&c)){var h=this.active;f=d.next();i=this.active.next();b={options:e,newHeader:c&&e.collapsible?a([]):d,oldHeader:this.active,newContent:c&&e.collapsible?a([]):f,oldContent:i};var g=this.headers.index(this.active[0])>this.headers.index(d[0]);this.active=c?a([]):d;this._toggle(f,i,b,c,g);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(e.icons.headerSelected).addClass(e.icons.header);
+if(!c){d.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(e.icons.header).addClass(e.icons.headerSelected);d.next().addClass("ui-accordion-content-active")}}}else if(e.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(e.icons.headerSelected).addClass(e.icons.header);this.active.next().addClass("ui-accordion-content-active");var i=this.active.next(),
+b={options:e,newHeader:a([]),oldHeader:e.active,newContent:a([]),oldContent:i},f=this.active=a([]);this._toggle(f,i,b)}},_toggle:function(d,c,e,h,g){var i=this,b=i.options;i.toShow=d;i.toHide=c;i.data=e;var f=function(){if(i)return i._completed.apply(i,arguments)};i._trigger("changestart",null,i.data);i.running=c.size()===0?d.size():c.size();if(b.animated){e={};e=b.collapsible&&h?{toShow:a([]),toHide:c,complete:f,down:g,autoHeight:b.autoHeight||b.fillSpace}:{toShow:d,toHide:c,complete:f,down:g,autoHeight:b.autoHeight||
+b.fillSpace};if(!b.proxied)b.proxied=b.animated;if(!b.proxiedDuration)b.proxiedDuration=b.duration;b.animated=a.isFunction(b.proxied)?b.proxied(e):b.proxied;b.duration=a.isFunction(b.proxiedDuration)?b.proxiedDuration(e):b.proxiedDuration;h=a.ui.accordion.animations;var j=b.duration,l=b.animated;if(l&&!h[l]&&!a.easing[l])l="slide";h[l]||(h[l]=function(o){this.slide(o,{easing:l,duration:j||700})});h[l](e)}else{if(b.collapsible&&h)d.toggle();else{c.hide();d.show()}f(true)}c.prev().attr({"aria-expanded":"false",
+"aria-selected":"false",tabIndex:-1}).blur();d.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(d){this.running=d?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});a.extend(a.ui.accordion,{version:"1.8.16",
+animations:{slide:function(d,c){d=a.extend({easing:"swing",duration:300},d,c);if(d.toHide.size())if(d.toShow.size()){var e=d.toShow.css("overflow"),h=0,g={},i={},b;c=d.toShow;b=c[0].style.width;c.width(parseInt(c.parent().width(),10)-parseInt(c.css("paddingLeft"),10)-parseInt(c.css("paddingRight"),10)-(parseInt(c.css("borderLeftWidth"),10)||0)-(parseInt(c.css("borderRightWidth"),10)||0));a.each(["height","paddingTop","paddingBottom"],function(f,j){i[j]="hide";f=(""+a.css(d.toShow[0],j)).match(/^([\d+-.]+)(.*)$/);
+g[j]={value:f[1],unit:f[2]||"px"}});d.toShow.css({height:0,overflow:"hidden"}).show();d.toHide.filter(":hidden").each(d.complete).end().filter(":visible").animate(i,{step:function(f,j){if(j.prop=="height")h=j.end-j.start===0?0:(j.now-j.start)/(j.end-j.start);d.toShow[0].style[j.prop]=h*g[j.prop].value+g[j.prop].unit},duration:d.duration,easing:d.easing,complete:function(){d.autoHeight||d.toShow.css("height","");d.toShow.css({width:b,overflow:e});d.complete()}})}else d.toHide.animate({height:"hide",
+paddingTop:"hide",paddingBottom:"hide"},d);else d.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},d)},bounceslide:function(d){this.slide(d,{easing:d.down?"easeOutBounce":"swing",duration:d.down?1E3:200})}}})})(jQuery);
+(function(a){var d=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var c=this,e=this.element[0].ownerDocument,h;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(g){if(!(c.options.disabled||c.element.propAttr("readOnly"))){h=
+false;var i=a.ui.keyCode;switch(g.keyCode){case i.PAGE_UP:c._move("previousPage",g);break;case i.PAGE_DOWN:c._move("nextPage",g);break;case i.UP:c._move("previous",g);g.preventDefault();break;case i.DOWN:c._move("next",g);g.preventDefault();break;case i.ENTER:case i.NUMPAD_ENTER:if(c.menu.active){h=true;g.preventDefault()}case i.TAB:if(!c.menu.active)return;c.menu.select(g);break;case i.ESCAPE:c.element.val(c.term);c.close(g);break;default:clearTimeout(c.searching);c.searching=setTimeout(function(){if(c.term!=
+c.element.val()){c.selectedItem=null;c.search(null,g)}},c.options.delay);break}}}).bind("keypress.autocomplete",function(g){if(h){h=false;g.preventDefault()}}).bind("focus.autocomplete",function(){if(!c.options.disabled){c.selectedItem=null;c.previous=c.element.val()}}).bind("blur.autocomplete",function(g){if(!c.options.disabled){clearTimeout(c.searching);c.closing=setTimeout(function(){c.close(g);c._change(g)},150)}});this._initSource();this.response=function(){return c._response.apply(c,arguments)};
+this.menu=a("<ul></ul>").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",e)[0]).mousedown(function(g){var i=c.menu.element[0];a(g.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(b){b.target!==c.element[0]&&b.target!==i&&!a.ui.contains(i,b.target)&&c.close()})},1);setTimeout(function(){clearTimeout(c.closing)},13)}).menu({focus:function(g,i){i=i.item.data("item.autocomplete");false!==c._trigger("focus",g,{item:i})&&/^key/.test(g.originalEvent.type)&&
+c.element.val(i.value)},selected:function(g,i){var b=i.item.data("item.autocomplete"),f=c.previous;if(c.element[0]!==e.activeElement){c.element.focus();c.previous=f;setTimeout(function(){c.previous=f;c.selectedItem=b},1)}false!==c._trigger("select",g,{item:b})&&c.element.val(b.value);c.term=c.element.val();c.close(g);c.selectedItem=b},blur:function(){c.menu.element.is(":visible")&&c.element.val()!==c.term&&c.element.val(c.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");
+a.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();a.Widget.prototype.destroy.call(this)},_setOption:function(c,e){a.Widget.prototype._setOption.apply(this,arguments);c==="source"&&this._initSource();if(c==="appendTo")this.menu.element.appendTo(a(e||"body",this.element[0].ownerDocument)[0]);c==="disabled"&&
+e&&this.xhr&&this.xhr.abort()},_initSource:function(){var c=this,e,h;if(a.isArray(this.options.source)){e=this.options.source;this.source=function(g,i){i(a.ui.autocomplete.filter(e,g.term))}}else if(typeof this.options.source==="string"){h=this.options.source;this.source=function(g,i){c.xhr&&c.xhr.abort();c.xhr=a.ajax({url:h,data:g,dataType:"json",autocompleteRequest:++d,success:function(b){this.autocompleteRequest===d&&i(b)},error:function(){this.autocompleteRequest===d&&i([])}})}}else this.source=
+this.options.source},search:function(c,e){c=c!=null?c:this.element.val();this.term=this.element.val();if(c.length<this.options.minLength)return this.close(e);clearTimeout(this.closing);if(this._trigger("search",e)!==false)return this._search(c)},_search:function(c){this.pending++;this.element.addClass("ui-autocomplete-loading");this.source({term:c},this.response)},_response:function(c){if(!this.options.disabled&&c&&c.length){c=this._normalize(c);this._suggest(c);this._trigger("open")}else this.close();
+this.pending--;this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(c){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this.menu.element.hide();this.menu.deactivate();this._trigger("close",c)}},_change:function(c){this.previous!==this.element.val()&&this._trigger("change",c,{item:this.selectedItem})},_normalize:function(c){if(c.length&&c[0].label&&c[0].value)return c;return a.map(c,function(e){if(typeof e==="string")return{label:e,value:e};return a.extend({label:e.label||
+e.value,value:e.value||e.label},e)})},_suggest:function(c){var e=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(e,c);this.menu.deactivate();this.menu.refresh();e.show();this._resizeMenu();e.position(a.extend({of:this.element},this.options.position));this.options.autoFocus&&this.menu.next(new a.Event("mouseover"))},_resizeMenu:function(){var c=this.menu.element;c.outerWidth(Math.max(c.width("").outerWidth(),this.element.outerWidth()))},_renderMenu:function(c,e){var h=this;
+a.each(e,function(g,i){h._renderItem(c,i)})},_renderItem:function(c,e){return a("<li></li>").data("item.autocomplete",e).append(a("<a></a>").text(e.label)).appendTo(c)},_move:function(c,e){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(c)||this.menu.last()&&/^next/.test(c)){this.element.val(this.term);this.menu.deactivate()}else this.menu[c](e);else this.search(null,e)},widget:function(){return this.menu.element}});a.extend(a.ui.autocomplete,{escapeRegex:function(c){return c.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,
+"\\$&")},filter:function(c,e){var h=new RegExp(a.ui.autocomplete.escapeRegex(e),"i");return a.grep(c,function(g){return h.test(g.label||g.value||g)})}})})(jQuery);
+(function(a){a.widget("ui.menu",{_create:function(){var d=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){if(a(c.target).closest(".ui-menu-item a").length){c.preventDefault();d.select(c)}});this.refresh()},refresh:function(){var d=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex",
+-1).mouseenter(function(c){d.activate(c,a(this).parent())}).mouseleave(function(){d.deactivate()})},activate:function(d,c){this.deactivate();if(this.hasScroll()){var e=c.offset().top-this.element.offset().top,h=this.element.scrollTop(),g=this.element.height();if(e<0)this.element.scrollTop(h+e);else e>=g&&this.element.scrollTop(h+e-g+c.height())}this.active=c.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",d,{item:c})},deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id");
+this._trigger("blur");this.active=null}},next:function(d){this.move("next",".ui-menu-item:first",d)},previous:function(d){this.move("prev",".ui-menu-item:last",d)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(d,c,e){if(this.active){d=this.active[d+"All"](".ui-menu-item").eq(0);d.length?this.activate(e,d):this.activate(e,this.element.children(c))}else this.activate(e,
+this.element.children(c))},nextPage:function(d){if(this.hasScroll())if(!this.active||this.last())this.activate(d,this.element.children(".ui-menu-item:first"));else{var c=this.active.offset().top,e=this.element.height(),h=this.element.children(".ui-menu-item").filter(function(){var g=a(this).offset().top-c-e+a(this).height();return g<10&&g>-10});h.length||(h=this.element.children(".ui-menu-item:last"));this.activate(d,h)}else this.activate(d,this.element.children(".ui-menu-item").filter(!this.active||
+this.last()?":first":":last"))},previousPage:function(d){if(this.hasScroll())if(!this.active||this.first())this.activate(d,this.element.children(".ui-menu-item:last"));else{var c=this.active.offset().top,e=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var h=a(this).offset().top-c+e-a(this).height();return h<10&&h>-10});result.length||(result=this.element.children(".ui-menu-item:first"));this.activate(d,result)}else this.activate(d,this.element.children(".ui-menu-item").filter(!this.active||
+this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[a.fn.prop?"prop":"attr"]("scrollHeight")},select:function(d){this._trigger("selected",d,{item:this.active})}})})(jQuery);
+(function(a){var d,c,e,h,g=function(){var b=a(this).find(":ui-button");setTimeout(function(){b.button("refresh")},1)},i=function(b){var f=b.name,j=b.form,l=a([]);if(f)l=j?a(j).find("[name='"+f+"']"):a("[name='"+f+"']",b.ownerDocument).filter(function(){return!this.form});return l};a.widget("ui.button",{options:{disabled:null,text:true,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",g);if(typeof this.options.disabled!==
+"boolean")this.options.disabled=this.element.propAttr("disabled");this._determineButtonType();this.hasTitle=!!this.buttonElement.attr("title");var b=this,f=this.options,j=this.type==="checkbox"||this.type==="radio",l="ui-state-hover"+(!j?" ui-state-active":"");if(f.label===null)f.label=this.buttonElement.html();if(this.element.is(":disabled"))f.disabled=true;this.buttonElement.addClass("ui-button ui-widget ui-state-default ui-corner-all").attr("role","button").bind("mouseenter.button",function(){if(!f.disabled){a(this).addClass("ui-state-hover");
+this===d&&a(this).addClass("ui-state-active")}}).bind("mouseleave.button",function(){f.disabled||a(this).removeClass(l)}).bind("click.button",function(o){if(f.disabled){o.preventDefault();o.stopImmediatePropagation()}});this.element.bind("focus.button",function(){b.buttonElement.addClass("ui-state-focus")}).bind("blur.button",function(){b.buttonElement.removeClass("ui-state-focus")});if(j){this.element.bind("change.button",function(){h||b.refresh()});this.buttonElement.bind("mousedown.button",function(o){if(!f.disabled){h=
+false;c=o.pageX;e=o.pageY}}).bind("mouseup.button",function(o){if(!f.disabled)if(c!==o.pageX||e!==o.pageY)h=true})}if(this.type==="checkbox")this.buttonElement.bind("click.button",function(){if(f.disabled||h)return false;a(this).toggleClass("ui-state-active");b.buttonElement.attr("aria-pressed",b.element[0].checked)});else if(this.type==="radio")this.buttonElement.bind("click.button",function(){if(f.disabled||h)return false;a(this).addClass("ui-state-active");b.buttonElement.attr("aria-pressed","true");
+var o=b.element[0];i(o).not(o).map(function(){return a(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")});else{this.buttonElement.bind("mousedown.button",function(){if(f.disabled)return false;a(this).addClass("ui-state-active");d=this;a(document).one("mouseup",function(){d=null})}).bind("mouseup.button",function(){if(f.disabled)return false;a(this).removeClass("ui-state-active")}).bind("keydown.button",function(o){if(f.disabled)return false;if(o.keyCode==a.ui.keyCode.SPACE||
+o.keyCode==a.ui.keyCode.ENTER)a(this).addClass("ui-state-active")}).bind("keyup.button",function(){a(this).removeClass("ui-state-active")});this.buttonElement.is("a")&&this.buttonElement.keyup(function(o){o.keyCode===a.ui.keyCode.SPACE&&a(this).click()})}this._setOption("disabled",f.disabled);this._resetButton()},_determineButtonType:function(){this.type=this.element.is(":checkbox")?"checkbox":this.element.is(":radio")?"radio":this.element.is("input")?"input":"button";if(this.type==="checkbox"||this.type===
+"radio"){var b=this.element.parents().filter(":last"),f="label[for='"+this.element.attr("id")+"']";this.buttonElement=b.find(f);if(!this.buttonElement.length){b=b.length?b.siblings():this.element.siblings();this.buttonElement=b.filter(f);if(!this.buttonElement.length)this.buttonElement=b.find(f)}this.element.addClass("ui-helper-hidden-accessible");(b=this.element.is(":checked"))&&this.buttonElement.addClass("ui-state-active");this.buttonElement.attr("aria-pressed",b)}else this.buttonElement=this.element},
+widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible");this.buttonElement.removeClass("ui-button ui-widget ui-state-default ui-corner-all ui-state-hover ui-state-active ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only").removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html());this.hasTitle||this.buttonElement.removeAttr("title");
+a.Widget.prototype.destroy.call(this)},_setOption:function(b,f){a.Widget.prototype._setOption.apply(this,arguments);if(b==="disabled")f?this.element.propAttr("disabled",true):this.element.propAttr("disabled",false);else this._resetButton()},refresh:function(){var b=this.element.is(":disabled");b!==this.options.disabled&&this._setOption("disabled",b);if(this.type==="radio")i(this.element[0]).each(function(){a(this).is(":checked")?a(this).button("widget").addClass("ui-state-active").attr("aria-pressed",
+"true"):a(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")});else if(this.type==="checkbox")this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false")},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var b=this.buttonElement.removeClass("ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only"),
+f=a("<span></span>").addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),j=this.options.icons,l=j.primary&&j.secondary,o=[];if(j.primary||j.secondary){if(this.options.text)o.push("ui-button-text-icon"+(l?"s":j.primary?"-primary":"-secondary"));j.primary&&b.prepend("<span class='ui-button-icon-primary ui-icon "+j.primary+"'></span>");j.secondary&&b.append("<span class='ui-button-icon-secondary ui-icon "+j.secondary+"'></span>");if(!this.options.text){o.push(l?"ui-button-icons-only":
+"ui-button-icon-only");this.hasTitle||b.attr("title",f)}}else o.push("ui-button-text-only");b.addClass(o.join(" "))}}});a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,f){b==="disabled"&&this.buttons.button("option",b,f);a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var b=this.element.css("direction")===
+"ltr";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(b?"ui-corner-left":"ui-corner-right").end().filter(":last").addClass(b?"ui-corner-right":"ui-corner-left").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");
+a.Widget.prototype.destroy.call(this)}})})(jQuery);
+(function(a,d){function c(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._inDialog=this._datepickerShowing=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass=
+"ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su",
+"Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",
+minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false,autoSize:false,disabled:false};a.extend(this._defaults,this.regional[""]);this.dpDiv=e(a('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}function e(b){return b.bind("mouseout",
+function(f){f=a(f.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");f.length&&f.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(f){f=a(f.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!(a.datepicker._isDisabledDatepicker(i.inline?b.parent()[0]:i.input[0])||!f.length)){f.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
+f.addClass("ui-state-hover");f.hasClass("ui-datepicker-prev")&&f.addClass("ui-datepicker-prev-hover");f.hasClass("ui-datepicker-next")&&f.addClass("ui-datepicker-next-hover")}})}function h(b,f){a.extend(b,f);for(var j in f)if(f[j]==null||f[j]==d)b[j]=f[j];return b}a.extend(a.ui,{datepicker:{version:"1.8.16"}});var g=(new Date).getTime(),i;a.extend(c.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},
+setDefaults:function(b){h(this._defaults,b||{});return this},_attachDatepicker:function(b,f){var j=null;for(var l in this._defaults){var o=b.getAttribute("date:"+l);if(o){j=j||{};try{j[l]=eval(o)}catch(n){j[l]=o}}}l=b.nodeName.toLowerCase();o=l=="div"||l=="span";if(!b.id){this.uuid+=1;b.id="dp"+this.uuid}var k=this._newInst(a(b),o);k.settings=a.extend({},f||{},j||{});if(l=="input")this._connectDatepicker(b,k);else o&&this._inlineDatepicker(b,k)},_newInst:function(b,f){return{id:b[0].id.replace(/([^A-Za-z0-9_-])/g,
+"\\\\$1"),input:b,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:f,dpDiv:!f?this.dpDiv:e(a('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}},_connectDatepicker:function(b,f){var j=a(b);f.append=a([]);f.trigger=a([]);if(!j.hasClass(this.markerClassName)){this._attachments(j,f);j.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",
+function(l,o,n){f.settings[o]=n}).bind("getData.datepicker",function(l,o){return this._get(f,o)});this._autoSize(f);a.data(b,"datepicker",f);f.settings.disabled&&this._disableDatepicker(b)}},_attachments:function(b,f){var j=this._get(f,"appendText"),l=this._get(f,"isRTL");f.append&&f.append.remove();if(j){f.append=a('<span class="'+this._appendClass+'">'+j+"</span>");b[l?"before":"after"](f.append)}b.unbind("focus",this._showDatepicker);f.trigger&&f.trigger.remove();j=this._get(f,"showOn");if(j==
+"focus"||j=="both")b.focus(this._showDatepicker);if(j=="button"||j=="both"){j=this._get(f,"buttonText");var o=this._get(f,"buttonImage");f.trigger=a(this._get(f,"buttonImageOnly")?a("<img/>").addClass(this._triggerClass).attr({src:o,alt:j,title:j}):a('<button type="button"></button>').addClass(this._triggerClass).html(o==""?j:a("<img/>").attr({src:o,alt:j,title:j})));b[l?"before":"after"](f.trigger);f.trigger.click(function(){a.datepicker._datepickerShowing&&a.datepicker._lastInput==b[0]?a.datepicker._hideDatepicker():
+a.datepicker._showDatepicker(b[0]);return false})}},_autoSize:function(b){if(this._get(b,"autoSize")&&!b.inline){var f=new Date(2009,11,20),j=this._get(b,"dateFormat");if(j.match(/[DM]/)){var l=function(o){for(var n=0,k=0,m=0;m<o.length;m++)if(o[m].length>n){n=o[m].length;k=m}return k};f.setMonth(l(this._get(b,j.match(/MM/)?"monthNames":"monthNamesShort")));f.setDate(l(this._get(b,j.match(/DD/)?"dayNames":"dayNamesShort"))+20-f.getDay())}b.input.attr("size",this._formatDate(b,f).length)}},_inlineDatepicker:function(b,
+f){var j=a(b);if(!j.hasClass(this.markerClassName)){j.addClass(this.markerClassName).append(f.dpDiv).bind("setData.datepicker",function(l,o,n){f.settings[o]=n}).bind("getData.datepicker",function(l,o){return this._get(f,o)});a.data(b,"datepicker",f);this._setDate(f,this._getDefaultDate(f),true);this._updateDatepicker(f);this._updateAlternate(f);f.settings.disabled&&this._disableDatepicker(b);f.dpDiv.css("display","block")}},_dialogDatepicker:function(b,f,j,l,o){b=this._dialogInst;if(!b){this.uuid+=
+1;this._dialogInput=a('<input type="text" id="'+("dp"+this.uuid)+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');this._dialogInput.keydown(this._doKeyDown);a("body").append(this._dialogInput);b=this._dialogInst=this._newInst(this._dialogInput,false);b.settings={};a.data(this._dialogInput[0],"datepicker",b)}h(b.settings,l||{});f=f&&f.constructor==Date?this._formatDate(b,f):f;this._dialogInput.val(f);this._pos=o?o.length?o:[o.pageX,o.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/
+2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");b.settings.onSelect=j;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);a.blockUI&&a.blockUI(this.dpDiv);a.data(this._dialogInput[0],"datepicker",b);return this},_destroyDatepicker:function(b){var f=
+a(b),j=a.data(b,"datepicker");if(f.hasClass(this.markerClassName)){var l=b.nodeName.toLowerCase();a.removeData(b,"datepicker");if(l=="input"){j.append.remove();j.trigger.remove();f.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(l=="div"||l=="span")f.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(b){var f=a(b),j=a.data(b,"datepicker");if(f.hasClass(this.markerClassName)){var l=
+b.nodeName.toLowerCase();if(l=="input"){b.disabled=false;j.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(l=="div"||l=="span"){f=f.children("."+this._inlineClass);f.children().removeClass("ui-state-disabled");f.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=a.map(this._disabledInputs,function(o){return o==b?null:o})}},_disableDatepicker:function(b){var f=a(b),j=a.data(b,
+"datepicker");if(f.hasClass(this.markerClassName)){var l=b.nodeName.toLowerCase();if(l=="input"){b.disabled=true;j.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(l=="div"||l=="span"){f=f.children("."+this._inlineClass);f.children().addClass("ui-state-disabled");f.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=a.map(this._disabledInputs,function(o){return o==
+b?null:o});this._disabledInputs[this._disabledInputs.length]=b}},_isDisabledDatepicker:function(b){if(!b)return false;for(var f=0;f<this._disabledInputs.length;f++)if(this._disabledInputs[f]==b)return true;return false},_getInst:function(b){try{return a.data(b,"datepicker")}catch(f){throw"Missing instance data for this datepicker";}},_optionDatepicker:function(b,f,j){var l=this._getInst(b);if(arguments.length==2&&typeof f=="string")return f=="defaults"?a.extend({},a.datepicker._defaults):l?f=="all"?
+a.extend({},l.settings):this._get(l,f):null;var o=f||{};if(typeof f=="string"){o={};o[f]=j}if(l){this._curInst==l&&this._hideDatepicker();var n=this._getDateDatepicker(b,true),k=this._getMinMaxDate(l,"min"),m=this._getMinMaxDate(l,"max");h(l.settings,o);if(k!==null&&o.dateFormat!==d&&o.minDate===d)l.settings.minDate=this._formatDate(l,k);if(m!==null&&o.dateFormat!==d&&o.maxDate===d)l.settings.maxDate=this._formatDate(l,m);this._attachments(a(b),l);this._autoSize(l);this._setDate(l,n);this._updateAlternate(l);
+this._updateDatepicker(l)}},_changeDatepicker:function(b,f,j){this._optionDatepicker(b,f,j)},_refreshDatepicker:function(b){(b=this._getInst(b))&&this._updateDatepicker(b)},_setDateDatepicker:function(b,f){if(b=this._getInst(b)){this._setDate(b,f);this._updateDatepicker(b);this._updateAlternate(b)}},_getDateDatepicker:function(b,f){(b=this._getInst(b))&&!b.inline&&this._setDateFromField(b,f);return b?this._getDate(b):null},_doKeyDown:function(b){var f=a.datepicker._getInst(b.target),j=true,l=f.dpDiv.is(".ui-datepicker-rtl");
+f._keyEvent=true;if(a.datepicker._datepickerShowing)switch(b.keyCode){case 9:a.datepicker._hideDatepicker();j=false;break;case 13:j=a("td."+a.datepicker._dayOverClass+":not(."+a.datepicker._currentClass+")",f.dpDiv);j[0]&&a.datepicker._selectDay(b.target,f.selectedMonth,f.selectedYear,j[0]);if(b=a.datepicker._get(f,"onSelect")){j=a.datepicker._formatDate(f);b.apply(f.input?f.input[0]:null,[j,f])}else a.datepicker._hideDatepicker();return false;case 27:a.datepicker._hideDatepicker();break;case 33:a.datepicker._adjustDate(b.target,
+b.ctrlKey?-a.datepicker._get(f,"stepBigMonths"):-a.datepicker._get(f,"stepMonths"),"M");break;case 34:a.datepicker._adjustDate(b.target,b.ctrlKey?+a.datepicker._get(f,"stepBigMonths"):+a.datepicker._get(f,"stepMonths"),"M");break;case 35:if(b.ctrlKey||b.metaKey)a.datepicker._clearDate(b.target);j=b.ctrlKey||b.metaKey;break;case 36:if(b.ctrlKey||b.metaKey)a.datepicker._gotoToday(b.target);j=b.ctrlKey||b.metaKey;break;case 37:if(b.ctrlKey||b.metaKey)a.datepicker._adjustDate(b.target,l?+1:-1,"D");j=
+b.ctrlKey||b.metaKey;if(b.originalEvent.altKey)a.datepicker._adjustDate(b.target,b.ctrlKey?-a.datepicker._get(f,"stepBigMonths"):-a.datepicker._get(f,"stepMonths"),"M");break;case 38:if(b.ctrlKey||b.metaKey)a.datepicker._adjustDate(b.target,-7,"D");j=b.ctrlKey||b.metaKey;break;case 39:if(b.ctrlKey||b.metaKey)a.datepicker._adjustDate(b.target,l?-1:+1,"D");j=b.ctrlKey||b.metaKey;if(b.originalEvent.altKey)a.datepicker._adjustDate(b.target,b.ctrlKey?+a.datepicker._get(f,"stepBigMonths"):+a.datepicker._get(f,
+"stepMonths"),"M");break;case 40:if(b.ctrlKey||b.metaKey)a.datepicker._adjustDate(b.target,+7,"D");j=b.ctrlKey||b.metaKey;break;default:j=false}else if(b.keyCode==36&&b.ctrlKey)a.datepicker._showDatepicker(this);else j=false;if(j){b.preventDefault();b.stopPropagation()}},_doKeyPress:function(b){var f=a.datepicker._getInst(b.target);if(a.datepicker._get(f,"constrainInput")){f=a.datepicker._possibleChars(a.datepicker._get(f,"dateFormat"));var j=String.fromCharCode(b.charCode==d?b.keyCode:b.charCode);
+return b.ctrlKey||b.metaKey||j<" "||!f||f.indexOf(j)>-1}},_doKeyUp:function(b){b=a.datepicker._getInst(b.target);if(b.input.val()!=b.lastVal)try{if(a.datepicker.parseDate(a.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,a.datepicker._getFormatConfig(b))){a.datepicker._setDateFromField(b);a.datepicker._updateAlternate(b);a.datepicker._updateDatepicker(b)}}catch(f){a.datepicker.log(f)}return true},_showDatepicker:function(b){b=b.target||b;if(b.nodeName.toLowerCase()!="input")b=a("input",
+b.parentNode)[0];if(!(a.datepicker._isDisabledDatepicker(b)||a.datepicker._lastInput==b)){var f=a.datepicker._getInst(b);if(a.datepicker._curInst&&a.datepicker._curInst!=f){a.datepicker._datepickerShowing&&a.datepicker._triggerOnClose(a.datepicker._curInst);a.datepicker._curInst.dpDiv.stop(true,true)}var j=a.datepicker._get(f,"beforeShow");j=j?j.apply(b,[b,f]):{};if(j!==false){h(f.settings,j);f.lastVal=null;a.datepicker._lastInput=b;a.datepicker._setDateFromField(f);if(a.datepicker._inDialog)b.value=
+"";if(!a.datepicker._pos){a.datepicker._pos=a.datepicker._findPos(b);a.datepicker._pos[1]+=b.offsetHeight}var l=false;a(b).parents().each(function(){l|=a(this).css("position")=="fixed";return!l});if(l&&a.browser.opera){a.datepicker._pos[0]-=document.documentElement.scrollLeft;a.datepicker._pos[1]-=document.documentElement.scrollTop}j={left:a.datepicker._pos[0],top:a.datepicker._pos[1]};a.datepicker._pos=null;f.dpDiv.empty();f.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});a.datepicker._updateDatepicker(f);
+j=a.datepicker._checkOffset(f,j,l);f.dpDiv.css({position:a.datepicker._inDialog&&a.blockUI?"static":l?"fixed":"absolute",display:"none",left:j.left+"px",top:j.top+"px"});if(!f.inline){j=a.datepicker._get(f,"showAnim");var o=a.datepicker._get(f,"duration"),n=function(){var k=f.dpDiv.find("iframe.ui-datepicker-cover");if(k.length){var m=a.datepicker._getBorders(f.dpDiv);k.css({left:-m[0],top:-m[1],width:f.dpDiv.outerWidth(),height:f.dpDiv.outerHeight()})}};f.dpDiv.zIndex(a(b).zIndex()+1);a.datepicker._datepickerShowing=
+true;a.effects&&a.effects[j]?f.dpDiv.show(j,a.datepicker._get(f,"showOptions"),o,n):f.dpDiv[j||"show"](j?o:null,n);if(!j||!o)n();f.input.is(":visible")&&!f.input.is(":disabled")&&f.input.focus();a.datepicker._curInst=f}}}},_updateDatepicker:function(b){this.maxRows=4;var f=a.datepicker._getBorders(b.dpDiv);i=b;b.dpDiv.empty().append(this._generateHTML(b));var j=b.dpDiv.find("iframe.ui-datepicker-cover");j.length&&j.css({left:-f[0],top:-f[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()});
+b.dpDiv.find("."+this._dayOverClass+" a").mouseover();f=this._getNumberOfMonths(b);j=f[1];b.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");j>1&&b.dpDiv.addClass("ui-datepicker-multi-"+j).css("width",17*j+"em");b.dpDiv[(f[0]!=1||f[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");b.dpDiv[(this._get(b,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");b==a.datepicker._curInst&&a.datepicker._datepickerShowing&&b.input&&b.input.is(":visible")&&
+!b.input.is(":disabled")&&b.input[0]!=document.activeElement&&b.input.focus();if(b.yearshtml){var l=b.yearshtml;setTimeout(function(){l===b.yearshtml&&b.yearshtml&&b.dpDiv.find("select.ui-datepicker-year:first").replaceWith(b.yearshtml);l=b.yearshtml=null},0)}},_getBorders:function(b){var f=function(j){return{thin:1,medium:2,thick:3}[j]||j};return[parseFloat(f(b.css("border-left-width"))),parseFloat(f(b.css("border-top-width")))]},_checkOffset:function(b,f,j){var l=b.dpDiv.outerWidth(),o=b.dpDiv.outerHeight(),
+n=b.input?b.input.outerWidth():0,k=b.input?b.input.outerHeight():0,m=document.documentElement.clientWidth+a(document).scrollLeft(),p=document.documentElement.clientHeight+a(document).scrollTop();f.left-=this._get(b,"isRTL")?l-n:0;f.left-=j&&f.left==b.input.offset().left?a(document).scrollLeft():0;f.top-=j&&f.top==b.input.offset().top+k?a(document).scrollTop():0;f.left-=Math.min(f.left,f.left+l>m&&m>l?Math.abs(f.left+l-m):0);f.top-=Math.min(f.top,f.top+o>p&&p>o?Math.abs(o+k):0);return f},_findPos:function(b){for(var f=
+this._get(this._getInst(b),"isRTL");b&&(b.type=="hidden"||b.nodeType!=1||a.expr.filters.hidden(b));)b=b[f?"previousSibling":"nextSibling"];b=a(b).offset();return[b.left,b.top]},_triggerOnClose:function(b){var f=this._get(b,"onClose");if(f)f.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b])},_hideDatepicker:function(b){var f=this._curInst;if(!(!f||b&&f!=a.data(b,"datepicker")))if(this._datepickerShowing){b=this._get(f,"showAnim");var j=this._get(f,"duration"),l=function(){a.datepicker._tidyDialog(f);
+this._curInst=null};a.effects&&a.effects[b]?f.dpDiv.hide(b,a.datepicker._get(f,"showOptions"),j,l):f.dpDiv[b=="slideDown"?"slideUp":b=="fadeIn"?"fadeOut":"hide"](b?j:null,l);b||l();a.datepicker._triggerOnClose(f);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(a.blockUI){a.unblockUI();a("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(b){b.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},
+_checkExternalClick:function(b){if(a.datepicker._curInst){b=a(b.target);b[0].id!=a.datepicker._mainDivId&&b.parents("#"+a.datepicker._mainDivId).length==0&&!b.hasClass(a.datepicker.markerClassName)&&!b.hasClass(a.datepicker._triggerClass)&&a.datepicker._datepickerShowing&&!(a.datepicker._inDialog&&a.blockUI)&&a.datepicker._hideDatepicker()}},_adjustDate:function(b,f,j){b=a(b);var l=this._getInst(b[0]);if(!this._isDisabledDatepicker(b[0])){this._adjustInstDate(l,f+(j=="M"?this._get(l,"showCurrentAtPos"):
+0),j);this._updateDatepicker(l)}},_gotoToday:function(b){b=a(b);var f=this._getInst(b[0]);if(this._get(f,"gotoCurrent")&&f.currentDay){f.selectedDay=f.currentDay;f.drawMonth=f.selectedMonth=f.currentMonth;f.drawYear=f.selectedYear=f.currentYear}else{var j=new Date;f.selectedDay=j.getDate();f.drawMonth=f.selectedMonth=j.getMonth();f.drawYear=f.selectedYear=j.getFullYear()}this._notifyChange(f);this._adjustDate(b)},_selectMonthYear:function(b,f,j){b=a(b);var l=this._getInst(b[0]);l["selected"+(j=="M"?
+"Month":"Year")]=l["draw"+(j=="M"?"Month":"Year")]=parseInt(f.options[f.selectedIndex].value,10);this._notifyChange(l);this._adjustDate(b)},_selectDay:function(b,f,j,l){var o=a(b);if(!(a(l).hasClass(this._unselectableClass)||this._isDisabledDatepicker(o[0]))){o=this._getInst(o[0]);o.selectedDay=o.currentDay=a("a",l).html();o.selectedMonth=o.currentMonth=f;o.selectedYear=o.currentYear=j;this._selectDate(b,this._formatDate(o,o.currentDay,o.currentMonth,o.currentYear))}},_clearDate:function(b){b=a(b);
+this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(b,f){b=this._getInst(a(b)[0]);f=f!=null?f:this._formatDate(b);b.input&&b.input.val(f);this._updateAlternate(b);var j=this._get(b,"onSelect");if(j)j.apply(b.input?b.input[0]:null,[f,b]);else b.input&&b.input.trigger("change");if(b.inline)this._updateDatepicker(b);else{this._hideDatepicker();this._lastInput=b.input[0];typeof b.input[0]!="object"&&b.input.focus();this._lastInput=null}},_updateAlternate:function(b){var f=this._get(b,"altField");
+if(f){var j=this._get(b,"altFormat")||this._get(b,"dateFormat"),l=this._getDate(b),o=this.formatDate(j,l,this._getFormatConfig(b));a(f).each(function(){a(this).val(o)})}},noWeekends:function(b){b=b.getDay();return[b>0&&b<6,""]},iso8601Week:function(b){b=new Date(b.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var f=b.getTime();b.setMonth(0);b.setDate(1);return Math.floor(Math.round((f-b)/864E5)/7)+1},parseDate:function(b,f,j){if(b==null||f==null)throw"Invalid arguments";f=typeof f=="object"?
+f.toString():f+"";if(f=="")return null;var l=(j?j.shortYearCutoff:null)||this._defaults.shortYearCutoff;l=typeof l!="string"?l:(new Date).getFullYear()%100+parseInt(l,10);for(var o=(j?j.dayNamesShort:null)||this._defaults.dayNamesShort,n=(j?j.dayNames:null)||this._defaults.dayNames,k=(j?j.monthNamesShort:null)||this._defaults.monthNamesShort,m=(j?j.monthNames:null)||this._defaults.monthNames,p=j=-1,q=-1,s=-1,r=false,u=function(z){(z=H+1<b.length&&b.charAt(H+1)==z)&&H++;return z},v=function(z){var I=
+u(z);z=new RegExp("^\\d{1,"+(z=="@"?14:z=="!"?20:z=="y"&&I?4:z=="o"?3:2)+"}");z=f.substring(y).match(z);if(!z)throw"Missing number at position "+y;y+=z[0].length;return parseInt(z[0],10)},w=function(z,I,N){z=a.map(u(z)?N:I,function(D,E){return[[E,D]]}).sort(function(D,E){return-(D[1].length-E[1].length)});var J=-1;a.each(z,function(D,E){D=E[1];if(f.substr(y,D.length).toLowerCase()==D.toLowerCase()){J=E[0];y+=D.length;return false}});if(J!=-1)return J+1;else throw"Unknown name at position "+y;},x=
+function(){if(f.charAt(y)!=b.charAt(H))throw"Unexpected literal at position "+y;y++},y=0,H=0;H<b.length;H++)if(r)if(b.charAt(H)=="'"&&!u("'"))r=false;else x();else switch(b.charAt(H)){case "d":q=v("d");break;case "D":w("D",o,n);break;case "o":s=v("o");break;case "m":p=v("m");break;case "M":p=w("M",k,m);break;case "y":j=v("y");break;case "@":var C=new Date(v("@"));j=C.getFullYear();p=C.getMonth()+1;q=C.getDate();break;case "!":C=new Date((v("!")-this._ticksTo1970)/1E4);j=C.getFullYear();p=C.getMonth()+
+1;q=C.getDate();break;case "'":if(u("'"))x();else r=true;break;default:x()}if(y<f.length)throw"Extra/unparsed characters found in date: "+f.substring(y);if(j==-1)j=(new Date).getFullYear();else if(j<100)j+=(new Date).getFullYear()-(new Date).getFullYear()%100+(j<=l?0:-100);if(s>-1){p=1;q=s;do{l=this._getDaysInMonth(j,p-1);if(q<=l)break;p++;q-=l}while(1)}C=this._daylightSavingAdjust(new Date(j,p-1,q));if(C.getFullYear()!=j||C.getMonth()+1!=p||C.getDate()!=q)throw"Invalid date";return C},ATOM:"yy-mm-dd",
+COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(b,f,j){if(!f)return"";var l=(j?j.dayNamesShort:null)||this._defaults.dayNamesShort,o=(j?j.dayNames:null)||this._defaults.dayNames,n=(j?j.monthNamesShort:null)||this._defaults.monthNamesShort;j=(j?j.monthNames:
+null)||this._defaults.monthNames;var k=function(u){(u=r+1<b.length&&b.charAt(r+1)==u)&&r++;return u},m=function(u,v,w){v=""+v;if(k(u))for(;v.length<w;)v="0"+v;return v},p=function(u,v,w,x){return k(u)?x[v]:w[v]},q="",s=false;if(f)for(var r=0;r<b.length;r++)if(s)if(b.charAt(r)=="'"&&!k("'"))s=false;else q+=b.charAt(r);else switch(b.charAt(r)){case "d":q+=m("d",f.getDate(),2);break;case "D":q+=p("D",f.getDay(),l,o);break;case "o":q+=m("o",Math.round(((new Date(f.getFullYear(),f.getMonth(),f.getDate())).getTime()-
+(new Date(f.getFullYear(),0,0)).getTime())/864E5),3);break;case "m":q+=m("m",f.getMonth()+1,2);break;case "M":q+=p("M",f.getMonth(),n,j);break;case "y":q+=k("y")?f.getFullYear():(f.getYear()%100<10?"0":"")+f.getYear()%100;break;case "@":q+=f.getTime();break;case "!":q+=f.getTime()*1E4+this._ticksTo1970;break;case "'":if(k("'"))q+="'";else s=true;break;default:q+=b.charAt(r)}return q},_possibleChars:function(b){for(var f="",j=false,l=function(n){(n=o+1<b.length&&b.charAt(o+1)==n)&&o++;return n},o=
+0;o<b.length;o++)if(j)if(b.charAt(o)=="'"&&!l("'"))j=false;else f+=b.charAt(o);else switch(b.charAt(o)){case "d":case "m":case "y":case "@":f+="0123456789";break;case "D":case "M":return null;case "'":if(l("'"))f+="'";else j=true;break;default:f+=b.charAt(o)}return f},_get:function(b,f){return b.settings[f]!==d?b.settings[f]:this._defaults[f]},_setDateFromField:function(b,f){if(b.input.val()!=b.lastVal){var j=this._get(b,"dateFormat"),l=b.lastVal=b.input?b.input.val():null,o,n;o=n=this._getDefaultDate(b);
+var k=this._getFormatConfig(b);try{o=this.parseDate(j,l,k)||n}catch(m){this.log(m);l=f?"":l}b.selectedDay=o.getDate();b.drawMonth=b.selectedMonth=o.getMonth();b.drawYear=b.selectedYear=o.getFullYear();b.currentDay=l?o.getDate():0;b.currentMonth=l?o.getMonth():0;b.currentYear=l?o.getFullYear():0;this._adjustInstDate(b)}},_getDefaultDate:function(b){return this._restrictMinMax(b,this._determineDate(b,this._get(b,"defaultDate"),new Date))},_determineDate:function(b,f,j){var l=function(n){var k=new Date;
+k.setDate(k.getDate()+n);return k},o=function(n){try{return a.datepicker.parseDate(a.datepicker._get(b,"dateFormat"),n,a.datepicker._getFormatConfig(b))}catch(k){}var m=(n.toLowerCase().match(/^c/)?a.datepicker._getDate(b):null)||new Date,p=m.getFullYear(),q=m.getMonth();m=m.getDate();for(var s=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,r=s.exec(n);r;){switch(r[2]||"d"){case "d":case "D":m+=parseInt(r[1],10);break;case "w":case "W":m+=parseInt(r[1],10)*7;break;case "m":case "M":q+=parseInt(r[1],10);m=
+Math.min(m,a.datepicker._getDaysInMonth(p,q));break;case "y":case "Y":p+=parseInt(r[1],10);m=Math.min(m,a.datepicker._getDaysInMonth(p,q));break}r=s.exec(n)}return new Date(p,q,m)};if(f=(f=f==null||f===""?j:typeof f=="string"?o(f):typeof f=="number"?isNaN(f)?j:l(f):new Date(f.getTime()))&&f.toString()=="Invalid Date"?j:f){f.setHours(0);f.setMinutes(0);f.setSeconds(0);f.setMilliseconds(0)}return this._daylightSavingAdjust(f)},_daylightSavingAdjust:function(b){if(!b)return null;b.setHours(b.getHours()>
+12?b.getHours()+2:0);return b},_setDate:function(b,f,j){var l=!f,o=b.selectedMonth,n=b.selectedYear;f=this._restrictMinMax(b,this._determineDate(b,f,new Date));b.selectedDay=b.currentDay=f.getDate();b.drawMonth=b.selectedMonth=b.currentMonth=f.getMonth();b.drawYear=b.selectedYear=b.currentYear=f.getFullYear();if((o!=b.selectedMonth||n!=b.selectedYear)&&!j)this._notifyChange(b);this._adjustInstDate(b);if(b.input)b.input.val(l?"":this._formatDate(b))},_getDate:function(b){return!b.currentYear||b.input&&
+b.input.val()==""?null:this._daylightSavingAdjust(new Date(b.currentYear,b.currentMonth,b.currentDay))},_generateHTML:function(b){var f=new Date;f=this._daylightSavingAdjust(new Date(f.getFullYear(),f.getMonth(),f.getDate()));var j=this._get(b,"isRTL"),l=this._get(b,"showButtonPanel"),o=this._get(b,"hideIfNoPrevNext"),n=this._get(b,"navigationAsDateFormat"),k=this._getNumberOfMonths(b),m=this._get(b,"showCurrentAtPos"),p=this._get(b,"stepMonths"),q=k[0]!=1||k[1]!=1,s=this._daylightSavingAdjust(!b.currentDay?
+new Date(9999,9,9):new Date(b.currentYear,b.currentMonth,b.currentDay)),r=this._getMinMaxDate(b,"min"),u=this._getMinMaxDate(b,"max");m=b.drawMonth-m;var v=b.drawYear;if(m<0){m+=12;v--}if(u){var w=this._daylightSavingAdjust(new Date(u.getFullYear(),u.getMonth()-k[0]*k[1]+1,u.getDate()));for(w=r&&w<r?r:w;this._daylightSavingAdjust(new Date(v,m,1))>w;){m--;if(m<0){m=11;v--}}}b.drawMonth=m;b.drawYear=v;w=this._get(b,"prevText");w=!n?w:this.formatDate(w,this._daylightSavingAdjust(new Date(v,m-p,1)),this._getFormatConfig(b));
+w=this._canAdjustMonth(b,-1,v,m)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+g+".datepicker._adjustDate('#"+b.id+"', -"+p+", 'M');\" title=\""+w+'"><span class="ui-icon ui-icon-circle-triangle-'+(j?"e":"w")+'">'+w+"</span></a>":o?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+w+'"><span class="ui-icon ui-icon-circle-triangle-'+(j?"e":"w")+'">'+w+"</span></a>";var x=this._get(b,"nextText");x=!n?x:this.formatDate(x,this._daylightSavingAdjust(new Date(v,
+m+p,1)),this._getFormatConfig(b));o=this._canAdjustMonth(b,+1,v,m)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+g+".datepicker._adjustDate('#"+b.id+"', +"+p+", 'M');\" title=\""+x+'"><span class="ui-icon ui-icon-circle-triangle-'+(j?"w":"e")+'">'+x+"</span></a>":o?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+x+'"><span class="ui-icon ui-icon-circle-triangle-'+(j?"w":"e")+'">'+x+"</span></a>";p=this._get(b,"currentText");x=this._get(b,"gotoCurrent")&&
+b.currentDay?s:f;p=!n?p:this.formatDate(p,x,this._getFormatConfig(b));n=!b.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+g+'.datepicker._hideDatepicker();">'+this._get(b,"closeText")+"</button>":"";l=l?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(j?n:"")+(this._isInRange(b,x)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+
+g+".datepicker._gotoToday('#"+b.id+"');\">"+p+"</button>":"")+(j?"":n)+"</div>":"";n=parseInt(this._get(b,"firstDay"),10);n=isNaN(n)?0:n;p=this._get(b,"showWeek");x=this._get(b,"dayNames");this._get(b,"dayNamesShort");var y=this._get(b,"dayNamesMin"),H=this._get(b,"monthNames"),C=this._get(b,"monthNamesShort"),z=this._get(b,"beforeShowDay"),I=this._get(b,"showOtherMonths"),N=this._get(b,"selectOtherMonths");this._get(b,"calculateWeek");for(var J=this._getDefaultDate(b),D="",E=0;E<k[0];E++){var P=
+"";this.maxRows=4;for(var L=0;L<k[1];L++){var Q=this._daylightSavingAdjust(new Date(v,m,b.selectedDay)),B=" ui-corner-all",F="";if(q){F+='<div class="ui-datepicker-group';if(k[1]>1)switch(L){case 0:F+=" ui-datepicker-group-first";B=" ui-corner-"+(j?"right":"left");break;case k[1]-1:F+=" ui-datepicker-group-last";B=" ui-corner-"+(j?"left":"right");break;default:F+=" ui-datepicker-group-middle";B="";break}F+='">'}F+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+B+'">'+(/all|left/.test(B)&&
+E==0?j?o:w:"")+(/all|right/.test(B)&&E==0?j?w:o:"")+this._generateMonthYearHeader(b,m,v,r,u,E>0||L>0,H,C)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var G=p?'<th class="ui-datepicker-week-col">'+this._get(b,"weekHeader")+"</th>":"";for(B=0;B<7;B++){var A=(B+n)%7;G+="<th"+((B+n+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+x[A]+'">'+y[A]+"</span></th>"}F+=G+"</tr></thead><tbody>";G=this._getDaysInMonth(v,m);if(v==b.selectedYear&&m==b.selectedMonth)b.selectedDay=Math.min(b.selectedDay,
+G);B=(this._getFirstDayOfMonth(v,m)-n+7)%7;G=Math.ceil((B+G)/7);this.maxRows=G=q?this.maxRows>G?this.maxRows:G:G;A=this._daylightSavingAdjust(new Date(v,m,1-B));for(var R=0;R<G;R++){F+="<tr>";var S=!p?"":'<td class="ui-datepicker-week-col">'+this._get(b,"calculateWeek")(A)+"</td>";for(B=0;B<7;B++){var M=z?z.apply(b.input?b.input[0]:null,[A]):[true,""],K=A.getMonth()!=m,O=K&&!N||!M[0]||r&&A<r||u&&A>u;S+='<td class="'+((B+n+6)%7>=5?" ui-datepicker-week-end":"")+(K?" ui-datepicker-other-month":"")+(A.getTime()==
+Q.getTime()&&m==b.selectedMonth&&b._keyEvent||J.getTime()==A.getTime()&&J.getTime()==Q.getTime()?" "+this._dayOverClass:"")+(O?" "+this._unselectableClass+" ui-state-disabled":"")+(K&&!I?"":" "+M[1]+(A.getTime()==s.getTime()?" "+this._currentClass:"")+(A.getTime()==f.getTime()?" ui-datepicker-today":""))+'"'+((!K||I)&&M[2]?' title="'+M[2]+'"':"")+(O?"":' onclick="DP_jQuery_'+g+".datepicker._selectDay('#"+b.id+"',"+A.getMonth()+","+A.getFullYear()+', this);return false;"')+">"+(K&&!I?"&#xa0;":O?'<span class="ui-state-default">'+
+A.getDate()+"</span>":'<a class="ui-state-default'+(A.getTime()==f.getTime()?" ui-state-highlight":"")+(A.getTime()==s.getTime()?" ui-state-active":"")+(K?" ui-priority-secondary":"")+'" href="#">'+A.getDate()+"</a>")+"</td>";A.setDate(A.getDate()+1);A=this._daylightSavingAdjust(A)}F+=S+"</tr>"}m++;if(m>11){m=0;v++}F+="</tbody></table>"+(q?"</div>"+(k[0]>0&&L==k[1]-1?'<div class="ui-datepicker-row-break"></div>':""):"");P+=F}D+=P}D+=l+(a.browser.msie&&parseInt(a.browser.version,10)<7&&!b.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':
+"");b._keyEvent=false;return D},_generateMonthYearHeader:function(b,f,j,l,o,n,k,m){var p=this._get(b,"changeMonth"),q=this._get(b,"changeYear"),s=this._get(b,"showMonthAfterYear"),r='<div class="ui-datepicker-title">',u="";if(n||!p)u+='<span class="ui-datepicker-month">'+k[f]+"</span>";else{k=l&&l.getFullYear()==j;var v=o&&o.getFullYear()==j;u+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+g+".datepicker._selectMonthYear('#"+b.id+"', this, 'M');\" >";for(var w=0;w<12;w++)if((!k||w>=l.getMonth())&&
+(!v||w<=o.getMonth()))u+='<option value="'+w+'"'+(w==f?' selected="selected"':"")+">"+m[w]+"</option>";u+="</select>"}s||(r+=u+(n||!(p&&q)?"&#xa0;":""));if(!b.yearshtml){b.yearshtml="";if(n||!q)r+='<span class="ui-datepicker-year">'+j+"</span>";else{m=this._get(b,"yearRange").split(":");var x=(new Date).getFullYear();k=function(y){y=y.match(/c[+-].*/)?j+parseInt(y.substring(1),10):y.match(/[+-].*/)?x+parseInt(y,10):parseInt(y,10);return isNaN(y)?x:y};f=k(m[0]);m=Math.max(f,k(m[1]||""));f=l?Math.max(f,
+l.getFullYear()):f;m=o?Math.min(m,o.getFullYear()):m;for(b.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+g+".datepicker._selectMonthYear('#"+b.id+"', this, 'Y');\" >";f<=m;f++)b.yearshtml+='<option value="'+f+'"'+(f==j?' selected="selected"':"")+">"+f+"</option>";b.yearshtml+="</select>";r+=b.yearshtml;b.yearshtml=null}}r+=this._get(b,"yearSuffix");if(s)r+=(n||!(p&&q)?"&#xa0;":"")+u;r+="</div>";return r},_adjustInstDate:function(b,f,j){var l=b.drawYear+(j=="Y"?f:0),o=b.drawMonth+
+(j=="M"?f:0);f=Math.min(b.selectedDay,this._getDaysInMonth(l,o))+(j=="D"?f:0);l=this._restrictMinMax(b,this._daylightSavingAdjust(new Date(l,o,f)));b.selectedDay=l.getDate();b.drawMonth=b.selectedMonth=l.getMonth();b.drawYear=b.selectedYear=l.getFullYear();if(j=="M"||j=="Y")this._notifyChange(b)},_restrictMinMax:function(b,f){var j=this._getMinMaxDate(b,"min");b=this._getMinMaxDate(b,"max");f=j&&f<j?j:f;return f=b&&f>b?b:f},_notifyChange:function(b){var f=this._get(b,"onChangeMonthYear");if(f)f.apply(b.input?
+b.input[0]:null,[b.selectedYear,b.selectedMonth+1,b])},_getNumberOfMonths:function(b){b=this._get(b,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(b,f){return this._determineDate(b,this._get(b,f+"Date"),null)},_getDaysInMonth:function(b,f){return 32-this._daylightSavingAdjust(new Date(b,f,32)).getDate()},_getFirstDayOfMonth:function(b,f){return(new Date(b,f,1)).getDay()},_canAdjustMonth:function(b,f,j,l){var o=this._getNumberOfMonths(b);j=this._daylightSavingAdjust(new Date(j,
+l+(f<0?f:o[0]*o[1]),1));f<0&&j.setDate(this._getDaysInMonth(j.getFullYear(),j.getMonth()));return this._isInRange(b,j)},_isInRange:function(b,f){var j=this._getMinMaxDate(b,"min");b=this._getMinMaxDate(b,"max");return(!j||f.getTime()>=j.getTime())&&(!b||f.getTime()<=b.getTime())},_getFormatConfig:function(b){var f=this._get(b,"shortYearCutoff");f=typeof f!="string"?f:(new Date).getFullYear()%100+parseInt(f,10);return{shortYearCutoff:f,dayNamesShort:this._get(b,"dayNamesShort"),dayNames:this._get(b,
+"dayNames"),monthNamesShort:this._get(b,"monthNamesShort"),monthNames:this._get(b,"monthNames")}},_formatDate:function(b,f,j,l){if(!f){b.currentDay=b.selectedDay;b.currentMonth=b.selectedMonth;b.currentYear=b.selectedYear}f=f?typeof f=="object"?f:this._daylightSavingAdjust(new Date(l,j,f)):this._daylightSavingAdjust(new Date(b.currentYear,b.currentMonth,b.currentDay));return this.formatDate(this._get(b,"dateFormat"),f,this._getFormatConfig(b))}});a.fn.datepicker=function(b){if(!this.length)return this;
+if(!a.datepicker.initialized){a(document).mousedown(a.datepicker._checkExternalClick).find("body").append(a.datepicker.dpDiv);a.datepicker.initialized=true}var f=Array.prototype.slice.call(arguments,1);if(typeof b=="string"&&(b=="isDisabled"||b=="getDate"||b=="widget"))return a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this[0]].concat(f));if(b=="option"&&arguments.length==2&&typeof arguments[1]=="string")return a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this[0]].concat(f));return this.each(function(){typeof b==
+"string"?a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this].concat(f)):a.datepicker._attachDatepicker(this,b)})};a.datepicker=new c;a.datepicker.initialized=false;a.datepicker.uuid=(new Date).getTime();a.datepicker.version="1.8.16";window["DP_jQuery_"+g]=a})(jQuery);
+(function(a,d){var c={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},e={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true},h=a.attrFn||{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true,click:true};a.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,
+position:{my:"center",at:"center",collision:"fit",using:function(g){var i=a(this).css(g).offset().top;i<0&&a(this).css("top",g.top-i)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var g=this,i=g.options,b=i.title||"&#160;",f=a.ui.dialog.getTitleId(g.element),j=(g.uiDialog=a("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+
+i.dialogClass).css({zIndex:i.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(n){if(i.closeOnEscape&&!n.isDefaultPrevented()&&n.keyCode&&n.keyCode===a.ui.keyCode.ESCAPE){g.close(n);n.preventDefault()}}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(n){g.moveToTop(false,n)});g.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(j);var l=(g.uiDialogTitlebar=a("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(j),
+o=a('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){o.addClass("ui-state-hover")},function(){o.removeClass("ui-state-hover")}).focus(function(){o.addClass("ui-state-focus")}).blur(function(){o.removeClass("ui-state-focus")}).click(function(n){g.close(n);return false}).appendTo(l);(g.uiDialogTitlebarCloseText=a("<span></span>")).addClass("ui-icon ui-icon-closethick").text(i.closeText).appendTo(o);a("<span></span>").addClass("ui-dialog-title").attr("id",
+f).html(b).prependTo(l);if(a.isFunction(i.beforeclose)&&!a.isFunction(i.beforeClose))i.beforeClose=i.beforeclose;l.find("*").add(l).disableSelection();i.draggable&&a.fn.draggable&&g._makeDraggable();i.resizable&&a.fn.resizable&&g._makeResizable();g._createButtons(i.buttons);g._isOpen=false;a.fn.bgiframe&&j.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var g=this;g.overlay&&g.overlay.destroy();g.uiDialog.hide();g.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");
+g.uiDialog.remove();g.originalTitle&&g.element.attr("title",g.originalTitle);return g},widget:function(){return this.uiDialog},close:function(g){var i=this,b,f;if(false!==i._trigger("beforeClose",g)){i.overlay&&i.overlay.destroy();i.uiDialog.unbind("keypress.ui-dialog");i._isOpen=false;if(i.options.hide)i.uiDialog.hide(i.options.hide,function(){i._trigger("close",g)});else{i.uiDialog.hide();i._trigger("close",g)}a.ui.dialog.overlay.resize();if(i.options.modal){b=0;a(".ui-dialog").each(function(){if(this!==
+i.uiDialog[0]){f=a(this).css("z-index");isNaN(f)||(b=Math.max(b,f))}});a.ui.dialog.maxZ=b}return i}},isOpen:function(){return this._isOpen},moveToTop:function(g,i){var b=this,f=b.options;if(f.modal&&!g||!f.stack&&!f.modal)return b._trigger("focus",i);if(f.zIndex>a.ui.dialog.maxZ)a.ui.dialog.maxZ=f.zIndex;if(b.overlay){a.ui.dialog.maxZ+=1;b.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)}g={scrollTop:b.element.scrollTop(),scrollLeft:b.element.scrollLeft()};a.ui.dialog.maxZ+=1;
+b.uiDialog.css("z-index",a.ui.dialog.maxZ);b.element.attr(g);b._trigger("focus",i);return b},open:function(){if(!this._isOpen){var g=this,i=g.options,b=g.uiDialog;g.overlay=i.modal?new a.ui.dialog.overlay(g):null;g._size();g._position(i.position);b.show(i.show);g.moveToTop(true);i.modal&&b.bind("keypress.ui-dialog",function(f){if(f.keyCode===a.ui.keyCode.TAB){var j=a(":tabbable",this),l=j.filter(":first");j=j.filter(":last");if(f.target===j[0]&&!f.shiftKey){l.focus(1);return false}else if(f.target===
+l[0]&&f.shiftKey){j.focus(1);return false}}});a(g.element.find(":tabbable").get().concat(b.find(".ui-dialog-buttonpane :tabbable").get().concat(b.get()))).eq(0).focus();g._isOpen=true;g._trigger("open");return g}},_createButtons:function(g){var i=this,b=false,f=a("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),j=a("<div></div>").addClass("ui-dialog-buttonset").appendTo(f);i.uiDialog.find(".ui-dialog-buttonpane").remove();typeof g==="object"&&g!==null&&a.each(g,
+function(){return!(b=true)});if(b){a.each(g,function(l,o){o=a.isFunction(o)?{click:o,text:l}:o;var n=a('<button type="button"></button>').click(function(){o.click.apply(i.element[0],arguments)}).appendTo(j);a.each(o,function(k,m){if(k!=="click")k in h?n[k](m):n.attr(k,m)});a.fn.button&&n.button()});f.appendTo(i.uiDialog)}},_makeDraggable:function(){function g(l){return{position:l.position,offset:l.offset}}var i=this,b=i.options,f=a(document),j;i.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",
+handle:".ui-dialog-titlebar",containment:"document",start:function(l,o){j=b.height==="auto"?"auto":a(this).height();a(this).height(a(this).height()).addClass("ui-dialog-dragging");i._trigger("dragStart",l,g(o))},drag:function(l,o){i._trigger("drag",l,g(o))},stop:function(l,o){b.position=[o.position.left-f.scrollLeft(),o.position.top-f.scrollTop()];a(this).removeClass("ui-dialog-dragging").height(j);i._trigger("dragStop",l,g(o));a.ui.dialog.overlay.resize()}})},_makeResizable:function(g){function i(l){return{originalPosition:l.originalPosition,
+originalSize:l.originalSize,position:l.position,size:l.size}}g=g===d?this.options.resizable:g;var b=this,f=b.options,j=b.uiDialog.css("position");g=typeof g==="string"?g:"n,e,s,w,se,sw,ne,nw";b.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:b.element,maxWidth:f.maxWidth,maxHeight:f.maxHeight,minWidth:f.minWidth,minHeight:b._minHeight(),handles:g,start:function(l,o){a(this).addClass("ui-dialog-resizing");b._trigger("resizeStart",l,i(o))},resize:function(l,o){b._trigger("resize",
+l,i(o))},stop:function(l,o){a(this).removeClass("ui-dialog-resizing");f.height=a(this).height();f.width=a(this).width();b._trigger("resizeStop",l,i(o));a.ui.dialog.overlay.resize()}}).css("position",j).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var g=this.options;return g.height==="auto"?g.minHeight:Math.min(g.minHeight,g.height)},_position:function(g){var i=[],b=[0,0],f;if(g){if(typeof g==="string"||typeof g==="object"&&"0"in g){i=g.split?g.split(" "):
+[g[0],g[1]];if(i.length===1)i[1]=i[0];a.each(["left","top"],function(j,l){if(+i[j]===i[j]){b[j]=i[j];i[j]=l}});g={my:i.join(" "),at:i.join(" "),offset:b.join(" ")}}g=a.extend({},a.ui.dialog.prototype.options.position,g)}else g=a.ui.dialog.prototype.options.position;(f=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},g));f||this.uiDialog.hide()},_setOptions:function(g){var i=this,b={},f=false;a.each(g,function(j,l){i._setOption(j,l);
+if(j in c)f=true;if(j in e)b[j]=l});f&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",b)},_setOption:function(g,i){var b=this,f=b.uiDialog;switch(g){case "beforeclose":g="beforeClose";break;case "buttons":b._createButtons(i);break;case "closeText":b.uiDialogTitlebarCloseText.text(""+i);break;case "dialogClass":f.removeClass(b.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+i);break;case "disabled":i?f.addClass("ui-dialog-disabled"):
+f.removeClass("ui-dialog-disabled");break;case "draggable":var j=f.is(":data(draggable)");j&&!i&&f.draggable("destroy");!j&&i&&b._makeDraggable();break;case "position":b._position(i);break;case "resizable":(j=f.is(":data(resizable)"))&&!i&&f.resizable("destroy");j&&typeof i==="string"&&f.resizable("option","handles",i);!j&&i!==false&&b._makeResizable(i);break;case "title":a(".ui-dialog-title",b.uiDialogTitlebar).html(""+(i||"&#160;"));break}a.Widget.prototype._setOption.apply(b,arguments)},_size:function(){var g=
+this.options,i,b,f=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(g.minWidth>g.width)g.width=g.minWidth;i=this.uiDialog.css({height:"auto",width:g.width}).height();b=Math.max(0,g.minHeight-i);if(g.height==="auto")if(a.support.minHeight)this.element.css({minHeight:b,height:"auto"});else{this.uiDialog.show();g=this.element.css("height","auto").height();f||this.uiDialog.hide();this.element.height(Math.max(g,b))}else this.element.height(Math.max(g.height-
+i,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});a.extend(a.ui.dialog,{version:"1.8.16",uuid:0,maxZ:0,getTitleId:function(g){g=g.attr("id");if(!g){this.uuid+=1;g=this.uuid}return"ui-dialog-title-"+g},overlay:function(g){this.$el=a.ui.dialog.overlay.create(g)}});a.extend(a.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:a.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(g){return g+".dialog-overlay"}).join(" "),
+create:function(g){if(this.instances.length===0){setTimeout(function(){a.ui.dialog.overlay.instances.length&&a(document).bind(a.ui.dialog.overlay.events,function(b){if(a(b.target).zIndex()<a.ui.dialog.overlay.maxZ)return false})},1);a(document).bind("keydown.dialog-overlay",function(b){if(g.options.closeOnEscape&&!b.isDefaultPrevented()&&b.keyCode&&b.keyCode===a.ui.keyCode.ESCAPE){g.close(b);b.preventDefault()}});a(window).bind("resize.dialog-overlay",a.ui.dialog.overlay.resize)}var i=(this.oldInstances.pop()||
+a("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});a.fn.bgiframe&&i.bgiframe();this.instances.push(i);return i},destroy:function(g){var i=a.inArray(g,this.instances);i!=-1&&this.oldInstances.push(this.instances.splice(i,1)[0]);this.instances.length===0&&a([document,window]).unbind(".dialog-overlay");g.remove();var b=0;a.each(this.instances,function(){b=Math.max(b,this.css("z-index"))});this.maxZ=b},height:function(){var g,i;if(a.browser.msie&&
+a.browser.version<7){g=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);i=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return g<i?a(window).height()+"px":g+"px"}else return a(document).height()+"px"},width:function(){var g,i;if(a.browser.msie){g=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);i=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return g<i?a(window).width()+"px":g+"px"}else return a(document).width()+
+"px"},resize:function(){var g=a([]);a.each(a.ui.dialog.overlay.instances,function(){g=g.add(this)});g.css({width:0,height:0}).css({width:a.ui.dialog.overlay.width(),height:a.ui.dialog.overlay.height()})}});a.extend(a.ui.dialog.overlay.prototype,{destroy:function(){a.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
+(function(a){a.ui=a.ui||{};var d=/left|center|right/,c=/top|center|bottom/,e=a.fn.position,h=a.fn.offset;a.fn.position=function(g){if(!g||!g.of)return e.apply(this,arguments);g=a.extend({},g);var i=a(g.of),b=i[0],f=(g.collision||"flip").split(" "),j=g.offset?g.offset.split(" "):[0,0],l,o,n;if(b.nodeType===9){l=i.width();o=i.height();n={top:0,left:0}}else if(b.setTimeout){l=i.width();o=i.height();n={top:i.scrollTop(),left:i.scrollLeft()}}else if(b.preventDefault){g.at="left top";l=o=0;n={top:g.of.pageY,
+left:g.of.pageX}}else{l=i.outerWidth();o=i.outerHeight();n=i.offset()}a.each(["my","at"],function(){var k=(g[this]||"").split(" ");if(k.length===1)k=d.test(k[0])?k.concat(["center"]):c.test(k[0])?["center"].concat(k):["center","center"];k[0]=d.test(k[0])?k[0]:"center";k[1]=c.test(k[1])?k[1]:"center";g[this]=k});if(f.length===1)f[1]=f[0];j[0]=parseInt(j[0],10)||0;if(j.length===1)j[1]=j[0];j[1]=parseInt(j[1],10)||0;if(g.at[0]==="right")n.left+=l;else if(g.at[0]==="center")n.left+=l/2;if(g.at[1]==="bottom")n.top+=
+o;else if(g.at[1]==="center")n.top+=o/2;n.left+=j[0];n.top+=j[1];return this.each(function(){var k=a(this),m=k.outerWidth(),p=k.outerHeight(),q=parseInt(a.curCSS(this,"marginLeft",true))||0,s=parseInt(a.curCSS(this,"marginTop",true))||0,r=m+q+(parseInt(a.curCSS(this,"marginRight",true))||0),u=p+s+(parseInt(a.curCSS(this,"marginBottom",true))||0),v=a.extend({},n),w;if(g.my[0]==="right")v.left-=m;else if(g.my[0]==="center")v.left-=m/2;if(g.my[1]==="bottom")v.top-=p;else if(g.my[1]==="center")v.top-=
+p/2;v.left=Math.round(v.left);v.top=Math.round(v.top);w={left:v.left-q,top:v.top-s};a.each(["left","top"],function(x,y){a.ui.position[f[x]]&&a.ui.position[f[x]][y](v,{targetWidth:l,targetHeight:o,elemWidth:m,elemHeight:p,collisionPosition:w,collisionWidth:r,collisionHeight:u,offset:j,my:g.my,at:g.at})});a.fn.bgiframe&&k.bgiframe();k.offset(a.extend(v,{using:g.using}))})};a.ui.position={fit:{left:function(g,i){var b=a(window);b=i.collisionPosition.left+i.collisionWidth-b.width()-b.scrollLeft();g.left=
+b>0?g.left-b:Math.max(g.left-i.collisionPosition.left,g.left)},top:function(g,i){var b=a(window);b=i.collisionPosition.top+i.collisionHeight-b.height()-b.scrollTop();g.top=b>0?g.top-b:Math.max(g.top-i.collisionPosition.top,g.top)}},flip:{left:function(g,i){if(i.at[0]!=="center"){var b=a(window);b=i.collisionPosition.left+i.collisionWidth-b.width()-b.scrollLeft();var f=i.my[0]==="left"?-i.elemWidth:i.my[0]==="right"?i.elemWidth:0,j=i.at[0]==="left"?i.targetWidth:-i.targetWidth,l=-2*i.offset[0];g.left+=
+i.collisionPosition.left<0?f+j+l:b>0?f+j+l:0}},top:function(g,i){if(i.at[1]!=="center"){var b=a(window);b=i.collisionPosition.top+i.collisionHeight-b.height()-b.scrollTop();var f=i.my[1]==="top"?-i.elemHeight:i.my[1]==="bottom"?i.elemHeight:0,j=i.at[1]==="top"?i.targetHeight:-i.targetHeight,l=-2*i.offset[1];g.top+=i.collisionPosition.top<0?f+j+l:b>0?f+j+l:0}}}};if(!a.offset.setOffset){a.offset.setOffset=function(g,i){if(/static/.test(a.curCSS(g,"position")))g.style.position="relative";var b=a(g),
+f=b.offset(),j=parseInt(a.curCSS(g,"top",true),10)||0,l=parseInt(a.curCSS(g,"left",true),10)||0;f={top:i.top-f.top+j,left:i.left-f.left+l};"using"in i?i.using.call(g,f):b.css(f)};a.fn.offset=function(g){var i=this[0];if(!i||!i.ownerDocument)return null;if(g)return this.each(function(){a.offset.setOffset(this,g)});return h.call(this)}}})(jQuery);
+(function(a,d){a.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=a("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow");
+this.valueDiv.remove();a.Widget.prototype.destroy.apply(this,arguments)},value:function(c){if(c===d)return this._value();this._setOption("value",c);return this},_setOption:function(c,e){if(c==="value"){this.options.value=e;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}a.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var c=this.options.value;if(typeof c!=="number")c=0;return Math.min(this.options.max,Math.max(this.min,c))},_percentage:function(){return 100*
+this._value()/this.options.max},_refreshValue:function(){var c=this.value(),e=this._percentage();if(this.oldValue!==c){this.oldValue=c;this._trigger("change")}this.valueDiv.toggle(c>this.min).toggleClass("ui-corner-right",c===this.options.max).width(e.toFixed(0)+"%");this.element.attr("aria-valuenow",c)}});a.extend(a.ui.progressbar,{version:"1.8.16"})})(jQuery);
+(function(a){a.widget("ui.slider",a.ui.mouse,{widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var d=this,c=this.options,e=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),h=c.values&&c.values.length||1,g=[];this._mouseSliding=this._keySliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+
+this.orientation+" ui-widget ui-widget-content ui-corner-all"+(c.disabled?" ui-slider-disabled ui-disabled":""));this.range=a([]);if(c.range){if(c.range===true){if(!c.values)c.values=[this._valueMin(),this._valueMin()];if(c.values.length&&c.values.length!==2)c.values=[c.values[0],c.values[0]]}this.range=a("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(c.range==="min"||c.range==="max"?" ui-slider-range-"+c.range:""))}for(var i=e.length;i<h;i+=1)g.push("<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>");
+this.handles=e.add(a(g.join("")).appendTo(d.element));this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(b){b.preventDefault()}).hover(function(){c.disabled||a(this).addClass("ui-state-hover")},function(){a(this).removeClass("ui-state-hover")}).focus(function(){if(c.disabled)a(this).blur();else{a(".ui-slider .ui-state-focus").removeClass("ui-state-focus");a(this).addClass("ui-state-focus")}}).blur(function(){a(this).removeClass("ui-state-focus")});this.handles.each(function(b){a(this).data("index.ui-slider-handle",
+b)});this.handles.keydown(function(b){var f=true,j=a(this).data("index.ui-slider-handle"),l,o,n;if(!d.options.disabled){switch(b.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.PAGE_UP:case a.ui.keyCode.PAGE_DOWN:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:f=false;if(!d._keySliding){d._keySliding=true;a(this).addClass("ui-state-active");l=d._start(b,j);if(l===false)return}break}n=d.options.step;l=d.options.values&&d.options.values.length?
+(o=d.values(j)):(o=d.value());switch(b.keyCode){case a.ui.keyCode.HOME:o=d._valueMin();break;case a.ui.keyCode.END:o=d._valueMax();break;case a.ui.keyCode.PAGE_UP:o=d._trimAlignValue(l+(d._valueMax()-d._valueMin())/5);break;case a.ui.keyCode.PAGE_DOWN:o=d._trimAlignValue(l-(d._valueMax()-d._valueMin())/5);break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(l===d._valueMax())return;o=d._trimAlignValue(l+n);break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(l===d._valueMin())return;o=d._trimAlignValue(l-
+n);break}d._slide(b,j,o);return f}}).keyup(function(b){var f=a(this).data("index.ui-slider-handle");if(d._keySliding){d._keySliding=false;d._stop(b,f);d._change(b,f);a(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy();
+return this},_mouseCapture:function(d){var c=this.options,e,h,g,i,b;if(c.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();e=this._normValueFromMouse({x:d.pageX,y:d.pageY});h=this._valueMax()-this._valueMin()+1;i=this;this.handles.each(function(f){var j=Math.abs(e-i.values(f));if(h>j){h=j;g=a(this);b=f}});if(c.range===true&&this.values(1)===c.min){b+=1;g=a(this.handles[b])}if(this._start(d,b)===false)return false;
+this._mouseSliding=true;i._handleIndex=b;g.addClass("ui-state-active").focus();c=g.offset();this._clickOffset=!a(d.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:d.pageX-c.left-g.width()/2,top:d.pageY-c.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(d,b,e);return this._animateOff=true},_mouseStart:function(){return true},_mouseDrag:function(d){var c=
+this._normValueFromMouse({x:d.pageX,y:d.pageY});this._slide(d,this._handleIndex,c);return false},_mouseStop:function(d){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(d,this._handleIndex);this._change(d,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(d){var c;if(this.orientation==="horizontal"){c=
+this.elementSize.width;d=d.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{c=this.elementSize.height;d=d.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}c=d/c;if(c>1)c=1;if(c<0)c=0;if(this.orientation==="vertical")c=1-c;d=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+c*d)},_start:function(d,c){var e={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){e.value=this.values(c);
+e.values=this.values()}return this._trigger("start",d,e)},_slide:function(d,c,e){var h;if(this.options.values&&this.options.values.length){h=this.values(c?0:1);if(this.options.values.length===2&&this.options.range===true&&(c===0&&e>h||c===1&&e<h))e=h;if(e!==this.values(c)){h=this.values();h[c]=e;d=this._trigger("slide",d,{handle:this.handles[c],value:e,values:h});this.values(c?0:1);d!==false&&this.values(c,e,true)}}else if(e!==this.value()){d=this._trigger("slide",d,{handle:this.handles[c],value:e});
+d!==false&&this.value(e)}},_stop:function(d,c){var e={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){e.value=this.values(c);e.values=this.values()}this._trigger("stop",d,e)},_change:function(d,c){if(!this._keySliding&&!this._mouseSliding){var e={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){e.value=this.values(c);e.values=this.values()}this._trigger("change",d,e)}},value:function(d){if(arguments.length){this.options.value=
+this._trimAlignValue(d);this._refreshValue();this._change(null,0)}else return this._value()},values:function(d,c){var e,h,g;if(arguments.length>1){this.options.values[d]=this._trimAlignValue(c);this._refreshValue();this._change(null,d)}else if(arguments.length)if(a.isArray(arguments[0])){e=this.options.values;h=arguments[0];for(g=0;g<e.length;g+=1){e[g]=this._trimAlignValue(h[g]);this._change(null,g)}this._refreshValue()}else return this.options.values&&this.options.values.length?this._values(d):
+this.value();else return this._values()},_setOption:function(d,c){var e,h=0;if(a.isArray(this.options.values))h=this.options.values.length;a.Widget.prototype._setOption.apply(this,arguments);switch(d){case "disabled":if(c){this.handles.filter(".ui-state-focus").blur();this.handles.removeClass("ui-state-hover");this.handles.propAttr("disabled",true);this.element.addClass("ui-disabled")}else{this.handles.propAttr("disabled",false);this.element.removeClass("ui-disabled")}break;case "orientation":this._detectOrientation();
+this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);this._refreshValue();break;case "value":this._animateOff=true;this._refreshValue();this._change(null,0);this._animateOff=false;break;case "values":this._animateOff=true;this._refreshValue();for(e=0;e<h;e+=1)this._change(null,e);this._animateOff=false;break}},_value:function(){var d=this.options.value;return d=this._trimAlignValue(d)},_values:function(d){var c,e;if(arguments.length){c=this.options.values[d];
+return c=this._trimAlignValue(c)}else{c=this.options.values.slice();for(e=0;e<c.length;e+=1)c[e]=this._trimAlignValue(c[e]);return c}},_trimAlignValue:function(d){if(d<=this._valueMin())return this._valueMin();if(d>=this._valueMax())return this._valueMax();var c=this.options.step>0?this.options.step:1,e=(d-this._valueMin())%c;d=d-e;if(Math.abs(e)*2>=c)d+=e>0?c:-c;return parseFloat(d.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var d=
+this.options.range,c=this.options,e=this,h=!this._animateOff?c.animate:false,g,i={},b,f,j,l;if(this.options.values&&this.options.values.length)this.handles.each(function(o){g=(e.values(o)-e._valueMin())/(e._valueMax()-e._valueMin())*100;i[e.orientation==="horizontal"?"left":"bottom"]=g+"%";a(this).stop(1,1)[h?"animate":"css"](i,c.animate);if(e.options.range===true)if(e.orientation==="horizontal"){if(o===0)e.range.stop(1,1)[h?"animate":"css"]({left:g+"%"},c.animate);if(o===1)e.range[h?"animate":"css"]({width:g-
+b+"%"},{queue:false,duration:c.animate})}else{if(o===0)e.range.stop(1,1)[h?"animate":"css"]({bottom:g+"%"},c.animate);if(o===1)e.range[h?"animate":"css"]({height:g-b+"%"},{queue:false,duration:c.animate})}b=g});else{f=this.value();j=this._valueMin();l=this._valueMax();g=l!==j?(f-j)/(l-j)*100:0;i[e.orientation==="horizontal"?"left":"bottom"]=g+"%";this.handle.stop(1,1)[h?"animate":"css"](i,c.animate);if(d==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[h?"animate":"css"]({width:g+"%"},
+c.animate);if(d==="max"&&this.orientation==="horizontal")this.range[h?"animate":"css"]({width:100-g+"%"},{queue:false,duration:c.animate});if(d==="min"&&this.orientation==="vertical")this.range.stop(1,1)[h?"animate":"css"]({height:g+"%"},c.animate);if(d==="max"&&this.orientation==="vertical")this.range[h?"animate":"css"]({height:100-g+"%"},{queue:false,duration:c.animate})}}});a.extend(a.ui.slider,{version:"1.8.16"})})(jQuery);
+(function(a,d){function c(){return++h}function e(){return++g}var h=0,g=0;a.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(true)},_setOption:function(i,b){if(i=="selected")this.options.collapsible&&
+b==this.options.selected||this.select(b);else{this.options[i]=b;this._tabify()}},_tabId:function(i){return i.title&&i.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+c()},_sanitizeSelector:function(i){return i.replace(/:/g,"\\:")},_cookie:function(){var i=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+e());return a.cookie.apply(null,[i].concat(a.makeArray(arguments)))},_ui:function(i,b){return{tab:i,panel:b,index:this.anchors.index(i)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var i=
+a(this);i.html(i.data("label.tabs")).removeData("label.tabs")})},_tabify:function(i){function b(r,u){r.css("display","");!a.support.opacity&&u.opacity&&r[0].style.removeAttribute("filter")}var f=this,j=this.options,l=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=a(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return a("a",this)[0]});this.panels=a([]);this.anchors.each(function(r,u){var v=a(u).attr("href"),w=v.split("#")[0],x;if(w&&(w===location.toString().split("#")[0]||
+(x=a("base")[0])&&w===x.href)){v=u.hash;u.href=v}if(l.test(v))f.panels=f.panels.add(f.element.find(f._sanitizeSelector(v)));else if(v&&v!=="#"){a.data(u,"href.tabs",v);a.data(u,"load.tabs",v.replace(/#.*$/,""));v=f._tabId(u);u.href="#"+v;u=f.element.find("#"+v);if(!u.length){u=a(j.panelTemplate).attr("id",v).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(f.panels[r-1]||f.list);u.data("destroy.tabs",true)}f.panels=f.panels.add(u)}else j.disabled.push(r)});if(i){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");
+this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(j.selected===d){location.hash&&this.anchors.each(function(r,u){if(u.hash==location.hash){j.selected=r;return false}});if(typeof j.selected!=="number"&&j.cookie)j.selected=parseInt(f._cookie(),10);if(typeof j.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)j.selected=
+this.lis.index(this.lis.filter(".ui-tabs-selected"));j.selected=j.selected||(this.lis.length?0:-1)}else if(j.selected===null)j.selected=-1;j.selected=j.selected>=0&&this.anchors[j.selected]||j.selected<0?j.selected:0;j.disabled=a.unique(j.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(r){return f.lis.index(r)}))).sort();a.inArray(j.selected,j.disabled)!=-1&&j.disabled.splice(a.inArray(j.selected,j.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");
+if(j.selected>=0&&this.anchors.length){f.element.find(f._sanitizeSelector(f.anchors[j.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(j.selected).addClass("ui-tabs-selected ui-state-active");f.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[j.selected],f.element.find(f._sanitizeSelector(f.anchors[j.selected].hash))[0]))});this.load(j.selected)}a(window).bind("unload",function(){f.lis.add(f.anchors).unbind(".tabs");f.lis=f.anchors=f.panels=null})}else j.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));
+this.element[j.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");j.cookie&&this._cookie(j.selected,j.cookie);i=0;for(var o;o=this.lis[i];i++)a(o)[a.inArray(i,j.disabled)!=-1&&!a(o).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");j.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(j.event!=="mouseover"){var n=function(r,u){u.is(":not(.ui-state-disabled)")&&u.addClass("ui-state-"+r)},k=function(r,u){u.removeClass("ui-state-"+
+r)};this.lis.bind("mouseover.tabs",function(){n("hover",a(this))});this.lis.bind("mouseout.tabs",function(){k("hover",a(this))});this.anchors.bind("focus.tabs",function(){n("focus",a(this).closest("li"))});this.anchors.bind("blur.tabs",function(){k("focus",a(this).closest("li"))})}var m,p;if(j.fx)if(a.isArray(j.fx)){m=j.fx[0];p=j.fx[1]}else m=p=j.fx;var q=p?function(r,u){a(r).closest("li").addClass("ui-tabs-selected ui-state-active");u.hide().removeClass("ui-tabs-hide").animate(p,p.duration||"normal",
+function(){b(u,p);f._trigger("show",null,f._ui(r,u[0]))})}:function(r,u){a(r).closest("li").addClass("ui-tabs-selected ui-state-active");u.removeClass("ui-tabs-hide");f._trigger("show",null,f._ui(r,u[0]))},s=m?function(r,u){u.animate(m,m.duration||"normal",function(){f.lis.removeClass("ui-tabs-selected ui-state-active");u.addClass("ui-tabs-hide");b(u,m);f.element.dequeue("tabs")})}:function(r,u){f.lis.removeClass("ui-tabs-selected ui-state-active");u.addClass("ui-tabs-hide");f.element.dequeue("tabs")};
+this.anchors.bind(j.event+".tabs",function(){var r=this,u=a(r).closest("li"),v=f.panels.filter(":not(.ui-tabs-hide)"),w=f.element.find(f._sanitizeSelector(r.hash));if(u.hasClass("ui-tabs-selected")&&!j.collapsible||u.hasClass("ui-state-disabled")||u.hasClass("ui-state-processing")||f.panels.filter(":animated").length||f._trigger("select",null,f._ui(this,w[0]))===false){this.blur();return false}j.selected=f.anchors.index(this);f.abort();if(j.collapsible)if(u.hasClass("ui-tabs-selected")){j.selected=
+-1;j.cookie&&f._cookie(j.selected,j.cookie);f.element.queue("tabs",function(){s(r,v)}).dequeue("tabs");this.blur();return false}else if(!v.length){j.cookie&&f._cookie(j.selected,j.cookie);f.element.queue("tabs",function(){q(r,w)});f.load(f.anchors.index(this));this.blur();return false}j.cookie&&f._cookie(j.selected,j.cookie);if(w.length){v.length&&f.element.queue("tabs",function(){s(r,v)});f.element.queue("tabs",function(){q(r,w)});f.load(f.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier.";
+a.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(i){if(typeof i=="string")i=this.anchors.index(this.anchors.filter("[href$="+i+"]"));return i},destroy:function(){var i=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var b=
+a.data(this,"href.tabs");if(b)this.href=b;var f=a(this).unbind(".tabs");a.each(["href","load","cache"],function(j,l){f.removeData(l+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});i.cookie&&this._cookie(null,i.cookie);return this},add:function(i,
+b,f){if(f===d)f=this.anchors.length;var j=this,l=this.options;b=a(l.tabTemplate.replace(/#\{href\}/g,i).replace(/#\{label\}/g,b));i=!i.indexOf("#")?i.replace("#",""):this._tabId(a("a",b)[0]);b.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var o=j.element.find("#"+i);o.length||(o=a(l.panelTemplate).attr("id",i).data("destroy.tabs",true));o.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(f>=this.lis.length){b.appendTo(this.list);o.appendTo(this.list[0].parentNode)}else{b.insertBefore(this.lis[f]);
+o.insertBefore(this.panels[f])}l.disabled=a.map(l.disabled,function(n){return n>=f?++n:n});this._tabify();if(this.anchors.length==1){l.selected=0;b.addClass("ui-tabs-selected ui-state-active");o.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){j._trigger("show",null,j._ui(j.anchors[0],j.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[f],this.panels[f]));return this},remove:function(i){i=this._getIndex(i);var b=this.options,f=this.lis.eq(i).remove(),j=this.panels.eq(i).remove();
+if(f.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(i+(i+1<this.anchors.length?1:-1));b.disabled=a.map(a.grep(b.disabled,function(l){return l!=i}),function(l){return l>=i?--l:l});this._tabify();this._trigger("remove",null,this._ui(f.find("a")[0],j[0]));return this},enable:function(i){i=this._getIndex(i);var b=this.options;if(a.inArray(i,b.disabled)!=-1){this.lis.eq(i).removeClass("ui-state-disabled");b.disabled=a.grep(b.disabled,function(f){return f!=i});this._trigger("enable",null,
+this._ui(this.anchors[i],this.panels[i]));return this}},disable:function(i){i=this._getIndex(i);var b=this.options;if(i!=b.selected){this.lis.eq(i).addClass("ui-state-disabled");b.disabled.push(i);b.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[i],this.panels[i]))}return this},select:function(i){i=this._getIndex(i);if(i==-1)if(this.options.collapsible&&this.options.selected!=-1)i=this.options.selected;else return this;this.anchors.eq(i).trigger(this.options.event+".tabs");return this},
+load:function(i){i=this._getIndex(i);var b=this,f=this.options,j=this.anchors.eq(i)[0],l=a.data(j,"load.tabs");this.abort();if(!l||this.element.queue("tabs").length!==0&&a.data(j,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(i).addClass("ui-state-processing");if(f.spinner){var o=a("span",j);o.data("label.tabs",o.html()).html(f.spinner)}this.xhr=a.ajax(a.extend({},f.ajaxOptions,{url:l,success:function(n,k){b.element.find(b._sanitizeSelector(j.hash)).html(n);b._cleanup();f.cache&&a.data(j,
+"cache.tabs",true);b._trigger("load",null,b._ui(b.anchors[i],b.panels[i]));try{f.ajaxOptions.success(n,k)}catch(m){}},error:function(n,k){b._cleanup();b._trigger("load",null,b._ui(b.anchors[i],b.panels[i]));try{f.ajaxOptions.error(n,k,i,j)}catch(m){}}}));b.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this},
+url:function(i,b){this.anchors.eq(i).removeData("cache.tabs").data("load.tabs",b);return this},length:function(){return this.anchors.length}});a.extend(a.ui.tabs,{version:"1.8.16"});a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(i,b){var f=this,j=this.options,l=f._rotate||(f._rotate=function(o){clearTimeout(f.rotation);f.rotation=setTimeout(function(){var n=j.selected;f.select(++n<f.anchors.length?n:0)},i);o&&o.stopPropagation()});b=f._unrotate||(f._unrotate=!b?function(o){o.clientX&&
+f.rotate(null)}:function(){t=j.selected;l()});if(i){this.element.bind("tabsshow",l);this.anchors.bind(j.event+".tabs",b);l()}else{clearTimeout(f.rotation);this.element.unbind("tabsshow",l);this.anchors.unbind(j.event+".tabs",b);delete this._rotate;delete this._unrotate}return this}})})(jQuery);
diff --git a/lib/scripts/jquery/jquery.cookie.js b/lib/scripts/jquery/jquery.cookie.js
new file mode 100644
index 000000000..6a3e394b4
--- /dev/null
+++ b/lib/scripts/jquery/jquery.cookie.js
@@ -0,0 +1,41 @@
+/**
+ * jQuery Cookie plugin
+ *
+ * Copyright (c) 2010 Klaus Hartl (stilbuero.de)
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+jQuery.cookie = function (key, value, options) {
+
+ // key and at least value given, set cookie...
+ if (arguments.length > 1 && String(value) !== "[object Object]") {
+ options = jQuery.extend({}, options);
+
+ if (value === null || value === undefined) {
+ options.expires = -1;
+ }
+
+ if (typeof options.expires === 'number') {
+ var days = options.expires, t = options.expires = new Date();
+ t.setDate(t.getDate() + days);
+ }
+
+ value = String(value);
+
+ return (document.cookie = [
+ encodeURIComponent(key), '=',
+ options.raw ? value : encodeURIComponent(value),
+ options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
+ options.path ? '; path=' + options.path : '',
+ options.domain ? '; domain=' + options.domain : '',
+ options.secure ? '; secure' : ''
+ ].join(''));
+ }
+
+ // key and possibly options given, get cookie...
+ options = value || {};
+ var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
+ return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
+};
diff --git a/lib/scripts/jquery/jquery.js b/lib/scripts/jquery/jquery.js
new file mode 100644
index 000000000..719e1d4ec
--- /dev/null
+++ b/lib/scripts/jquery/jquery.js
@@ -0,0 +1,9046 @@
+/*!
+ * jQuery JavaScript Library v1.6.4
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Mon Sep 12 18:54:48 2011 -0400
+ */
+(function( window, undefined ) {
+
+// Use the correct document accordingly with window argument (sandbox)
+var document = window.document,
+ navigator = window.navigator,
+ location = window.location;
+var jQuery = (function() {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context, rootjQuery );
+ },
+
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ // A central reference to the root jQuery(document)
+ rootjQuery,
+
+ // A simple way to check for HTML strings or ID strings
+ // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+ quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
+
+ // Check if a string has a non-whitespace character in it
+ rnotwhite = /\S/,
+
+ // Used for trimming whitespace
+ trimLeft = /^\s+/,
+ trimRight = /\s+$/,
+
+ // Check for digits
+ rdigit = /\d/,
+
+ // Match a standalone tag
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+ // JSON RegExp
+ rvalidchars = /^[\],:{}\s]*$/,
+ rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
+ rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+ rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+
+ // Useragent RegExp
+ rwebkit = /(webkit)[ \/]([\w.]+)/,
+ ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
+ rmsie = /(msie) ([\w.]+)/,
+ rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
+
+ // Matches dashed string for camelizing
+ rdashAlpha = /-([a-z]|[0-9])/ig,
+ rmsPrefix = /^-ms-/,
+
+ // Used by jQuery.camelCase as callback to replace()
+ fcamelCase = function( all, letter ) {
+ return ( letter + "" ).toUpperCase();
+ },
+
+ // Keep a UserAgent string for use with jQuery.browser
+ userAgent = navigator.userAgent,
+
+ // For matching the engine and version of the browser
+ browserMatch,
+
+ // The deferred used on DOM ready
+ readyList,
+
+ // The ready event handler
+ DOMContentLoaded,
+
+ // Save a reference to some core methods
+ toString = Object.prototype.toString,
+ hasOwn = Object.prototype.hasOwnProperty,
+ push = Array.prototype.push,
+ slice = Array.prototype.slice,
+ trim = String.prototype.trim,
+ indexOf = Array.prototype.indexOf,
+
+ // [[Class]] -> type pairs
+ class2type = {};
+
+jQuery.fn = jQuery.prototype = {
+ constructor: jQuery,
+ init: function( selector, context, rootjQuery ) {
+ var match, elem, ret, doc;
+
+ // Handle $(""), $(null), or $(undefined)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this.context = this[0] = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // The body element only exists once, optimize finding it
+ if ( selector === "body" && !context && document.body ) {
+ this.context = document;
+ this[0] = document.body;
+ this.selector = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ // Are we dealing with HTML string or an ID?
+ if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+ // Assume that strings that start and end with <> are HTML and skip the regex check
+ match = [ null, selector, null ];
+
+ } else {
+ match = quickExpr.exec( selector );
+ }
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] ) {
+ context = context instanceof jQuery ? context[0] : context;
+ doc = (context ? context.ownerDocument || context : document);
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ ret = rsingleTag.exec( selector );
+
+ if ( ret ) {
+ if ( jQuery.isPlainObject( context ) ) {
+ selector = [ document.createElement( ret[1] ) ];
+ jQuery.fn.attr.call( selector, context, true );
+
+ } else {
+ selector = [ doc.createElement( ret[1] ) ];
+ }
+
+ } else {
+ ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
+ selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
+ }
+
+ return jQuery.merge( this, selector );
+
+ // HANDLE: $("#id")
+ } else {
+ elem = document.getElementById( match[2] );
+
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id !== match[2] ) {
+ return rootjQuery.find( selector );
+ }
+
+ // Otherwise, we inject the element directly into the jQuery object
+ this.length = 1;
+ this[0] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return (context || rootjQuery).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor( context ).find( selector );
+ }
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return rootjQuery.ready( selector );
+ }
+
+ if (selector.selector !== undefined) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.makeArray( selector, this );
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The current version of jQuery being used
+ jquery: "1.6.4",
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ toArray: function() {
+ return slice.call( this, 0 );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num == null ?
+
+ // Return a 'clean' array
+ this.toArray() :
+
+ // Return just the object
+ ( num < 0 ? this[ this.length + num ] : this[ num ] );
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems, name, selector ) {
+ // Build a new jQuery matched element set
+ var ret = this.constructor();
+
+ if ( jQuery.isArray( elems ) ) {
+ push.apply( ret, elems );
+
+ } else {
+ jQuery.merge( ret, elems );
+ }
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if ( name === "find" ) {
+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
+ } else if ( name ) {
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
+ }
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ ready: function( fn ) {
+ // Attach the listeners
+ jQuery.bindReady();
+
+ // Add the callback
+ readyList.done( fn );
+
+ return this;
+ },
+
+ eq: function( i ) {
+ return i === -1 ?
+ this.slice( i ) :
+ this.slice( i, +i + 1 );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ),
+ "slice", slice.call(arguments).join(",") );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ end: function() {
+ return this.prevObject || this.constructor(null);
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: [].sort,
+ splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[0] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+ target = {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( length === i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ ) {
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && jQuery.isArray(src) ? src : [];
+
+ } else {
+ clone = src && jQuery.isPlainObject(src) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ if ( window.$ === jQuery ) {
+ window.$ = _$;
+ }
+
+ if ( deep && window.jQuery === jQuery ) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+ },
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait: 1,
+
+ // Hold (or release) the ready event
+ holdReady: function( hold ) {
+ if ( hold ) {
+ jQuery.readyWait++;
+ } else {
+ jQuery.ready( true );
+ }
+ },
+
+ // Handle when the DOM is ready
+ ready: function( wait ) {
+ // Either a released hold or an DOMready/load event and not yet ready
+ if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( !document.body ) {
+ return setTimeout( jQuery.ready, 1 );
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If a normal DOM Ready event fired, decrement, and wait if need be
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
+ return;
+ }
+
+ // If there are functions bound, to execute
+ readyList.resolveWith( document, [ jQuery ] );
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.trigger ) {
+ jQuery( document ).trigger( "ready" ).unbind( "ready" );
+ }
+ }
+ },
+
+ bindReady: function() {
+ if ( readyList ) {
+ return;
+ }
+
+ readyList = jQuery._Deferred();
+
+ // Catch cases where $(document).ready() is called after the
+ // browser event has already occurred.
+ if ( document.readyState === "complete" ) {
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ return setTimeout( jQuery.ready, 1 );
+ }
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", jQuery.ready, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent( "onreadystatechange", DOMContentLoaded );
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", jQuery.ready );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var toplevel = false;
+
+ try {
+ toplevel = window.frameElement == null;
+ } catch(e) {}
+
+ if ( document.documentElement.doScroll && toplevel ) {
+ doScrollCheck();
+ }
+ }
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return jQuery.type(obj) === "function";
+ },
+
+ isArray: Array.isArray || function( obj ) {
+ return jQuery.type(obj) === "array";
+ },
+
+ // A crude way of determining if an object is a window
+ isWindow: function( obj ) {
+ return obj && typeof obj === "object" && "setInterval" in obj;
+ },
+
+ isNaN: function( obj ) {
+ return obj == null || !rdigit.test( obj ) || isNaN( obj );
+ },
+
+ type: function( obj ) {
+ return obj == null ?
+ String( obj ) :
+ class2type[ toString.call(obj) ] || "object";
+ },
+
+ isPlainObject: function( obj ) {
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of the constructor property.
+ // Make sure that DOM nodes and window objects don't pass through, as well
+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ try {
+ // Not own constructor property must be Object
+ if ( obj.constructor &&
+ !hasOwn.call(obj, "constructor") &&
+ !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+ return false;
+ }
+ } catch ( e ) {
+ // IE8,9 Will throw exceptions on certain host objects #9897
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own.
+
+ var key;
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwn.call( obj, key );
+ },
+
+ isEmptyObject: function( obj ) {
+ for ( var name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ error: function( msg ) {
+ throw msg;
+ },
+
+ parseJSON: function( data ) {
+ if ( typeof data !== "string" || !data ) {
+ return null;
+ }
+
+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
+ data = jQuery.trim( data );
+
+ // Attempt to parse using the native JSON parser first
+ if ( window.JSON && window.JSON.parse ) {
+ return window.JSON.parse( data );
+ }
+
+ // Make sure the incoming data is actual JSON
+ // Logic borrowed from http://json.org/json2.js
+ if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+ .replace( rvalidtokens, "]" )
+ .replace( rvalidbraces, "")) ) {
+
+ return (new Function( "return " + data ))();
+
+ }
+ jQuery.error( "Invalid JSON: " + data );
+ },
+
+ // Cross-browser xml parsing
+ parseXML: function( data ) {
+ var xml, tmp;
+ try {
+ if ( window.DOMParser ) { // Standard
+ tmp = new DOMParser();
+ xml = tmp.parseFromString( data , "text/xml" );
+ } else { // IE
+ xml = new ActiveXObject( "Microsoft.XMLDOM" );
+ xml.async = "false";
+ xml.loadXML( data );
+ }
+ } catch( e ) {
+ xml = undefined;
+ }
+ if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
+ jQuery.error( "Invalid XML: " + data );
+ }
+ return xml;
+ },
+
+ noop: function() {},
+
+ // Evaluates a script in a global context
+ // Workarounds based on findings by Jim Driscoll
+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+ globalEval: function( data ) {
+ if ( data && rnotwhite.test( data ) ) {
+ // We use execScript on Internet Explorer
+ // We use an anonymous function so that context is window
+ // rather than jQuery in Firefox
+ ( window.execScript || function( data ) {
+ window[ "eval" ].call( window, data );
+ } )( data );
+ }
+ },
+
+ // Convert dashed to camelCase; used by the css and data modules
+ // Microsoft forgot to hump their vendor prefix (#9572)
+ camelCase: function( string ) {
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ var name, i = 0,
+ length = object.length,
+ isObj = length === undefined || jQuery.isFunction( object );
+
+ if ( args ) {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.apply( object[ name ], args ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.apply( object[ i++ ], args ) === false ) {
+ break;
+ }
+ }
+ }
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
+ break;
+ }
+ }
+ }
+ }
+
+ return object;
+ },
+
+ // Use native String.trim function wherever possible
+ trim: trim ?
+ function( text ) {
+ return text == null ?
+ "" :
+ trim.call( text );
+ } :
+
+ // Otherwise use our own trimming functionality
+ function( text ) {
+ return text == null ?
+ "" :
+ text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( array, results ) {
+ var ret = results || [];
+
+ if ( array != null ) {
+ // The window, strings (and functions) also have 'length'
+ // The extra typeof function check is to prevent crashes
+ // in Safari 2 (See: #3039)
+ // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
+ var type = jQuery.type( array );
+
+ if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
+ push.call( ret, array );
+ } else {
+ jQuery.merge( ret, array );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ if ( !array ) {
+ return -1;
+ }
+
+ if ( indexOf ) {
+ return indexOf.call( array, elem );
+ }
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ if ( array[ i ] === elem ) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ var i = first.length,
+ j = 0;
+
+ if ( typeof second.length === "number" ) {
+ for ( var l = second.length; j < l; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ } else {
+ while ( second[j] !== undefined ) {
+ first[ i++ ] = second[ j++ ];
+ }
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [], retVal;
+ inv = !!inv;
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ retVal = !!callback( elems[ i ], i );
+ if ( inv !== retVal ) {
+ ret.push( elems[ i ] );
+ }
+ }
+
+ return ret;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var value, key, ret = [],
+ i = 0,
+ length = elems.length,
+ // jquery objects are treated as arrays
+ isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
+
+ // Go through the array, translating each of the items to their
+ if ( isArray ) {
+ for ( ; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+
+ // Go through every key on the object,
+ } else {
+ for ( key in elems ) {
+ value = callback( elems[ key ], key, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+ }
+
+ // Flatten any nested arrays
+ return ret.concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ // Bind a function to a context, optionally partially applying any
+ // arguments.
+ proxy: function( fn, context ) {
+ if ( typeof context === "string" ) {
+ var tmp = fn[ context ];
+ context = fn;
+ fn = tmp;
+ }
+
+ // Quick check to determine if target is callable, in the spec
+ // this throws a TypeError, but we will just return undefined.
+ if ( !jQuery.isFunction( fn ) ) {
+ return undefined;
+ }
+
+ // Simulated bind
+ var args = slice.call( arguments, 2 ),
+ proxy = function() {
+ return fn.apply( context, args.concat( slice.call( arguments ) ) );
+ };
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+
+ return proxy;
+ },
+
+ // Mutifunctional method to get and set values to a collection
+ // The value/s can optionally be executed if it's a function
+ access: function( elems, key, value, exec, fn, pass ) {
+ var length = elems.length;
+
+ // Setting many attributes
+ if ( typeof key === "object" ) {
+ for ( var k in key ) {
+ jQuery.access( elems, k, key[k], exec, fn, value );
+ }
+ return elems;
+ }
+
+ // Setting one attribute
+ if ( value !== undefined ) {
+ // Optionally, function values get executed if exec is true
+ exec = !pass && exec && jQuery.isFunction(value);
+
+ for ( var i = 0; i < length; i++ ) {
+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+ }
+
+ return elems;
+ }
+
+ // Getting an attribute
+ return length ? fn( elems[0], key ) : undefined;
+ },
+
+ now: function() {
+ return (new Date()).getTime();
+ },
+
+ // Use of jQuery.browser is frowned upon.
+ // More details: http://docs.jquery.com/Utilities/jQuery.browser
+ uaMatch: function( ua ) {
+ ua = ua.toLowerCase();
+
+ var match = rwebkit.exec( ua ) ||
+ ropera.exec( ua ) ||
+ rmsie.exec( ua ) ||
+ ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
+ [];
+
+ return { browser: match[1] || "", version: match[2] || "0" };
+ },
+
+ sub: function() {
+ function jQuerySub( selector, context ) {
+ return new jQuerySub.fn.init( selector, context );
+ }
+ jQuery.extend( true, jQuerySub, this );
+ jQuerySub.superclass = this;
+ jQuerySub.fn = jQuerySub.prototype = this();
+ jQuerySub.fn.constructor = jQuerySub;
+ jQuerySub.sub = this.sub;
+ jQuerySub.fn.init = function init( selector, context ) {
+ if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
+ context = jQuerySub( context );
+ }
+
+ return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
+ };
+ jQuerySub.fn.init.prototype = jQuerySub.fn;
+ var rootjQuerySub = jQuerySub(document);
+ return jQuerySub;
+ },
+
+ browser: {}
+});
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+ jQuery.browser[ browserMatch.browser ] = true;
+ jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+ jQuery.browser.safari = true;
+}
+
+// IE doesn't match non-breaking spaces with \s
+if ( rnotwhite.test( "\xA0" ) ) {
+ trimLeft = /^[\s\xA0]+/;
+ trimRight = /[\s\xA0]+$/;
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+ DOMContentLoaded = function() {
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+ jQuery.ready();
+ };
+
+} else if ( document.attachEvent ) {
+ DOMContentLoaded = function() {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
+ jQuery.ready();
+ }
+ };
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+ if ( jQuery.isReady ) {
+ return;
+ }
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch(e) {
+ setTimeout( doScrollCheck, 1 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+}
+
+return jQuery;
+
+})();
+
+
+var // Promise methods
+ promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
+ // Static reference to slice
+ sliceDeferred = [].slice;
+
+jQuery.extend({
+ // Create a simple deferred (one callbacks list)
+ _Deferred: function() {
+ var // callbacks list
+ callbacks = [],
+ // stored [ context , args ]
+ fired,
+ // to avoid firing when already doing so
+ firing,
+ // flag to know if the deferred has been cancelled
+ cancelled,
+ // the deferred itself
+ deferred = {
+
+ // done( f1, f2, ...)
+ done: function() {
+ if ( !cancelled ) {
+ var args = arguments,
+ i,
+ length,
+ elem,
+ type,
+ _fired;
+ if ( fired ) {
+ _fired = fired;
+ fired = 0;
+ }
+ for ( i = 0, length = args.length; i < length; i++ ) {
+ elem = args[ i ];
+ type = jQuery.type( elem );
+ if ( type === "array" ) {
+ deferred.done.apply( deferred, elem );
+ } else if ( type === "function" ) {
+ callbacks.push( elem );
+ }
+ }
+ if ( _fired ) {
+ deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
+ }
+ }
+ return this;
+ },
+
+ // resolve with given context and args
+ resolveWith: function( context, args ) {
+ if ( !cancelled && !fired && !firing ) {
+ // make sure args are available (#8421)
+ args = args || [];
+ firing = 1;
+ try {
+ while( callbacks[ 0 ] ) {
+ callbacks.shift().apply( context, args );
+ }
+ }
+ finally {
+ fired = [ context, args ];
+ firing = 0;
+ }
+ }
+ return this;
+ },
+
+ // resolve with this as context and given arguments
+ resolve: function() {
+ deferred.resolveWith( this, arguments );
+ return this;
+ },
+
+ // Has this deferred been resolved?
+ isResolved: function() {
+ return !!( firing || fired );
+ },
+
+ // Cancel
+ cancel: function() {
+ cancelled = 1;
+ callbacks = [];
+ return this;
+ }
+ };
+
+ return deferred;
+ },
+
+ // Full fledged deferred (two callbacks list)
+ Deferred: function( func ) {
+ var deferred = jQuery._Deferred(),
+ failDeferred = jQuery._Deferred(),
+ promise;
+ // Add errorDeferred methods, then and promise
+ jQuery.extend( deferred, {
+ then: function( doneCallbacks, failCallbacks ) {
+ deferred.done( doneCallbacks ).fail( failCallbacks );
+ return this;
+ },
+ always: function() {
+ return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
+ },
+ fail: failDeferred.done,
+ rejectWith: failDeferred.resolveWith,
+ reject: failDeferred.resolve,
+ isRejected: failDeferred.isResolved,
+ pipe: function( fnDone, fnFail ) {
+ return jQuery.Deferred(function( newDefer ) {
+ jQuery.each( {
+ done: [ fnDone, "resolve" ],
+ fail: [ fnFail, "reject" ]
+ }, function( handler, data ) {
+ var fn = data[ 0 ],
+ action = data[ 1 ],
+ returned;
+ if ( jQuery.isFunction( fn ) ) {
+ deferred[ handler ](function() {
+ returned = fn.apply( this, arguments );
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
+ returned.promise().then( newDefer.resolve, newDefer.reject );
+ } else {
+ newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
+ }
+ });
+ } else {
+ deferred[ handler ]( newDefer[ action ] );
+ }
+ });
+ }).promise();
+ },
+ // Get a promise for this deferred
+ // If obj is provided, the promise aspect is added to the object
+ promise: function( obj ) {
+ if ( obj == null ) {
+ if ( promise ) {
+ return promise;
+ }
+ promise = obj = {};
+ }
+ var i = promiseMethods.length;
+ while( i-- ) {
+ obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
+ }
+ return obj;
+ }
+ });
+ // Make sure only one callback list will be used
+ deferred.done( failDeferred.cancel ).fail( deferred.cancel );
+ // Unexpose cancel
+ delete deferred.cancel;
+ // Call given func if any
+ if ( func ) {
+ func.call( deferred, deferred );
+ }
+ return deferred;
+ },
+
+ // Deferred helper
+ when: function( firstParam ) {
+ var args = arguments,
+ i = 0,
+ length = args.length,
+ count = length,
+ deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
+ firstParam :
+ jQuery.Deferred();
+ function resolveFunc( i ) {
+ return function( value ) {
+ args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
+ if ( !( --count ) ) {
+ // Strange bug in FF4:
+ // Values changed onto the arguments object sometimes end up as undefined values
+ // outside the $.when method. Cloning the object into a fresh array solves the issue
+ deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
+ }
+ };
+ }
+ if ( length > 1 ) {
+ for( ; i < length; i++ ) {
+ if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
+ args[ i ].promise().then( resolveFunc(i), deferred.reject );
+ } else {
+ --count;
+ }
+ }
+ if ( !count ) {
+ deferred.resolveWith( deferred, args );
+ }
+ } else if ( deferred !== firstParam ) {
+ deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
+ }
+ return deferred.promise();
+ }
+});
+
+
+
+jQuery.support = (function() {
+
+ var div = document.createElement( "div" ),
+ documentElement = document.documentElement,
+ all,
+ a,
+ select,
+ opt,
+ input,
+ marginDiv,
+ support,
+ fragment,
+ body,
+ testElementParent,
+ testElement,
+ testElementStyle,
+ tds,
+ events,
+ eventName,
+ i,
+ isSupported;
+
+ // Preliminary tests
+ div.setAttribute("className", "t");
+ div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+
+ all = div.getElementsByTagName( "*" );
+ a = div.getElementsByTagName( "a" )[ 0 ];
+
+ // Can't get basic test support
+ if ( !all || !all.length || !a ) {
+ return {};
+ }
+
+ // First batch of supports tests
+ select = document.createElement( "select" );
+ opt = select.appendChild( document.createElement("option") );
+ input = div.getElementsByTagName( "input" )[ 0 ];
+
+ support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: ( div.firstChild.nodeType === 3 ),
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName( "tbody" ).length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName( "link" ).length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText instead)
+ style: /top/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ // Use a regex to work around a WebKit issue. See #5145
+ opacity: /^0.55$/.test( a.style.opacity ),
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Make sure that if no value is specified for a checkbox
+ // that it defaults to "on".
+ // (WebKit defaults to "" instead)
+ checkOn: ( input.value === "on" ),
+
+ // Make sure that a selected-by-default option has a working selected property.
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+ optSelected: opt.selected,
+
+ // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+ getSetAttribute: div.className !== "t",
+
+ // Will be defined later
+ submitBubbles: true,
+ changeBubbles: true,
+ focusinBubbles: false,
+ deleteExpando: true,
+ noCloneEvent: true,
+ inlineBlockNeedsLayout: false,
+ shrinkWrapBlocks: false,
+ reliableMarginRight: true
+ };
+
+ // Make sure checked status is properly cloned
+ input.checked = true;
+ support.noCloneChecked = input.cloneNode( true ).checked;
+
+ // Make sure that the options inside disabled selects aren't marked as disabled
+ // (WebKit marks them as disabled)
+ select.disabled = true;
+ support.optDisabled = !opt.disabled;
+
+ // Test to see if it's possible to delete an expando from an element
+ // Fails in Internet Explorer
+ try {
+ delete div.test;
+ } catch( e ) {
+ support.deleteExpando = false;
+ }
+
+ if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
+ div.attachEvent( "onclick", function() {
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ support.noCloneEvent = false;
+ });
+ div.cloneNode( true ).fireEvent( "onclick" );
+ }
+
+ // Check if a radio maintains it's value
+ // after being appended to the DOM
+ input = document.createElement("input");
+ input.value = "t";
+ input.setAttribute("type", "radio");
+ support.radioValue = input.value === "t";
+
+ input.setAttribute("checked", "checked");
+ div.appendChild( input );
+ fragment = document.createDocumentFragment();
+ fragment.appendChild( div.firstChild );
+
+ // WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+ div.innerHTML = "";
+
+ // Figure out if the W3C box model works as expected
+ div.style.width = div.style.paddingLeft = "1px";
+
+ body = document.getElementsByTagName( "body" )[ 0 ];
+ // We use our own, invisible, body unless the body is already present
+ // in which case we use a div (#9239)
+ testElement = document.createElement( body ? "div" : "body" );
+ testElementStyle = {
+ visibility: "hidden",
+ width: 0,
+ height: 0,
+ border: 0,
+ margin: 0,
+ background: "none"
+ };
+ if ( body ) {
+ jQuery.extend( testElementStyle, {
+ position: "absolute",
+ left: "-1000px",
+ top: "-1000px"
+ });
+ }
+ for ( i in testElementStyle ) {
+ testElement.style[ i ] = testElementStyle[ i ];
+ }
+ testElement.appendChild( div );
+ testElementParent = body || documentElement;
+ testElementParent.insertBefore( testElement, testElementParent.firstChild );
+
+ // Check if a disconnected checkbox will retain its checked
+ // value of true after appended to the DOM (IE6/7)
+ support.appendChecked = input.checked;
+
+ support.boxModel = div.offsetWidth === 2;
+
+ if ( "zoom" in div.style ) {
+ // Check if natively block-level elements act like inline-block
+ // elements when setting their display to 'inline' and giving
+ // them layout
+ // (IE < 8 does this)
+ div.style.display = "inline";
+ div.style.zoom = 1;
+ support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
+
+ // Check if elements with layout shrink-wrap their children
+ // (IE 6 does this)
+ div.style.display = "";
+ div.innerHTML = "<div style='width:4px;'></div>";
+ support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
+ }
+
+ div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
+ tds = div.getElementsByTagName( "td" );
+
+ // Check if table cells still have offsetWidth/Height when they are set
+ // to display:none and there are still other visible table cells in a
+ // table row; if so, offsetWidth/Height are not reliable for use when
+ // determining if an element has been hidden directly using
+ // display:none (it is still safe to use offsets if a parent element is
+ // hidden; don safety goggles and see bug #4512 for more information).
+ // (only IE 8 fails this test)
+ isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+ tds[ 0 ].style.display = "";
+ tds[ 1 ].style.display = "none";
+
+ // Check if empty table cells still have offsetWidth/Height
+ // (IE < 8 fail this test)
+ support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+ div.innerHTML = "";
+
+ // Check if div with explicit width and no margin-right incorrectly
+ // gets computed margin-right based on width of container. For more
+ // info see bug #3333
+ // Fails in WebKit before Feb 2011 nightlies
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ if ( document.defaultView && document.defaultView.getComputedStyle ) {
+ marginDiv = document.createElement( "div" );
+ marginDiv.style.width = "0";
+ marginDiv.style.marginRight = "0";
+ div.appendChild( marginDiv );
+ support.reliableMarginRight =
+ ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
+ }
+
+ // Remove the body element we added
+ testElement.innerHTML = "";
+ testElementParent.removeChild( testElement );
+
+ // Technique from Juriy Zaytsev
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+ // We only care about the case where non-standard event systems
+ // are used, namely in IE. Short-circuiting here helps us to
+ // avoid an eval call (in setAttribute) which can cause CSP
+ // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
+ if ( div.attachEvent ) {
+ for( i in {
+ submit: 1,
+ change: 1,
+ focusin: 1
+ } ) {
+ eventName = "on" + i;
+ isSupported = ( eventName in div );
+ if ( !isSupported ) {
+ div.setAttribute( eventName, "return;" );
+ isSupported = ( typeof div[ eventName ] === "function" );
+ }
+ support[ i + "Bubbles" ] = isSupported;
+ }
+ }
+
+ // Null connected elements to avoid leaks in IE
+ testElement = fragment = select = opt = body = marginDiv = div = input = null;
+
+ return support;
+})();
+
+// Keep track of boxModel
+jQuery.boxModel = jQuery.support.boxModel;
+
+
+
+
+var rbrace = /^(?:\{.*\}|\[.*\])$/,
+ rmultiDash = /([A-Z])/g;
+
+jQuery.extend({
+ cache: {},
+
+ // Please use with caution
+ uuid: 0,
+
+ // Unique for each copy of jQuery on the page
+ // Non-digits removed to match rinlinejQuery
+ expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
+
+ // The following elements throw uncatchable exceptions if you
+ // attempt to add expando properties to them.
+ noData: {
+ "embed": true,
+ // Ban all objects except for Flash (which handle expandos)
+ "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+ "applet": true
+ },
+
+ hasData: function( elem ) {
+ elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+
+ return !!elem && !isEmptyDataObject( elem );
+ },
+
+ data: function( elem, name, data, pvt /* Internal Use Only */ ) {
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
+
+ var thisCache, ret,
+ internalKey = jQuery.expando,
+ getByName = typeof name === "string",
+
+ // We have to handle DOM nodes and JS objects differently because IE6-7
+ // can't GC object references properly across the DOM-JS boundary
+ isNode = elem.nodeType,
+
+ // Only DOM nodes need the global jQuery cache; JS object data is
+ // attached directly to the object so GC can occur automatically
+ cache = isNode ? jQuery.cache : elem,
+
+ // Only defining an ID for JS objects if its cache already exists allows
+ // the code to shortcut on the same path as a DOM node with no cache
+ id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
+
+ // Avoid doing any more work than we need to when trying to get data on an
+ // object that has no data at all
+ if ( (!id || (pvt && id && (cache[ id ] && !cache[ id ][ internalKey ]))) && getByName && data === undefined ) {
+ return;
+ }
+
+ if ( !id ) {
+ // Only DOM nodes need a new unique ID for each element since their data
+ // ends up in the global cache
+ if ( isNode ) {
+ elem[ jQuery.expando ] = id = ++jQuery.uuid;
+ } else {
+ id = jQuery.expando;
+ }
+ }
+
+ if ( !cache[ id ] ) {
+ cache[ id ] = {};
+
+ // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+ // metadata on plain JS objects when the object is serialized using
+ // JSON.stringify
+ if ( !isNode ) {
+ cache[ id ].toJSON = jQuery.noop;
+ }
+ }
+
+ // An object can be passed to jQuery.data instead of a key/value pair; this gets
+ // shallow copied over onto the existing cache
+ if ( typeof name === "object" || typeof name === "function" ) {
+ if ( pvt ) {
+ cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
+ } else {
+ cache[ id ] = jQuery.extend(cache[ id ], name);
+ }
+ }
+
+ thisCache = cache[ id ];
+
+ // Internal jQuery data is stored in a separate object inside the object's data
+ // cache in order to avoid key collisions between internal data and user-defined
+ // data
+ if ( pvt ) {
+ if ( !thisCache[ internalKey ] ) {
+ thisCache[ internalKey ] = {};
+ }
+
+ thisCache = thisCache[ internalKey ];
+ }
+
+ if ( data !== undefined ) {
+ thisCache[ jQuery.camelCase( name ) ] = data;
+ }
+
+ // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
+ // not attempt to inspect the internal events object using jQuery.data, as this
+ // internal data object is undocumented and subject to change.
+ if ( name === "events" && !thisCache[name] ) {
+ return thisCache[ internalKey ] && thisCache[ internalKey ].events;
+ }
+
+ // Check for both converted-to-camel and non-converted data property names
+ // If a data property was specified
+ if ( getByName ) {
+
+ // First Try to find as-is property data
+ ret = thisCache[ name ];
+
+ // Test for null|undefined property data
+ if ( ret == null ) {
+
+ // Try to find the camelCased property
+ ret = thisCache[ jQuery.camelCase( name ) ];
+ }
+ } else {
+ ret = thisCache;
+ }
+
+ return ret;
+ },
+
+ removeData: function( elem, name, pvt /* Internal Use Only */ ) {
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
+
+ var thisCache,
+
+ // Reference to internal data cache key
+ internalKey = jQuery.expando,
+
+ isNode = elem.nodeType,
+
+ // See jQuery.data for more information
+ cache = isNode ? jQuery.cache : elem,
+
+ // See jQuery.data for more information
+ id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+ // If there is already no cache entry for this object, there is no
+ // purpose in continuing
+ if ( !cache[ id ] ) {
+ return;
+ }
+
+ if ( name ) {
+
+ thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
+
+ if ( thisCache ) {
+
+ // Support interoperable removal of hyphenated or camelcased keys
+ if ( !thisCache[ name ] ) {
+ name = jQuery.camelCase( name );
+ }
+
+ delete thisCache[ name ];
+
+ // If there is no data left in the cache, we want to continue
+ // and let the cache object itself get destroyed
+ if ( !isEmptyDataObject(thisCache) ) {
+ return;
+ }
+ }
+ }
+
+ // See jQuery.data for more information
+ if ( pvt ) {
+ delete cache[ id ][ internalKey ];
+
+ // Don't destroy the parent cache unless the internal data object
+ // had been the only thing left in it
+ if ( !isEmptyDataObject(cache[ id ]) ) {
+ return;
+ }
+ }
+
+ var internalCache = cache[ id ][ internalKey ];
+
+ // Browsers that fail expando deletion also refuse to delete expandos on
+ // the window, but it will allow it on all other JS objects; other browsers
+ // don't care
+ // Ensure that `cache` is not a window object #10080
+ if ( jQuery.support.deleteExpando || !cache.setInterval ) {
+ delete cache[ id ];
+ } else {
+ cache[ id ] = null;
+ }
+
+ // We destroyed the entire user cache at once because it's faster than
+ // iterating through each key, but we need to continue to persist internal
+ // data if it existed
+ if ( internalCache ) {
+ cache[ id ] = {};
+ // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+ // metadata on plain JS objects when the object is serialized using
+ // JSON.stringify
+ if ( !isNode ) {
+ cache[ id ].toJSON = jQuery.noop;
+ }
+
+ cache[ id ][ internalKey ] = internalCache;
+
+ // Otherwise, we need to eliminate the expando on the node to avoid
+ // false lookups in the cache for entries that no longer exist
+ } else if ( isNode ) {
+ // IE does not allow us to delete expando properties from nodes,
+ // nor does it have a removeAttribute function on Document nodes;
+ // we must handle all of these cases
+ if ( jQuery.support.deleteExpando ) {
+ delete elem[ jQuery.expando ];
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+ } else {
+ elem[ jQuery.expando ] = null;
+ }
+ }
+ },
+
+ // For internal use only.
+ _data: function( elem, name, data ) {
+ return jQuery.data( elem, name, data, true );
+ },
+
+ // A method for determining if a DOM node can handle the data expando
+ acceptData: function( elem ) {
+ if ( elem.nodeName ) {
+ var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+ if ( match ) {
+ return !(match === true || elem.getAttribute("classid") !== match);
+ }
+ }
+
+ return true;
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ) {
+ var data = null;
+
+ if ( typeof key === "undefined" ) {
+ if ( this.length ) {
+ data = jQuery.data( this[0] );
+
+ if ( this[0].nodeType === 1 ) {
+ var attr = this[0].attributes, name;
+ for ( var i = 0, l = attr.length; i < l; i++ ) {
+ name = attr[i].name;
+
+ if ( name.indexOf( "data-" ) === 0 ) {
+ name = jQuery.camelCase( name.substring(5) );
+
+ dataAttr( this[0], name, data[ name ] );
+ }
+ }
+ }
+ }
+
+ return data;
+
+ } else if ( typeof key === "object" ) {
+ return this.each(function() {
+ jQuery.data( this, key );
+ });
+ }
+
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ // Try to fetch any internally stored data first
+ if ( data === undefined && this.length ) {
+ data = jQuery.data( this[0], key );
+ data = dataAttr( this[0], key, data );
+ }
+
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+
+ } else {
+ return this.each(function() {
+ var $this = jQuery( this ),
+ args = [ parts[0], value ];
+
+ $this.triggerHandler( "setData" + parts[1] + "!", args );
+ jQuery.data( this, key, value );
+ $this.triggerHandler( "changeData" + parts[1] + "!", args );
+ });
+ }
+ },
+
+ removeData: function( key ) {
+ return this.each(function() {
+ jQuery.removeData( this, key );
+ });
+ }
+});
+
+function dataAttr( elem, key, data ) {
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if ( data === undefined && elem.nodeType === 1 ) {
+
+ var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+
+ data = elem.getAttribute( name );
+
+ if ( typeof data === "string" ) {
+ try {
+ data = data === "true" ? true :
+ data === "false" ? false :
+ data === "null" ? null :
+ !jQuery.isNaN( data ) ? parseFloat( data ) :
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
+ data;
+ } catch( e ) {}
+
+ // Make sure we set the data so it isn't changed later
+ jQuery.data( elem, key, data );
+
+ } else {
+ data = undefined;
+ }
+ }
+
+ return data;
+}
+
+// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
+// property to be considered empty objects; this property always exists in
+// order to make sure JSON.stringify does not expose internal metadata
+function isEmptyDataObject( obj ) {
+ for ( var name in obj ) {
+ if ( name !== "toJSON" ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+
+
+function handleQueueMarkDefer( elem, type, src ) {
+ var deferDataKey = type + "defer",
+ queueDataKey = type + "queue",
+ markDataKey = type + "mark",
+ defer = jQuery.data( elem, deferDataKey, undefined, true );
+ if ( defer &&
+ ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
+ ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
+ // Give room for hard-coded callbacks to fire first
+ // and eventually mark/queue something else on the element
+ setTimeout( function() {
+ if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
+ !jQuery.data( elem, markDataKey, undefined, true ) ) {
+ jQuery.removeData( elem, deferDataKey, true );
+ defer.resolve();
+ }
+ }, 0 );
+ }
+}
+
+jQuery.extend({
+
+ _mark: function( elem, type ) {
+ if ( elem ) {
+ type = (type || "fx") + "mark";
+ jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
+ }
+ },
+
+ _unmark: function( force, elem, type ) {
+ if ( force !== true ) {
+ type = elem;
+ elem = force;
+ force = false;
+ }
+ if ( elem ) {
+ type = type || "fx";
+ var key = type + "mark",
+ count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
+ if ( count ) {
+ jQuery.data( elem, key, count, true );
+ } else {
+ jQuery.removeData( elem, key, true );
+ handleQueueMarkDefer( elem, type, "mark" );
+ }
+ }
+ },
+
+ queue: function( elem, type, data ) {
+ if ( elem ) {
+ type = (type || "fx") + "queue";
+ var q = jQuery.data( elem, type, undefined, true );
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( data ) {
+ if ( !q || jQuery.isArray(data) ) {
+ q = jQuery.data( elem, type, jQuery.makeArray(data), true );
+ } else {
+ q.push( data );
+ }
+ }
+ return q || [];
+ }
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ),
+ fn = queue.shift(),
+ defer;
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ }
+
+ if ( fn ) {
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift("inprogress");
+ }
+
+ fn.call(elem, function() {
+ jQuery.dequeue(elem, type);
+ });
+ }
+
+ if ( !queue.length ) {
+ jQuery.removeData( elem, type + "queue", true );
+ handleQueueMarkDefer( elem, type, "queue" );
+ }
+ }
+});
+
+jQuery.fn.extend({
+ queue: function( type, data ) {
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined ) {
+ return jQuery.queue( this[0], type );
+ }
+ return this.each(function() {
+ var queue = jQuery.queue( this, type, data );
+
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ dequeue: function( type ) {
+ return this.each(function() {
+ jQuery.dequeue( this, type );
+ });
+ },
+ // Based off of the plugin by Clint Helfers, with permission.
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
+ delay: function( time, type ) {
+ time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+ type = type || "fx";
+
+ return this.queue( type, function() {
+ var elem = this;
+ setTimeout(function() {
+ jQuery.dequeue( elem, type );
+ }, time );
+ });
+ },
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ },
+ // Get a promise resolved when queues of a certain type
+ // are emptied (fx is the type by default)
+ promise: function( type, object ) {
+ if ( typeof type !== "string" ) {
+ object = type;
+ type = undefined;
+ }
+ type = type || "fx";
+ var defer = jQuery.Deferred(),
+ elements = this,
+ i = elements.length,
+ count = 1,
+ deferDataKey = type + "defer",
+ queueDataKey = type + "queue",
+ markDataKey = type + "mark",
+ tmp;
+ function resolve() {
+ if ( !( --count ) ) {
+ defer.resolveWith( elements, [ elements ] );
+ }
+ }
+ while( i-- ) {
+ if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
+ ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
+ jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
+ jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
+ count++;
+ tmp.done( resolve );
+ }
+ }
+ resolve();
+ return defer.promise();
+ }
+});
+
+
+
+
+var rclass = /[\n\t\r]/g,
+ rspace = /\s+/,
+ rreturn = /\r/g,
+ rtype = /^(?:button|input)$/i,
+ rfocusable = /^(?:button|input|object|select|textarea)$/i,
+ rclickable = /^a(?:rea)?$/i,
+ rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
+ nodeHook, boolHook;
+
+jQuery.fn.extend({
+ attr: function( name, value ) {
+ return jQuery.access( this, name, value, true, jQuery.attr );
+ },
+
+ removeAttr: function( name ) {
+ return this.each(function() {
+ jQuery.removeAttr( this, name );
+ });
+ },
+
+ prop: function( name, value ) {
+ return jQuery.access( this, name, value, true, jQuery.prop );
+ },
+
+ removeProp: function( name ) {
+ name = jQuery.propFix[ name ] || name;
+ return this.each(function() {
+ // try/catch handles cases where IE balks (such as removing a property on window)
+ try {
+ this[ name ] = undefined;
+ delete this[ name ];
+ } catch( e ) {}
+ });
+ },
+
+ addClass: function( value ) {
+ var classNames, i, l, elem,
+ setClass, c, cl;
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function( j ) {
+ jQuery( this ).addClass( value.call(this, j, this.className) );
+ });
+ }
+
+ if ( value && typeof value === "string" ) {
+ classNames = value.split( rspace );
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ elem = this[ i ];
+
+ if ( elem.nodeType === 1 ) {
+ if ( !elem.className && classNames.length === 1 ) {
+ elem.className = value;
+
+ } else {
+ setClass = " " + elem.className + " ";
+
+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {
+ if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
+ setClass += classNames[ c ] + " ";
+ }
+ }
+ elem.className = jQuery.trim( setClass );
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ removeClass: function( value ) {
+ var classNames, i, l, elem, className, c, cl;
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function( j ) {
+ jQuery( this ).removeClass( value.call(this, j, this.className) );
+ });
+ }
+
+ if ( (value && typeof value === "string") || value === undefined ) {
+ classNames = (value || "").split( rspace );
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ elem = this[ i ];
+
+ if ( elem.nodeType === 1 && elem.className ) {
+ if ( value ) {
+ className = (" " + elem.className + " ").replace( rclass, " " );
+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {
+ className = className.replace(" " + classNames[ c ] + " ", " ");
+ }
+ elem.className = jQuery.trim( className );
+
+ } else {
+ elem.className = "";
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ toggleClass: function( value, stateVal ) {
+ var type = typeof value,
+ isBool = typeof stateVal === "boolean";
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function( i ) {
+ jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
+ });
+ }
+
+ return this.each(function() {
+ if ( type === "string" ) {
+ // toggle individual class names
+ var className,
+ i = 0,
+ self = jQuery( this ),
+ state = stateVal,
+ classNames = value.split( rspace );
+
+ while ( (className = classNames[ i++ ]) ) {
+ // check each className given, space seperated list
+ state = isBool ? state : !self.hasClass( className );
+ self[ state ? "addClass" : "removeClass" ]( className );
+ }
+
+ } else if ( type === "undefined" || type === "boolean" ) {
+ if ( this.className ) {
+ // store className if set
+ jQuery._data( this, "__className__", this.className );
+ }
+
+ // toggle whole className
+ this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
+ }
+ });
+ },
+
+ hasClass: function( selector ) {
+ var className = " " + selector + " ";
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ val: function( value ) {
+ var hooks, ret,
+ elem = this[0];
+
+ if ( !arguments.length ) {
+ if ( elem ) {
+ hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
+
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+ return ret;
+ }
+
+ ret = elem.value;
+
+ return typeof ret === "string" ?
+ // handle most common string cases
+ ret.replace(rreturn, "") :
+ // handle cases where value is null/undef or number
+ ret == null ? "" : ret;
+ }
+
+ return undefined;
+ }
+
+ var isFunction = jQuery.isFunction( value );
+
+ return this.each(function( i ) {
+ var self = jQuery(this), val;
+
+ if ( this.nodeType !== 1 ) {
+ return;
+ }
+
+ if ( isFunction ) {
+ val = value.call( this, i, self.val() );
+ } else {
+ val = value;
+ }
+
+ // Treat null/undefined as ""; convert numbers to string
+ if ( val == null ) {
+ val = "";
+ } else if ( typeof val === "number" ) {
+ val += "";
+ } else if ( jQuery.isArray( val ) ) {
+ val = jQuery.map(val, function ( value ) {
+ return value == null ? "" : value + "";
+ });
+ }
+
+ hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
+
+ // If set returns undefined, fall back to normal setting
+ if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+ this.value = val;
+ }
+ });
+ }
+});
+
+jQuery.extend({
+ valHooks: {
+ option: {
+ get: function( elem ) {
+ // attributes.value is undefined in Blackberry 4.7 but
+ // uses .value. See #6932
+ var val = elem.attributes.value;
+ return !val || val.specified ? elem.value : elem.text;
+ }
+ },
+ select: {
+ get: function( elem ) {
+ var value,
+ index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type === "select-one";
+
+ // Nothing was selected
+ if ( index < 0 ) {
+ return null;
+ }
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ // Don't return options that are disabled or in a disabled optgroup
+ if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
+ (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
+
+ // Get the specific value for the option
+ value = jQuery( option ).val();
+
+ // We don't need an array for one selects
+ if ( one ) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
+ if ( one && !values.length && options.length ) {
+ return jQuery( options[ index ] ).val();
+ }
+
+ return values;
+ },
+
+ set: function( elem, value ) {
+ var values = jQuery.makeArray( value );
+
+ jQuery(elem).find("option").each(function() {
+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+ });
+
+ if ( !values.length ) {
+ elem.selectedIndex = -1;
+ }
+ return values;
+ }
+ }
+ },
+
+ attrFn: {
+ val: true,
+ css: true,
+ html: true,
+ text: true,
+ data: true,
+ width: true,
+ height: true,
+ offset: true
+ },
+
+ attrFix: {
+ // Always normalize to ensure hook usage
+ tabindex: "tabIndex"
+ },
+
+ attr: function( elem, name, value, pass ) {
+ var nType = elem.nodeType;
+
+ // don't get/set attributes on text, comment and attribute nodes
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+ return undefined;
+ }
+
+ if ( pass && name in jQuery.attrFn ) {
+ return jQuery( elem )[ name ]( value );
+ }
+
+ // Fallback to prop when attributes are not supported
+ if ( !("getAttribute" in elem) ) {
+ return jQuery.prop( elem, name, value );
+ }
+
+ var ret, hooks,
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+ // Normalize the name if needed
+ if ( notxml ) {
+ name = jQuery.attrFix[ name ] || name;
+
+ hooks = jQuery.attrHooks[ name ];
+
+ if ( !hooks ) {
+ // Use boolHook for boolean attributes
+ if ( rboolean.test( name ) ) {
+ hooks = boolHook;
+
+ // Use nodeHook if available( IE6/7 )
+ } else if ( nodeHook ) {
+ hooks = nodeHook;
+ }
+ }
+ }
+
+ if ( value !== undefined ) {
+
+ if ( value === null ) {
+ jQuery.removeAttr( elem, name );
+ return undefined;
+
+ } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
+ return ret;
+
+ } else {
+ elem.setAttribute( name, "" + value );
+ return value;
+ }
+
+ } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
+ return ret;
+
+ } else {
+
+ ret = elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return ret === null ?
+ undefined :
+ ret;
+ }
+ },
+
+ removeAttr: function( elem, name ) {
+ var propName;
+ if ( elem.nodeType === 1 ) {
+ name = jQuery.attrFix[ name ] || name;
+
+ jQuery.attr( elem, name, "" );
+ elem.removeAttribute( name );
+
+ // Set corresponding property to false for boolean attributes
+ if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
+ elem[ propName ] = false;
+ }
+ }
+ },
+
+ attrHooks: {
+ type: {
+ set: function( elem, value ) {
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
+ jQuery.error( "type property can't be changed" );
+ } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+ // Setting the type on a radio button after the value resets the value in IE6-9
+ // Reset value to it's default in case type is set after value
+ // This is for element creation
+ var val = elem.value;
+ elem.setAttribute( "type", value );
+ if ( val ) {
+ elem.value = val;
+ }
+ return value;
+ }
+ }
+ },
+ // Use the value property for back compat
+ // Use the nodeHook for button elements in IE6/7 (#1954)
+ value: {
+ get: function( elem, name ) {
+ if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
+ return nodeHook.get( elem, name );
+ }
+ return name in elem ?
+ elem.value :
+ null;
+ },
+ set: function( elem, value, name ) {
+ if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
+ return nodeHook.set( elem, value, name );
+ }
+ // Does not return so that setAttribute is also used
+ elem.value = value;
+ }
+ }
+ },
+
+ propFix: {
+ tabindex: "tabIndex",
+ readonly: "readOnly",
+ "for": "htmlFor",
+ "class": "className",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ cellpadding: "cellPadding",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ usemap: "useMap",
+ frameborder: "frameBorder",
+ contenteditable: "contentEditable"
+ },
+
+ prop: function( elem, name, value ) {
+ var nType = elem.nodeType;
+
+ // don't get/set properties on text, comment and attribute nodes
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+ return undefined;
+ }
+
+ var ret, hooks,
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+ if ( notxml ) {
+ // Fix name and attach hooks
+ name = jQuery.propFix[ name ] || name;
+ hooks = jQuery.propHooks[ name ];
+ }
+
+ if ( value !== undefined ) {
+ if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+ return ret;
+
+ } else {
+ return (elem[ name ] = value);
+ }
+
+ } else {
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+ return ret;
+
+ } else {
+ return elem[ name ];
+ }
+ }
+ },
+
+ propHooks: {
+ tabIndex: {
+ get: function( elem ) {
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ var attributeNode = elem.getAttributeNode("tabindex");
+
+ return attributeNode && attributeNode.specified ?
+ parseInt( attributeNode.value, 10 ) :
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+ 0 :
+ undefined;
+ }
+ }
+ }
+});
+
+// Add the tabindex propHook to attrHooks for back-compat
+jQuery.attrHooks.tabIndex = jQuery.propHooks.tabIndex;
+
+// Hook for boolean attributes
+boolHook = {
+ get: function( elem, name ) {
+ // Align boolean attributes with corresponding properties
+ // Fall back to attribute presence where some booleans are not supported
+ var attrNode;
+ return jQuery.prop( elem, name ) === true || ( attrNode = elem.getAttributeNode( name ) ) && attrNode.nodeValue !== false ?
+ name.toLowerCase() :
+ undefined;
+ },
+ set: function( elem, value, name ) {
+ var propName;
+ if ( value === false ) {
+ // Remove boolean attributes when set to false
+ jQuery.removeAttr( elem, name );
+ } else {
+ // value is true since we know at this point it's type boolean and not false
+ // Set boolean attributes to the same name and set the DOM property
+ propName = jQuery.propFix[ name ] || name;
+ if ( propName in elem ) {
+ // Only set the IDL specifically if it already exists on the element
+ elem[ propName ] = true;
+ }
+
+ elem.setAttribute( name, name.toLowerCase() );
+ }
+ return name;
+ }
+};
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !jQuery.support.getSetAttribute ) {
+
+ // Use this for any attribute in IE6/7
+ // This fixes almost every IE6/7 issue
+ nodeHook = jQuery.valHooks.button = {
+ get: function( elem, name ) {
+ var ret;
+ ret = elem.getAttributeNode( name );
+ // Return undefined if nodeValue is empty string
+ return ret && ret.nodeValue !== "" ?
+ ret.nodeValue :
+ undefined;
+ },
+ set: function( elem, value, name ) {
+ // Set the existing or create a new attribute node
+ var ret = elem.getAttributeNode( name );
+ if ( !ret ) {
+ ret = document.createAttribute( name );
+ elem.setAttributeNode( ret );
+ }
+ return (ret.nodeValue = value + "");
+ }
+ };
+
+ // Set width and height to auto instead of 0 on empty string( Bug #8150 )
+ // This is for removals
+ jQuery.each([ "width", "height" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ set: function( elem, value ) {
+ if ( value === "" ) {
+ elem.setAttribute( name, "auto" );
+ return value;
+ }
+ }
+ });
+ });
+}
+
+
+// Some attributes require a special call on IE
+if ( !jQuery.support.hrefNormalized ) {
+ jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ get: function( elem ) {
+ var ret = elem.getAttribute( name, 2 );
+ return ret === null ? undefined : ret;
+ }
+ });
+ });
+}
+
+if ( !jQuery.support.style ) {
+ jQuery.attrHooks.style = {
+ get: function( elem ) {
+ // Return undefined in the case of empty string
+ // Normalize to lowercase since IE uppercases css property names
+ return elem.style.cssText.toLowerCase() || undefined;
+ },
+ set: function( elem, value ) {
+ return (elem.style.cssText = "" + value);
+ }
+ };
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+ jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
+ get: function( elem ) {
+ var parent = elem.parentNode;
+
+ if ( parent ) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ return null;
+ }
+ });
+}
+
+// Radios and checkboxes getter/setter
+if ( !jQuery.support.checkOn ) {
+ jQuery.each([ "radio", "checkbox" ], function() {
+ jQuery.valHooks[ this ] = {
+ get: function( elem ) {
+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+ return elem.getAttribute("value") === null ? "on" : elem.value;
+ }
+ };
+ });
+}
+jQuery.each([ "radio", "checkbox" ], function() {
+ jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
+ set: function( elem, value ) {
+ if ( jQuery.isArray( value ) ) {
+ return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
+ }
+ }
+ });
+});
+
+
+
+
+var rnamespaces = /\.(.*)$/,
+ rformElems = /^(?:textarea|input|select)$/i,
+ rperiod = /\./g,
+ rspaces = / /g,
+ rescape = /[^\w\s.|`]/g,
+ fcleanup = function( nm ) {
+ return nm.replace(rescape, "\\$&");
+ };
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function( elem, types, handler, data ) {
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ if ( handler === false ) {
+ handler = returnFalse;
+ } else if ( !handler ) {
+ // Fixes bug #7229. Fix recommended by jdalton
+ return;
+ }
+
+ var handleObjIn, handleObj;
+
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ }
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure
+ var elemData = jQuery._data( elem );
+
+ // If no elemData is found then we must be trying to bind to one of the
+ // banned noData elements
+ if ( !elemData ) {
+ return;
+ }
+
+ var events = elemData.events,
+ eventHandle = elemData.handle;
+
+ if ( !events ) {
+ elemData.events = events = {};
+ }
+
+ if ( !eventHandle ) {
+ elemData.handle = eventHandle = function( e ) {
+ // Discard the second event of a jQuery.event.trigger() and
+ // when an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
+ jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+ undefined;
+ };
+ }
+
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native events in IE.
+ eventHandle.elem = elem;
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ var type, i = 0, namespaces;
+
+ while ( (type = types[ i++ ]) ) {
+ handleObj = handleObjIn ?
+ jQuery.extend({}, handleObjIn) :
+ { handler: handler, data: data };
+
+ // Namespaced event handlers
+ if ( type.indexOf(".") > -1 ) {
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+ } else {
+ namespaces = [];
+ handleObj.namespace = "";
+ }
+
+ handleObj.type = type;
+ if ( !handleObj.guid ) {
+ handleObj.guid = handler.guid;
+ }
+
+ // Get the current list of functions bound to this event
+ var handlers = events[ type ],
+ special = jQuery.event.special[ type ] || {};
+
+ // Init the event handler queue
+ if ( !handlers ) {
+ handlers = events[ type ] = [];
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ // Bind the global event handler to the element
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle, false );
+
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, eventHandle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers.push( handleObj );
+
+ // Keep track of which events have been used, for event optimization
+ jQuery.event.global[ type ] = true;
+ }
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, pos ) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ if ( handler === false ) {
+ handler = returnFalse;
+ }
+
+ var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+ elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
+ events = elemData && elemData.events;
+
+ if ( !elemData || !events ) {
+ return;
+ }
+
+ // types is actually an event object here
+ if ( types && types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Unbind all events for the element
+ if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+ types = types || "";
+
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types );
+ }
+
+ return;
+ }
+
+ // Handle multiple events separated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ while ( (type = types[ i++ ]) ) {
+ origType = type;
+ handleObj = null;
+ all = type.indexOf(".") < 0;
+ namespaces = [];
+
+ if ( !all ) {
+ // Namespaced event handlers
+ namespaces = type.split(".");
+ type = namespaces.shift();
+
+ namespace = new RegExp("(^|\\.)" +
+ jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
+ }
+
+ eventType = events[ type ];
+
+ if ( !eventType ) {
+ continue;
+ }
+
+ if ( !handler ) {
+ for ( j = 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ jQuery.event.remove( elem, origType, handleObj.handler, j );
+ eventType.splice( j--, 1 );
+ }
+ }
+
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+
+ for ( j = pos || 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( handler.guid === handleObj.guid ) {
+ // remove the given handler for the given type
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ if ( pos == null ) {
+ eventType.splice( j--, 1 );
+ }
+
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+
+ if ( pos != null ) {
+ break;
+ }
+ }
+ }
+
+ // remove generic event handler if no more handlers exist
+ if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+ jQuery.removeEvent( elem, type, elemData.handle );
+ }
+
+ ret = null;
+ delete events[ type ];
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ var handle = elemData.handle;
+ if ( handle ) {
+ handle.elem = null;
+ }
+
+ delete elemData.events;
+ delete elemData.handle;
+
+ if ( jQuery.isEmptyObject( elemData ) ) {
+ jQuery.removeData( elem, undefined, true );
+ }
+ }
+ },
+
+ // Events that are safe to short-circuit if no handlers are attached.
+ // Native DOM events should not be added, they may have inline handlers.
+ customEvent: {
+ "getData": true,
+ "setData": true,
+ "changeData": true
+ },
+
+ trigger: function( event, data, elem, onlyHandlers ) {
+ // Event object or event type
+ var type = event.type || event,
+ namespaces = [],
+ exclusive;
+
+ if ( type.indexOf("!") >= 0 ) {
+ // Exclusive events trigger only for the exact event (no namespaces)
+ type = type.slice(0, -1);
+ exclusive = true;
+ }
+
+ if ( type.indexOf(".") >= 0 ) {
+ // Namespaced trigger; create a regexp to match event type in handle()
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ namespaces.sort();
+ }
+
+ if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
+ // No jQuery handlers for this event type, and it can't have inline handlers
+ return;
+ }
+
+ // Caller can pass in an Event, Object, or just an event type string
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[ jQuery.expando ] ? event :
+ // Object literal
+ new jQuery.Event( type, event ) :
+ // Just the event type (string)
+ new jQuery.Event( type );
+
+ event.type = type;
+ event.exclusive = exclusive;
+ event.namespace = namespaces.join(".");
+ event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
+
+ // triggerHandler() and global events don't bubble or run the default action
+ if ( onlyHandlers || !elem ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // TODO: Stop taunting the data cache; remove global events and always attach to document
+ jQuery.each( jQuery.cache, function() {
+ // internalKey variable is just used to make it easier to find
+ // and potentially change this stuff later; currently it just
+ // points to jQuery.expando
+ var internalKey = jQuery.expando,
+ internalCache = this[ internalKey ];
+ if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
+ jQuery.event.trigger( event, data, internalCache.handle.elem );
+ }
+ });
+ return;
+ }
+
+ // Don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ // Clean up the event in case it is being reused
+ event.result = undefined;
+ event.target = elem;
+
+ // Clone any incoming data and prepend the event, creating the handler arg list
+ data = data != null ? jQuery.makeArray( data ) : [];
+ data.unshift( event );
+
+ var cur = elem,
+ // IE doesn't like method names with a colon (#3533, #8272)
+ ontype = type.indexOf(":") < 0 ? "on" + type : "";
+
+ // Fire event on the current element, then bubble up the DOM tree
+ do {
+ var handle = jQuery._data( cur, "handle" );
+
+ event.currentTarget = cur;
+ if ( handle ) {
+ handle.apply( cur, data );
+ }
+
+ // Trigger an inline bound script
+ if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
+ event.result = false;
+ event.preventDefault();
+ }
+
+ // Bubble up to document, then to window
+ cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
+ } while ( cur && !event.isPropagationStopped() );
+
+ // If nobody prevented the default action, do it now
+ if ( !event.isDefaultPrevented() ) {
+ var old,
+ special = jQuery.event.special[ type ] || {};
+
+ if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
+ !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
+
+ // Call a native DOM method on the target with the same name name as the event.
+ // Can't use an .isFunction)() check here because IE6/7 fails that test.
+ // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
+ try {
+ if ( ontype && elem[ type ] ) {
+ // Don't re-trigger an onFOO event when we call its FOO() method
+ old = elem[ ontype ];
+
+ if ( old ) {
+ elem[ ontype ] = null;
+ }
+
+ jQuery.event.triggered = type;
+ elem[ type ]();
+ }
+ } catch ( ieError ) {}
+
+ if ( old ) {
+ elem[ ontype ] = old;
+ }
+
+ jQuery.event.triggered = undefined;
+ }
+ }
+
+ return event.result;
+ },
+
+ handle: function( event ) {
+ event = jQuery.event.fix( event || window.event );
+ // Snapshot the handlers list since a called handler may add/remove events.
+ var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
+ run_all = !event.exclusive && !event.namespace,
+ args = Array.prototype.slice.call( arguments, 0 );
+
+ // Use the fix-ed Event rather than the (read-only) native event
+ args[0] = event;
+ event.currentTarget = this;
+
+ for ( var j = 0, l = handlers.length; j < l; j++ ) {
+ var handleObj = handlers[ j ];
+
+ // Triggered event must 1) be non-exclusive and have no namespace, or
+ // 2) have namespace(s) a subset or equal to those in the bound event.
+ if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ event.handler = handleObj.handler;
+ event.data = handleObj.data;
+ event.handleObj = handleObj;
+
+ var ret = handleObj.handler.apply( this, args );
+
+ if ( ret !== undefined ) {
+ event.result = ret;
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ if ( event.isImmediatePropagationStopped() ) {
+ break;
+ }
+ }
+ }
+ return event.result;
+ },
+
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+ fix: function( event ) {
+ if ( event[ jQuery.expando ] ) {
+ return event;
+ }
+
+ // store a copy of the original event object
+ // and "clone" to set read-only properties
+ var originalEvent = event;
+ event = jQuery.Event( originalEvent );
+
+ for ( var i = this.props.length, prop; i; ) {
+ prop = this.props[ --i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Fix target property, if necessary
+ if ( !event.target ) {
+ // Fixes #1925 where srcElement might not be defined either
+ event.target = event.srcElement || document;
+ }
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType === 3 ) {
+ event.target = event.target.parentNode;
+ }
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement ) {
+ event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+ }
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var eventDocument = event.target.ownerDocument || document,
+ doc = eventDocument.documentElement,
+ body = eventDocument.body;
+
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
+ event.which = event.charCode != null ? event.charCode : event.keyCode;
+ }
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey ) {
+ event.metaKey = event.ctrlKey;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button !== undefined ) {
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+ }
+
+ return event;
+ },
+
+ // Deprecated, use jQuery.guid instead
+ guid: 1E8,
+
+ // Deprecated, use jQuery.proxy instead
+ proxy: jQuery.proxy,
+
+ special: {
+ ready: {
+ // Make sure the ready event is setup
+ setup: jQuery.bindReady,
+ teardown: jQuery.noop
+ },
+
+ live: {
+ add: function( handleObj ) {
+ jQuery.event.add( this,
+ liveConvert( handleObj.origType, handleObj.selector ),
+ jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
+ },
+
+ remove: function( handleObj ) {
+ jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
+ }
+ },
+
+ beforeunload: {
+ setup: function( data, namespaces, eventHandle ) {
+ // We only want to do this special case on windows
+ if ( jQuery.isWindow( this ) ) {
+ this.onbeforeunload = eventHandle;
+ }
+ },
+
+ teardown: function( namespaces, eventHandle ) {
+ if ( this.onbeforeunload === eventHandle ) {
+ this.onbeforeunload = null;
+ }
+ }
+ }
+ }
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+ function( elem, type, handle ) {
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, handle, false );
+ }
+ } :
+ function( elem, type, handle ) {
+ if ( elem.detachEvent ) {
+ elem.detachEvent( "on" + type, handle );
+ }
+ };
+
+jQuery.Event = function( src, props ) {
+ // Allow instantiation without the 'new' keyword
+ if ( !this.preventDefault ) {
+ return new jQuery.Event( src, props );
+ }
+
+ // Event object
+ if ( src && src.type ) {
+ this.originalEvent = src;
+ this.type = src.type;
+
+ // Events bubbling up the document may have been marked as prevented
+ // by a handler lower down the tree; reflect the correct value.
+ this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
+ src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
+
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // Put explicitly provided properties onto the event object
+ if ( props ) {
+ jQuery.extend( this, props );
+ }
+
+ // timeStamp is buggy for some events on Firefox(#3843)
+ // So we won't rely on the native value
+ this.timeStamp = jQuery.now();
+
+ // Mark it as fixed
+ this[ jQuery.expando ] = true;
+};
+
+function returnFalse() {
+ return false;
+}
+function returnTrue() {
+ return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+
+ // if preventDefault exists run it on the original event
+ if ( e.preventDefault ) {
+ e.preventDefault();
+
+ // otherwise set the returnValue property of the original event to false (IE)
+ } else {
+ e.returnValue = false;
+ }
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+ // if stopPropagation exists run it on the original event
+ if ( e.stopPropagation ) {
+ e.stopPropagation();
+ }
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation: function() {
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+
+ // Check if mouse(over|out) are still within the same parent element
+ var related = event.relatedTarget,
+ inside = false,
+ eventType = event.type;
+
+ event.type = event.data;
+
+ if ( related !== this ) {
+
+ if ( related ) {
+ inside = jQuery.contains( this, related );
+ }
+
+ if ( !inside ) {
+
+ jQuery.event.handle.apply( this, arguments );
+
+ event.type = eventType;
+ }
+ }
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+ event.type = event.data;
+ jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+}, function( orig, fix ) {
+ jQuery.event.special[ orig ] = {
+ setup: function( data ) {
+ jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
+ },
+ teardown: function( data ) {
+ jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
+ }
+ };
+});
+
+// submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+ jQuery.event.special.submit = {
+ setup: function( data, namespaces ) {
+ if ( !jQuery.nodeName( this, "form" ) ) {
+ jQuery.event.add(this, "click.specialSubmit", function( e ) {
+ // Avoid triggering error on non-existent type attribute in IE VML (#7071)
+ var elem = e.target,
+ type = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.type : "";
+
+ if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+ trigger( "submit", this, arguments );
+ }
+ });
+
+ jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
+ var elem = e.target,
+ type = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.type : "";
+
+ if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+ trigger( "submit", this, arguments );
+ }
+ });
+
+ } else {
+ return false;
+ }
+ },
+
+ teardown: function( namespaces ) {
+ jQuery.event.remove( this, ".specialSubmit" );
+ }
+ };
+
+}
+
+// change delegation, happens here so we have bind.
+if ( !jQuery.support.changeBubbles ) {
+
+ var changeFilters,
+
+ getVal = function( elem ) {
+ var type = jQuery.nodeName( elem, "input" ) ? elem.type : "",
+ val = elem.value;
+
+ if ( type === "radio" || type === "checkbox" ) {
+ val = elem.checked;
+
+ } else if ( type === "select-multiple" ) {
+ val = elem.selectedIndex > -1 ?
+ jQuery.map( elem.options, function( elem ) {
+ return elem.selected;
+ }).join("-") :
+ "";
+
+ } else if ( jQuery.nodeName( elem, "select" ) ) {
+ val = elem.selectedIndex;
+ }
+
+ return val;
+ },
+
+ testChange = function testChange( e ) {
+ var elem = e.target, data, val;
+
+ if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
+ return;
+ }
+
+ data = jQuery._data( elem, "_change_data" );
+ val = getVal(elem);
+
+ // the current data will be also retrieved by beforeactivate
+ if ( e.type !== "focusout" || elem.type !== "radio" ) {
+ jQuery._data( elem, "_change_data", val );
+ }
+
+ if ( data === undefined || val === data ) {
+ return;
+ }
+
+ if ( data != null || val ) {
+ e.type = "change";
+ e.liveFired = undefined;
+ jQuery.event.trigger( e, arguments[1], elem );
+ }
+ };
+
+ jQuery.event.special.change = {
+ filters: {
+ focusout: testChange,
+
+ beforedeactivate: testChange,
+
+ click: function( e ) {
+ var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
+
+ if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
+ testChange.call( this, e );
+ }
+ },
+
+ // Change has to be called before submit
+ // Keydown will be called before keypress, which is used in submit-event delegation
+ keydown: function( e ) {
+ var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
+
+ if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
+ (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
+ type === "select-multiple" ) {
+ testChange.call( this, e );
+ }
+ },
+
+ // Beforeactivate happens also before the previous element is blurred
+ // with this event you can't trigger a change event, but you can store
+ // information
+ beforeactivate: function( e ) {
+ var elem = e.target;
+ jQuery._data( elem, "_change_data", getVal(elem) );
+ }
+ },
+
+ setup: function( data, namespaces ) {
+ if ( this.type === "file" ) {
+ return false;
+ }
+
+ for ( var type in changeFilters ) {
+ jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
+ }
+
+ return rformElems.test( this.nodeName );
+ },
+
+ teardown: function( namespaces ) {
+ jQuery.event.remove( this, ".specialChange" );
+
+ return rformElems.test( this.nodeName );
+ }
+ };
+
+ changeFilters = jQuery.event.special.change.filters;
+
+ // Handle when the input is .focus()'d
+ changeFilters.focus = changeFilters.beforeactivate;
+}
+
+function trigger( type, elem, args ) {
+ // Piggyback on a donor event to simulate a different one.
+ // Fake originalEvent to avoid donor's stopPropagation, but if the
+ // simulated event prevents default then we do the same on the donor.
+ // Don't pass args or remember liveFired; they apply to the donor event.
+ var event = jQuery.extend( {}, args[ 0 ] );
+ event.type = type;
+ event.originalEvent = {};
+ event.liveFired = undefined;
+ jQuery.event.handle.call( elem, event );
+ if ( event.isDefaultPrevented() ) {
+ args[ 0 ].preventDefault();
+ }
+}
+
+// Create "bubbling" focus and blur events
+if ( !jQuery.support.focusinBubbles ) {
+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+ // Attach a single capturing handler while someone wants focusin/focusout
+ var attaches = 0;
+
+ jQuery.event.special[ fix ] = {
+ setup: function() {
+ if ( attaches++ === 0 ) {
+ document.addEventListener( orig, handler, true );
+ }
+ },
+ teardown: function() {
+ if ( --attaches === 0 ) {
+ document.removeEventListener( orig, handler, true );
+ }
+ }
+ };
+
+ function handler( donor ) {
+ // Donor event is always a native one; fix it and switch its type.
+ // Let focusin/out handler cancel the donor focus/blur event.
+ var e = jQuery.event.fix( donor );
+ e.type = fix;
+ e.originalEvent = {};
+ jQuery.event.trigger( e, null, e.target );
+ if ( e.isDefaultPrevented() ) {
+ donor.preventDefault();
+ }
+ }
+ });
+}
+
+jQuery.each(["bind", "one"], function( i, name ) {
+ jQuery.fn[ name ] = function( type, data, fn ) {
+ var handler;
+
+ // Handle object literals
+ if ( typeof type === "object" ) {
+ for ( var key in type ) {
+ this[ name ](key, data, type[key], fn);
+ }
+ return this;
+ }
+
+ if ( arguments.length === 2 || data === false ) {
+ fn = data;
+ data = undefined;
+ }
+
+ if ( name === "one" ) {
+ handler = function( event ) {
+ jQuery( this ).unbind( event, handler );
+ return fn.apply( this, arguments );
+ };
+ handler.guid = fn.guid || jQuery.guid++;
+ } else {
+ handler = fn;
+ }
+
+ if ( type === "unload" && name !== "one" ) {
+ this.one( type, data, fn );
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ jQuery.event.add( this[i], type, handler, data );
+ }
+ }
+
+ return this;
+ };
+});
+
+jQuery.fn.extend({
+ unbind: function( type, fn ) {
+ // Handle object literals
+ if ( typeof type === "object" && !type.preventDefault ) {
+ for ( var key in type ) {
+ this.unbind(key, type[key]);
+ }
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ jQuery.event.remove( this[i], type, fn );
+ }
+ }
+
+ return this;
+ },
+
+ delegate: function( selector, types, data, fn ) {
+ return this.live( types, data, fn, selector );
+ },
+
+ undelegate: function( selector, types, fn ) {
+ if ( arguments.length === 0 ) {
+ return this.unbind( "live" );
+
+ } else {
+ return this.die( types, null, fn, selector );
+ }
+ },
+
+ trigger: function( type, data ) {
+ return this.each(function() {
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+
+ triggerHandler: function( type, data ) {
+ if ( this[0] ) {
+ return jQuery.event.trigger( type, data, this[0], true );
+ }
+ },
+
+ toggle: function( fn ) {
+ // Save reference to arguments for access in closure
+ var args = arguments,
+ guid = fn.guid || jQuery.guid++,
+ i = 0,
+ toggler = function( event ) {
+ // Figure out which function to execute
+ var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+ jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ lastToggle ].apply( this, arguments ) || false;
+ };
+
+ // link all the functions, so any of them can unbind this click handler
+ toggler.guid = guid;
+ while ( i < args.length ) {
+ args[ i++ ].guid = guid;
+ }
+
+ return this.click( toggler );
+ },
+
+ hover: function( fnOver, fnOut ) {
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+ }
+});
+
+var liveMap = {
+ focus: "focusin",
+ blur: "focusout",
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+};
+
+jQuery.each(["live", "die"], function( i, name ) {
+ jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
+ var type, i = 0, match, namespaces, preType,
+ selector = origSelector || this.selector,
+ context = origSelector ? this : jQuery( this.context );
+
+ if ( typeof types === "object" && !types.preventDefault ) {
+ for ( var key in types ) {
+ context[ name ]( key, data, types[key], selector );
+ }
+
+ return this;
+ }
+
+ if ( name === "die" && !types &&
+ origSelector && origSelector.charAt(0) === "." ) {
+
+ context.unbind( origSelector );
+
+ return this;
+ }
+
+ if ( data === false || jQuery.isFunction( data ) ) {
+ fn = data || returnFalse;
+ data = undefined;
+ }
+
+ types = (types || "").split(" ");
+
+ while ( (type = types[ i++ ]) != null ) {
+ match = rnamespaces.exec( type );
+ namespaces = "";
+
+ if ( match ) {
+ namespaces = match[0];
+ type = type.replace( rnamespaces, "" );
+ }
+
+ if ( type === "hover" ) {
+ types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
+ continue;
+ }
+
+ preType = type;
+
+ if ( liveMap[ type ] ) {
+ types.push( liveMap[ type ] + namespaces );
+ type = type + namespaces;
+
+ } else {
+ type = (liveMap[ type ] || type) + namespaces;
+ }
+
+ if ( name === "live" ) {
+ // bind live handler
+ for ( var j = 0, l = context.length; j < l; j++ ) {
+ jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
+ { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
+ }
+
+ } else {
+ // unbind live handler
+ context.unbind( "live." + liveConvert( type, selector ), fn );
+ }
+ }
+
+ return this;
+ };
+});
+
+function liveHandler( event ) {
+ var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
+ elems = [],
+ selectors = [],
+ events = jQuery._data( this, "events" );
+
+ // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
+ if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
+ return;
+ }
+
+ if ( event.namespace ) {
+ namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
+ }
+
+ event.liveFired = this;
+
+ var live = events.live.slice(0);
+
+ for ( j = 0; j < live.length; j++ ) {
+ handleObj = live[j];
+
+ if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
+ selectors.push( handleObj.selector );
+
+ } else {
+ live.splice( j--, 1 );
+ }
+ }
+
+ match = jQuery( event.target ).closest( selectors, event.currentTarget );
+
+ for ( i = 0, l = match.length; i < l; i++ ) {
+ close = match[i];
+
+ for ( j = 0; j < live.length; j++ ) {
+ handleObj = live[j];
+
+ if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
+ elem = close.elem;
+ related = null;
+
+ // Those two events require additional checking
+ if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
+ event.type = handleObj.preType;
+ related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
+
+ // Make sure not to accidentally match a child element with the same selector
+ if ( related && jQuery.contains( elem, related ) ) {
+ related = elem;
+ }
+ }
+
+ if ( !related || related !== elem ) {
+ elems.push({ elem: elem, handleObj: handleObj, level: close.level });
+ }
+ }
+ }
+ }
+
+ for ( i = 0, l = elems.length; i < l; i++ ) {
+ match = elems[i];
+
+ if ( maxLevel && match.level > maxLevel ) {
+ break;
+ }
+
+ event.currentTarget = match.elem;
+ event.data = match.handleObj.data;
+ event.handleObj = match.handleObj;
+
+ ret = match.handleObj.origHandler.apply( match.elem, arguments );
+
+ if ( ret === false || event.isPropagationStopped() ) {
+ maxLevel = match.level;
+
+ if ( ret === false ) {
+ stop = false;
+ }
+ if ( event.isImmediatePropagationStopped() ) {
+ break;
+ }
+ }
+ }
+
+ return stop;
+}
+
+function liveConvert( type, selector ) {
+ return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
+}
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+ "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
+
+ // Handle event binding
+ jQuery.fn[ name ] = function( data, fn ) {
+ if ( fn == null ) {
+ fn = data;
+ data = null;
+ }
+
+ return arguments.length > 0 ?
+ this.bind( name, data, fn ) :
+ this.trigger( name );
+ };
+
+ if ( jQuery.attrFn ) {
+ jQuery.attrFn[ name ] = true;
+ }
+});
+
+
+
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+ done = 0,
+ toString = Object.prototype.toString,
+ hasDuplicate = false,
+ baseHasDuplicate = true,
+ rBackslash = /\\/g,
+ rNonWord = /\W/;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+// Thus far that includes Google Chrome.
+[0, 0].sort(function() {
+ baseHasDuplicate = false;
+ return 0;
+});
+
+var Sizzle = function( selector, context, results, seed ) {
+ results = results || [];
+ context = context || document;
+
+ var origContext = context;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var m, set, checkSet, extra, ret, cur, pop, i,
+ prune = true,
+ contextXML = Sizzle.isXML( context ),
+ parts = [],
+ soFar = selector;
+
+ // Reset the position of the chunker regexp (start from head)
+ do {
+ chunker.exec( "" );
+ m = chunker.exec( soFar );
+
+ if ( m ) {
+ soFar = m[3];
+
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = m[3];
+ break;
+ }
+ }
+ } while ( m );
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] ) {
+ selector += parts.shift();
+ }
+
+ set = posProcess( selector, set );
+ }
+ }
+
+ } else {
+ // Take a shortcut and set the context if the root selector is an ID
+ // (but not if it'll be faster if the inner selector is an ID)
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+
+ ret = Sizzle.find( parts.shift(), context, contextXML );
+ context = ret.expr ?
+ Sizzle.filter( ret.expr, ret.set )[0] :
+ ret.set[0];
+ }
+
+ if ( context ) {
+ ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+
+ set = ret.expr ?
+ Sizzle.filter( ret.expr, ret.set ) :
+ ret.set;
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray( set );
+
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ cur = parts.pop();
+ pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
+ }
+
+ } else {
+ checkSet = parts = [];
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ Sizzle.error( cur || selector );
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+
+ } else if ( context && context.nodeType === 1 ) {
+ for ( i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+
+ } else {
+ for ( i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, origContext, results, seed );
+ Sizzle.uniqueSort( results );
+ }
+
+ return results;
+};
+
+Sizzle.uniqueSort = function( results ) {
+ if ( sortOrder ) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[ i - 1 ] ) {
+ results.splice( i--, 1 );
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function( expr, set ) {
+ return Sizzle( expr, null, null, set );
+};
+
+Sizzle.matchesSelector = function( node, expr ) {
+ return Sizzle( expr, null, null, [node] ).length > 0;
+};
+
+Sizzle.find = function( expr, context, isXML ) {
+ var set;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var match,
+ type = Expr.order[i];
+
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+ var left = match[1];
+ match.splice( 1, 1 );
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace( rBackslash, "" );
+ set = Expr.find[ type ]( match, context, isXML );
+
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = typeof context.getElementsByTagName !== "undefined" ?
+ context.getElementsByTagName( "*" ) :
+ [];
+ }
+
+ return { set: set, expr: expr };
+};
+
+Sizzle.filter = function( expr, set, inplace, not ) {
+ var match, anyFound,
+ old = expr,
+ result = [],
+ curLoop = set,
+ isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+ var found, item,
+ filter = Expr.filter[ type ],
+ left = match[1];
+
+ anyFound = false;
+
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) === "\\" ) {
+ continue;
+ }
+
+ if ( curLoop === result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+
+ } else {
+ curLoop[i] = false;
+ }
+
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if ( expr === old ) {
+ if ( anyFound == null ) {
+ Sizzle.error( expr );
+
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+ throw "Syntax error, unrecognized expression: " + msg;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+ },
+
+ leftMatch: {},
+
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+
+ attrHandle: {
+ href: function( elem ) {
+ return elem.getAttribute( "href" );
+ },
+ type: function( elem ) {
+ return elem.getAttribute( "type" );
+ }
+ },
+
+ relative: {
+ "+": function(checkSet, part){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !rNonWord.test( part ),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag ) {
+ part = part.toLowerCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+
+ ">": function( checkSet, part ) {
+ var elem,
+ isPartStr = typeof part === "string",
+ i = 0,
+ l = checkSet.length;
+
+ if ( isPartStr && !rNonWord.test( part ) ) {
+ part = part.toLowerCase();
+
+ for ( ; i < l; i++ ) {
+ elem = checkSet[i];
+
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+ }
+ }
+
+ } else {
+ for ( ; i < l; i++ ) {
+ elem = checkSet[i];
+
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+
+ "": function(checkSet, part, isXML){
+ var nodeCheck,
+ doneName = done++,
+ checkFn = dirCheck;
+
+ if ( typeof part === "string" && !rNonWord.test( part ) ) {
+ part = part.toLowerCase();
+ nodeCheck = part;
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
+ },
+
+ "~": function( checkSet, part, isXML ) {
+ var nodeCheck,
+ doneName = done++,
+ checkFn = dirCheck;
+
+ if ( typeof part === "string" && !rNonWord.test( part ) ) {
+ part = part.toLowerCase();
+ nodeCheck = part;
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
+ }
+ },
+
+ find: {
+ ID: function( match, context, isXML ) {
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ return m && m.parentNode ? [m] : [];
+ }
+ },
+
+ NAME: function( match, context ) {
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [],
+ results = context.getElementsByName( match[1] );
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+
+ TAG: function( match, context ) {
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ return context.getElementsByTagName( match[1] );
+ }
+ }
+ },
+ preFilter: {
+ CLASS: function( match, curLoop, inplace, result, not, isXML ) {
+ match = " " + match[1].replace( rBackslash, "" ) + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
+ if ( !inplace ) {
+ result.push( elem );
+ }
+
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+
+ ID: function( match ) {
+ return match[1].replace( rBackslash, "" );
+ },
+
+ TAG: function( match, curLoop ) {
+ return match[1].replace( rBackslash, "" ).toLowerCase();
+ },
+
+ CHILD: function( match ) {
+ if ( match[1] === "nth" ) {
+ if ( !match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ match[2] = match[2].replace(/^\+|\s*/g, '');
+
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
+ match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+ else if ( match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+
+ ATTR: function( match, curLoop, inplace, result, not, isXML ) {
+ var name = match[1] = match[1].replace( rBackslash, "" );
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ // Handle if an un-quoted value was used
+ match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+
+ PSEUDO: function( match, curLoop, inplace, result, not ) {
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+
+ return false;
+ }
+
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+
+ POS: function( match ) {
+ match.unshift( true );
+
+ return match;
+ }
+ },
+
+ filters: {
+ enabled: function( elem ) {
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+
+ disabled: function( elem ) {
+ return elem.disabled === true;
+ },
+
+ checked: function( elem ) {
+ return elem.checked === true;
+ },
+
+ selected: function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ parent: function( elem ) {
+ return !!elem.firstChild;
+ },
+
+ empty: function( elem ) {
+ return !elem.firstChild;
+ },
+
+ has: function( elem, i, match ) {
+ return !!Sizzle( match[3], elem ).length;
+ },
+
+ header: function( elem ) {
+ return (/h\d/i).test( elem.nodeName );
+ },
+
+ text: function( elem ) {
+ var attr = elem.getAttribute( "type" ), type = elem.type;
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // use getAttribute instead to test this case
+ return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
+ },
+
+ radio: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
+ },
+
+ checkbox: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
+ },
+
+ file: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
+ },
+
+ password: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
+ },
+
+ submit: function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && "submit" === elem.type;
+ },
+
+ image: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
+ },
+
+ reset: function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && "reset" === elem.type;
+ },
+
+ button: function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && "button" === elem.type || name === "button";
+ },
+
+ input: function( elem ) {
+ return (/input|select|textarea|button/i).test( elem.nodeName );
+ },
+
+ focus: function( elem ) {
+ return elem === elem.ownerDocument.activeElement;
+ }
+ },
+ setFilters: {
+ first: function( elem, i ) {
+ return i === 0;
+ },
+
+ last: function( elem, i, match, array ) {
+ return i === array.length - 1;
+ },
+
+ even: function( elem, i ) {
+ return i % 2 === 0;
+ },
+
+ odd: function( elem, i ) {
+ return i % 2 === 1;
+ },
+
+ lt: function( elem, i, match ) {
+ return i < match[3] - 0;
+ },
+
+ gt: function( elem, i, match ) {
+ return i > match[3] - 0;
+ },
+
+ nth: function( elem, i, match ) {
+ return match[3] - 0 === i;
+ },
+
+ eq: function( elem, i, match ) {
+ return match[3] - 0 === i;
+ }
+ },
+ filter: {
+ PSEUDO: function( elem, match, i, array ) {
+ var name = match[1],
+ filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
+
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var j = 0, l = not.length; j < l; j++ ) {
+ if ( not[j] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+
+ } else {
+ Sizzle.error( name );
+ }
+ },
+
+ CHILD: function( elem, match ) {
+ var type = match[1],
+ node = elem;
+
+ switch ( type ) {
+ case "only":
+ case "first":
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ if ( type === "first" ) {
+ return true;
+ }
+
+ node = elem;
+
+ case "last":
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ return true;
+
+ case "nth":
+ var first = match[2],
+ last = match[3];
+
+ if ( first === 1 && last === 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+
+ if ( first === 0 ) {
+ return diff === 0;
+
+ } else {
+ return ( diff % first === 0 && diff / first >= 0 );
+ }
+ }
+ },
+
+ ID: function( elem, match ) {
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+
+ TAG: function( elem, match ) {
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+ },
+
+ CLASS: function( elem, match ) {
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+
+ ATTR: function( elem, match ) {
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value !== check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+
+ POS: function( elem, match, i, array ) {
+ var name = match[2],
+ filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS,
+ fescape = function(all, num){
+ return "\\" + (num - 0 + 1);
+ };
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
+}
+
+var makeArray = function( array, results ) {
+ array = Array.prototype.slice.call( array, 0 );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+// Also verifies that the returned array holds DOM nodes
+// (which is not the case in the Blackberry browser)
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
+
+// Provide a fallback method if it does not work
+} catch( e ) {
+ makeArray = function( array, results ) {
+ var i = 0,
+ ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+
+ } else {
+ for ( ; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder, siblingCheck;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+ return a.compareDocumentPosition ? -1 : 1;
+ }
+
+ return a.compareDocumentPosition(b) & 4 ? -1 : 1;
+ };
+
+} else {
+ sortOrder = function( a, b ) {
+ // The nodes are identical, we can exit early
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+
+ // Fallback to using sourceIndex (in IE) if it's available on both nodes
+ } else if ( a.sourceIndex && b.sourceIndex ) {
+ return a.sourceIndex - b.sourceIndex;
+ }
+
+ var al, bl,
+ ap = [],
+ bp = [],
+ aup = a.parentNode,
+ bup = b.parentNode,
+ cur = aup;
+
+ // If the nodes are siblings (or identical) we can do a quick check
+ if ( aup === bup ) {
+ return siblingCheck( a, b );
+
+ // If no parents were found then the nodes are disconnected
+ } else if ( !aup ) {
+ return -1;
+
+ } else if ( !bup ) {
+ return 1;
+ }
+
+ // Otherwise they're somewhere else in the tree so we need
+ // to build up a full list of the parentNodes for comparison
+ while ( cur ) {
+ ap.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ cur = bup;
+
+ while ( cur ) {
+ bp.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ al = ap.length;
+ bl = bp.length;
+
+ // Start walking down the tree looking for a discrepancy
+ for ( var i = 0; i < al && i < bl; i++ ) {
+ if ( ap[i] !== bp[i] ) {
+ return siblingCheck( ap[i], bp[i] );
+ }
+ }
+
+ // We ended someplace up the tree so do a sibling check
+ return i === al ?
+ siblingCheck( a, bp[i], -1 ) :
+ siblingCheck( ap[i], b, 1 );
+ };
+
+ siblingCheck = function( a, b, ret ) {
+ if ( a === b ) {
+ return ret;
+ }
+
+ var cur = a.nextSibling;
+
+ while ( cur ) {
+ if ( cur === b ) {
+ return -1;
+ }
+
+ cur = cur.nextSibling;
+ }
+
+ return 1;
+ };
+}
+
+// Utility function for retreiving the text value of an array of DOM nodes
+Sizzle.getText = function( elems ) {
+ var ret = "", elem;
+
+ for ( var i = 0; elems[i]; i++ ) {
+ elem = elems[i];
+
+ // Get the text from text nodes and CDATA nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+ ret += elem.nodeValue;
+
+ // Traverse everything else, except comment nodes
+ } else if ( elem.nodeType !== 8 ) {
+ ret += Sizzle.getText( elem.childNodes );
+ }
+ }
+
+ return ret;
+};
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("div"),
+ id = "script" + (new Date()).getTime(),
+ root = document.documentElement;
+
+ form.innerHTML = "<a name='" + id + "'/>";
+
+ // Inject it into the root element, check its status, and remove it quickly
+ root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if ( document.getElementById( id ) ) {
+ Expr.find.ID = function( match, context, isXML ) {
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+
+ return m ?
+ m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
+ [m] :
+ undefined :
+ [];
+ }
+ };
+
+ Expr.filter.ID = function( elem, match ) {
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+
+ // release memory in IE
+ root = form = null;
+})();
+
+(function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function( match, context ) {
+ var results = context.getElementsByTagName( match[1] );
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "<a href='#'></a>";
+
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+
+ Expr.attrHandle.href = function( elem ) {
+ return elem.getAttribute( "href", 2 );
+ };
+ }
+
+ // release memory in IE
+ div = null;
+})();
+
+if ( document.querySelectorAll ) {
+ (function(){
+ var oldSizzle = Sizzle,
+ div = document.createElement("div"),
+ id = "__sizzle__";
+
+ div.innerHTML = "<p class='TEST'></p>";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function( query, context, extra, seed ) {
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && !Sizzle.isXML(context) ) {
+ // See if we find a selector to speed up
+ var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
+
+ if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
+ // Speed-up: Sizzle("TAG")
+ if ( match[1] ) {
+ return makeArray( context.getElementsByTagName( query ), extra );
+
+ // Speed-up: Sizzle(".CLASS")
+ } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
+ return makeArray( context.getElementsByClassName( match[2] ), extra );
+ }
+ }
+
+ if ( context.nodeType === 9 ) {
+ // Speed-up: Sizzle("body")
+ // The body element only exists once, optimize finding it
+ if ( query === "body" && context.body ) {
+ return makeArray( [ context.body ], extra );
+
+ // Speed-up: Sizzle("#ID")
+ } else if ( match && match[3] ) {
+ var elem = context.getElementById( match[3] );
+
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id === match[3] ) {
+ return makeArray( [ elem ], extra );
+ }
+
+ } else {
+ return makeArray( [], extra );
+ }
+ }
+
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(qsaError) {}
+
+ // qSA works strangely on Element-rooted queries
+ // We can work around this by specifying an extra ID on the root
+ // and working up from there (Thanks to Andrew Dupont for the technique)
+ // IE 8 doesn't work on object elements
+ } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+ var oldContext = context,
+ old = context.getAttribute( "id" ),
+ nid = old || id,
+ hasParent = context.parentNode,
+ relativeHierarchySelector = /^\s*[+~]/.test( query );
+
+ if ( !old ) {
+ context.setAttribute( "id", nid );
+ } else {
+ nid = nid.replace( /'/g, "\\$&" );
+ }
+ if ( relativeHierarchySelector && hasParent ) {
+ context = context.parentNode;
+ }
+
+ try {
+ if ( !relativeHierarchySelector || hasParent ) {
+ return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
+ }
+
+ } catch(pseudoError) {
+ } finally {
+ if ( !old ) {
+ oldContext.removeAttribute( "id" );
+ }
+ }
+ }
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ for ( var prop in oldSizzle ) {
+ Sizzle[ prop ] = oldSizzle[ prop ];
+ }
+
+ // release memory in IE
+ div = null;
+ })();
+}
+
+(function(){
+ var html = document.documentElement,
+ matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
+
+ if ( matches ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9 fails this)
+ var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
+ pseudoWorks = false;
+
+ try {
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call( document.documentElement, "[test!='']:sizzle" );
+
+ } catch( pseudoError ) {
+ pseudoWorks = true;
+ }
+
+ Sizzle.matchesSelector = function( node, expr ) {
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
+
+ if ( !Sizzle.isXML( node ) ) {
+ try {
+ if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
+ var ret = matches.call( node, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || !disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9, so check for that
+ node.document && node.document.nodeType !== 11 ) {
+ return ret;
+ }
+ }
+ } catch(e) {}
+ }
+
+ return Sizzle(expr, null, null, [node]).length > 0;
+ };
+ }
+})();
+
+(function(){
+ var div = document.createElement("div");
+
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ // Opera can't find a second classname (in 9.6)
+ // Also, make sure that getElementsByClassName actually exists
+ if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+ return;
+ }
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 ) {
+ return;
+ }
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function( match, context, isXML ) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+
+ // release memory in IE
+ div = null;
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+
+ if ( elem ) {
+ var match = false;
+
+ elem = elem[dir];
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName.toLowerCase() === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+
+ if ( elem ) {
+ var match = false;
+
+ elem = elem[dir];
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+if ( document.documentElement.contains ) {
+ Sizzle.contains = function( a, b ) {
+ return a !== b && (a.contains ? a.contains(b) : true);
+ };
+
+} else if ( document.documentElement.compareDocumentPosition ) {
+ Sizzle.contains = function( a, b ) {
+ return !!(a.compareDocumentPosition(b) & 16);
+ };
+
+} else {
+ Sizzle.contains = function() {
+ return false;
+ };
+}
+
+Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function( selector, context ) {
+ var match,
+ tmpSet = [],
+ later = "",
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})();
+
+
+var runtil = /Until$/,
+ rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+ // Note: This RegExp should be improved, or likely pulled from Sizzle
+ rmultiselector = /,/,
+ isSimple = /^.[^:#\[\.,]*$/,
+ slice = Array.prototype.slice,
+ POS = jQuery.expr.match.POS,
+ // methods guaranteed to produce a unique set when starting from a unique set
+ guaranteedUnique = {
+ children: true,
+ contents: true,
+ next: true,
+ prev: true
+ };
+
+jQuery.fn.extend({
+ find: function( selector ) {
+ var self = this,
+ i, l;
+
+ if ( typeof selector !== "string" ) {
+ return jQuery( selector ).filter(function() {
+ for ( i = 0, l = self.length; i < l; i++ ) {
+ if ( jQuery.contains( self[ i ], this ) ) {
+ return true;
+ }
+ }
+ });
+ }
+
+ var ret = this.pushStack( "", "find", selector ),
+ length, n, r;
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ length = ret.length;
+ jQuery.find( selector, this[i], ret );
+
+ if ( i > 0 ) {
+ // Make sure that the results are unique
+ for ( n = length; n < ret.length; n++ ) {
+ for ( r = 0; r < length; r++ ) {
+ if ( ret[r] === ret[n] ) {
+ ret.splice(n--, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ has: function( target ) {
+ var targets = jQuery( target );
+ return this.filter(function() {
+ for ( var i = 0, l = targets.length; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[i] ) ) {
+ return true;
+ }
+ }
+ });
+ },
+
+ not: function( selector ) {
+ return this.pushStack( winnow(this, selector, false), "not", selector);
+ },
+
+ filter: function( selector ) {
+ return this.pushStack( winnow(this, selector, true), "filter", selector );
+ },
+
+ is: function( selector ) {
+ return !!selector && ( typeof selector === "string" ?
+ jQuery.filter( selector, this ).length > 0 :
+ this.filter( selector ).length > 0 );
+ },
+
+ closest: function( selectors, context ) {
+ var ret = [], i, l, cur = this[0];
+
+ // Array
+ if ( jQuery.isArray( selectors ) ) {
+ var match, selector,
+ matches = {},
+ level = 1;
+
+ if ( cur && selectors.length ) {
+ for ( i = 0, l = selectors.length; i < l; i++ ) {
+ selector = selectors[i];
+
+ if ( !matches[ selector ] ) {
+ matches[ selector ] = POS.test( selector ) ?
+ jQuery( selector, context || this.context ) :
+ selector;
+ }
+ }
+
+ while ( cur && cur.ownerDocument && cur !== context ) {
+ for ( selector in matches ) {
+ match = matches[ selector ];
+
+ if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
+ ret.push({ selector: selector, elem: cur, level: level });
+ }
+ }
+
+ cur = cur.parentNode;
+ level++;
+ }
+ }
+
+ return ret;
+ }
+
+ // String
+ var pos = POS.test( selectors ) || typeof selectors !== "string" ?
+ jQuery( selectors, context || this.context ) :
+ 0;
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ cur = this[i];
+
+ while ( cur ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
+ ret.push( cur );
+ break;
+
+ } else {
+ cur = cur.parentNode;
+ if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
+ break;
+ }
+ }
+ }
+ }
+
+ ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
+
+ return this.pushStack( ret, "closest", selectors );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+
+ // No argument, return index in parent
+ if ( !elem ) {
+ return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
+ }
+
+ // index in selector
+ if ( typeof elem === "string" ) {
+ return jQuery.inArray( this[0], jQuery( elem ) );
+ }
+
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[0] : elem, this );
+ },
+
+ add: function( selector, context ) {
+ var set = typeof selector === "string" ?
+ jQuery( selector, context ) :
+ jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
+ all = jQuery.merge( this.get(), set );
+
+ return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+ all :
+ jQuery.unique( all ) );
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ }
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+ return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return jQuery.dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return jQuery.nth( elem, 2, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return jQuery.nth( elem, 2, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return jQuery.dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return jQuery.dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return jQuery.sibling( elem.parentNode.firstChild, elem );
+ },
+ children: function( elem ) {
+ return jQuery.sibling( elem.firstChild );
+ },
+ contents: function( elem ) {
+ return jQuery.nodeName( elem, "iframe" ) ?
+ elem.contentDocument || elem.contentWindow.document :
+ jQuery.makeArray( elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var ret = jQuery.map( this, fn, until ),
+ // The variable 'args' was introduced in
+ // https://github.com/jquery/jquery/commit/52a0238
+ // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
+ // http://code.google.com/p/v8/issues/detail?id=1050
+ args = slice.call(arguments);
+
+ if ( !runtil.test( name ) ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ ret = jQuery.filter( selector, ret );
+ }
+
+ ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
+
+ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack( ret, name, args.join(",") );
+ };
+});
+
+jQuery.extend({
+ filter: function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return elems.length === 1 ?
+ jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+ jQuery.find.matches(expr, elems);
+ },
+
+ dir: function( elem, dir, until ) {
+ var matched = [],
+ cur = elem[ dir ];
+
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+ if ( cur.nodeType === 1 ) {
+ matched.push( cur );
+ }
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function( cur, result, dir, elem ) {
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] ) {
+ if ( cur.nodeType === 1 && ++num === result ) {
+ break;
+ }
+ }
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ r.push( n );
+ }
+ }
+
+ return r;
+ }
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, keep ) {
+
+ // Can't pass null or undefined to indexOf in Firefox 4
+ // Set to 0 to skip string check
+ qualifier = qualifier || 0;
+
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ var retVal = !!qualifier.call( elem, i, elem );
+ return retVal === keep;
+ });
+
+ } else if ( qualifier.nodeType ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ return (elem === qualifier) === keep;
+ });
+
+ } else if ( typeof qualifier === "string" ) {
+ var filtered = jQuery.grep(elements, function( elem ) {
+ return elem.nodeType === 1;
+ });
+
+ if ( isSimple.test( qualifier ) ) {
+ return jQuery.filter(qualifier, filtered, !keep);
+ } else {
+ qualifier = jQuery.filter( qualifier, filtered );
+ }
+ }
+
+ return jQuery.grep(elements, function( elem, i ) {
+ return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+ });
+}
+
+
+
+
+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+ rleadingWhitespace = /^\s+/,
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
+ rtagName = /<([\w:]+)/,
+ rtbody = /<tbody/i,
+ rhtml = /<|&#?\w+;/,
+ rnocache = /<(?:script|object|embed|option|style)/i,
+ // checked="checked" or checked
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+ rscriptType = /\/(java|ecma)script/i,
+ rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
+ wrapMap = {
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
+ thead: [ 1, "<table>", "</table>" ],
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+ area: [ 1, "<map>", "</map>" ],
+ _default: [ 0, "", "" ]
+ };
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+ wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+ text: function( text ) {
+ if ( jQuery.isFunction(text) ) {
+ return this.each(function(i) {
+ var self = jQuery( this );
+
+ self.text( text.call(this, i, self.text()) );
+ });
+ }
+
+ if ( typeof text !== "object" && text !== undefined ) {
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+ }
+
+ return jQuery.text( this );
+ },
+
+ wrapAll: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapAll( html.call(this, i) );
+ });
+ }
+
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+ if ( this[0].parentNode ) {
+ wrap.insertBefore( this[0] );
+ }
+
+ wrap.map(function() {
+ var elem = this;
+
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+ elem = elem.firstChild;
+ }
+
+ return elem;
+ }).append( this );
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapInner( html.call(this, i) );
+ });
+ }
+
+ return this.each(function() {
+ var self = jQuery( this ),
+ contents = self.contents();
+
+ if ( contents.length ) {
+ contents.wrapAll( html );
+
+ } else {
+ self.append( html );
+ }
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function() {
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ unwrap: function() {
+ return this.parent().each(function() {
+ if ( !jQuery.nodeName( this, "body" ) ) {
+ jQuery( this ).replaceWith( this.childNodes );
+ }
+ }).end();
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.appendChild( elem );
+ }
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.insertBefore( elem, this.firstChild );
+ }
+ });
+ },
+
+ before: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this );
+ });
+ } else if ( arguments.length ) {
+ var set = jQuery(arguments[0]);
+ set.push.apply( set, this.toArray() );
+ return this.pushStack( set, "before", arguments );
+ }
+ },
+
+ after: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ } else if ( arguments.length ) {
+ var set = this.pushStack( this, "after", arguments );
+ set.push.apply( set, jQuery(arguments[0]).toArray() );
+ return set;
+ }
+ },
+
+ // keepData is for internal use only--do not document
+ remove: function( selector, keepData ) {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
+ if ( !keepData && elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ jQuery.cleanData( [ elem ] );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+ }
+ }
+
+ return this;
+ },
+
+ empty: function() {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ }
+
+ // Remove any remaining nodes
+ while ( elem.firstChild ) {
+ elem.removeChild( elem.firstChild );
+ }
+ }
+
+ return this;
+ },
+
+ clone: function( dataAndEvents, deepDataAndEvents ) {
+ dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+ return this.map( function () {
+ return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+ });
+ },
+
+ html: function( value ) {
+ if ( value === undefined ) {
+ return this[0] && this[0].nodeType === 1 ?
+ this[0].innerHTML.replace(rinlinejQuery, "") :
+ null;
+
+ // See if we can take a shortcut and just use innerHTML
+ } else if ( typeof value === "string" && !rnocache.test( value ) &&
+ (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+ !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+ value = value.replace(rxhtmlTag, "<$1></$2>");
+
+ try {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( this[i].nodeType === 1 ) {
+ jQuery.cleanData( this[i].getElementsByTagName("*") );
+ this[i].innerHTML = value;
+ }
+ }
+
+ // If using innerHTML throws an exception, use the fallback method
+ } catch(e) {
+ this.empty().append( value );
+ }
+
+ } else if ( jQuery.isFunction( value ) ) {
+ this.each(function(i){
+ var self = jQuery( this );
+
+ self.html( value.call(this, i, self.html()) );
+ });
+
+ } else {
+ this.empty().append( value );
+ }
+
+ return this;
+ },
+
+ replaceWith: function( value ) {
+ if ( this[0] && this[0].parentNode ) {
+ // Make sure that the elements are removed from the DOM before they are inserted
+ // this can help fix replacing a parent with child elements
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this), old = self.html();
+ self.replaceWith( value.call( this, i, old ) );
+ });
+ }
+
+ if ( typeof value !== "string" ) {
+ value = jQuery( value ).detach();
+ }
+
+ return this.each(function() {
+ var next = this.nextSibling,
+ parent = this.parentNode;
+
+ jQuery( this ).remove();
+
+ if ( next ) {
+ jQuery(next).before( value );
+ } else {
+ jQuery(parent).append( value );
+ }
+ });
+ } else {
+ return this.length ?
+ this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
+ this;
+ }
+ },
+
+ detach: function( selector ) {
+ return this.remove( selector, true );
+ },
+
+ domManip: function( args, table, callback ) {
+ var results, first, fragment, parent,
+ value = args[0],
+ scripts = [];
+
+ // We can't cloneNode fragments that contain checked, in WebKit
+ if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+ return this.each(function() {
+ jQuery(this).domManip( args, table, callback, true );
+ });
+ }
+
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ args[0] = value.call(this, i, table ? self.html() : undefined);
+ self.domManip( args, table, callback );
+ });
+ }
+
+ if ( this[0] ) {
+ parent = value && value.parentNode;
+
+ // If we're in a fragment, just use that instead of building a new one
+ if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
+ results = { fragment: parent };
+
+ } else {
+ results = jQuery.buildFragment( args, this, scripts );
+ }
+
+ fragment = results.fragment;
+
+ if ( fragment.childNodes.length === 1 ) {
+ first = fragment = fragment.firstChild;
+ } else {
+ first = fragment.firstChild;
+ }
+
+ if ( first ) {
+ table = table && jQuery.nodeName( first, "tr" );
+
+ for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
+ callback.call(
+ table ?
+ root(this[i], first) :
+ this[i],
+ // Make sure that we do not leak memory by inadvertently discarding
+ // the original fragment (which might have attached data) instead of
+ // using it; in addition, use the original fragment object for the last
+ // item instead of first because it can end up being emptied incorrectly
+ // in certain situations (Bug #8070).
+ // Fragments from the fragment cache must always be cloned and never used
+ // in place.
+ results.cacheable || (l > 1 && i < lastIndex) ?
+ jQuery.clone( fragment, true, true ) :
+ fragment
+ );
+ }
+ }
+
+ if ( scripts.length ) {
+ jQuery.each( scripts, evalScript );
+ }
+ }
+
+ return this;
+ }
+});
+
+function root( elem, cur ) {
+ return jQuery.nodeName(elem, "table") ?
+ (elem.getElementsByTagName("tbody")[0] ||
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+ elem;
+}
+
+function cloneCopyEvent( src, dest ) {
+
+ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+ return;
+ }
+
+ var internalKey = jQuery.expando,
+ oldData = jQuery.data( src ),
+ curData = jQuery.data( dest, oldData );
+
+ // Switch to use the internal data object, if it exists, for the next
+ // stage of data copying
+ if ( (oldData = oldData[ internalKey ]) ) {
+ var events = oldData.events;
+ curData = curData[ internalKey ] = jQuery.extend({}, oldData);
+
+ if ( events ) {
+ delete curData.handle;
+ curData.events = {};
+
+ for ( var type in events ) {
+ for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
+ jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
+ }
+ }
+ }
+ }
+}
+
+function cloneFixAttributes( src, dest ) {
+ var nodeName;
+
+ // We do not need to do anything for non-Elements
+ if ( dest.nodeType !== 1 ) {
+ return;
+ }
+
+ // clearAttributes removes the attributes, which we don't want,
+ // but also removes the attachEvent events, which we *do* want
+ if ( dest.clearAttributes ) {
+ dest.clearAttributes();
+ }
+
+ // mergeAttributes, in contrast, only merges back on the
+ // original attributes, not the events
+ if ( dest.mergeAttributes ) {
+ dest.mergeAttributes( src );
+ }
+
+ nodeName = dest.nodeName.toLowerCase();
+
+ // IE6-8 fail to clone children inside object elements that use
+ // the proprietary classid attribute value (rather than the type
+ // attribute) to identify the type of content to display
+ if ( nodeName === "object" ) {
+ dest.outerHTML = src.outerHTML;
+
+ } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
+ // IE6-8 fails to persist the checked state of a cloned checkbox
+ // or radio button. Worse, IE6-7 fail to give the cloned element
+ // a checked appearance if the defaultChecked value isn't also set
+ if ( src.checked ) {
+ dest.defaultChecked = dest.checked = src.checked;
+ }
+
+ // IE6-7 get confused and end up setting the value of a cloned
+ // checkbox/radio button to an empty string instead of "on"
+ if ( dest.value !== src.value ) {
+ dest.value = src.value;
+ }
+
+ // IE6-8 fails to return the selected option to the default selected
+ // state when cloning options
+ } else if ( nodeName === "option" ) {
+ dest.selected = src.defaultSelected;
+
+ // IE6-8 fails to set the defaultValue to the correct value when
+ // cloning other types of input fields
+ } else if ( nodeName === "input" || nodeName === "textarea" ) {
+ dest.defaultValue = src.defaultValue;
+ }
+
+ // Event data gets referenced instead of copied if the expando
+ // gets copied too
+ dest.removeAttribute( jQuery.expando );
+}
+
+jQuery.buildFragment = function( args, nodes, scripts ) {
+ var fragment, cacheable, cacheresults, doc;
+
+ // nodes may contain either an explicit document object,
+ // a jQuery collection or context object.
+ // If nodes[0] contains a valid object to assign to doc
+ if ( nodes && nodes[0] ) {
+ doc = nodes[0].ownerDocument || nodes[0];
+ }
+
+ // Ensure that an attr object doesn't incorrectly stand in as a document object
+ // Chrome and Firefox seem to allow this to occur and will throw exception
+ // Fixes #8950
+ if ( !doc.createDocumentFragment ) {
+ doc = document;
+ }
+
+ // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
+ // Cloning options loses the selected state, so don't cache them
+ // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
+ // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+ if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
+ args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+
+ cacheable = true;
+
+ cacheresults = jQuery.fragments[ args[0] ];
+ if ( cacheresults && cacheresults !== 1 ) {
+ fragment = cacheresults;
+ }
+ }
+
+ if ( !fragment ) {
+ fragment = doc.createDocumentFragment();
+ jQuery.clean( args, doc, fragment, scripts );
+ }
+
+ if ( cacheable ) {
+ jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+ }
+
+ return { fragment: fragment, cacheable: cacheable };
+};
+
+jQuery.fragments = {};
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function( name, original ) {
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = [],
+ insert = jQuery( selector ),
+ parent = this.length === 1 && this[0].parentNode;
+
+ if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
+ insert[ original ]( this[0] );
+ return this;
+
+ } else {
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery( insert[i] )[ original ]( elems );
+ ret = ret.concat( elems );
+ }
+
+ return this.pushStack( ret, name, insert.selector );
+ }
+ };
+});
+
+function getAll( elem ) {
+ if ( "getElementsByTagName" in elem ) {
+ return elem.getElementsByTagName( "*" );
+
+ } else if ( "querySelectorAll" in elem ) {
+ return elem.querySelectorAll( "*" );
+
+ } else {
+ return [];
+ }
+}
+
+// Used in clean, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+ if ( elem.type === "checkbox" || elem.type === "radio" ) {
+ elem.defaultChecked = elem.checked;
+ }
+}
+// Finds all inputs and passes them to fixDefaultChecked
+function findInputs( elem ) {
+ if ( jQuery.nodeName( elem, "input" ) ) {
+ fixDefaultChecked( elem );
+ } else if ( "getElementsByTagName" in elem ) {
+ jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
+ }
+}
+
+jQuery.extend({
+ clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+ var clone = elem.cloneNode(true),
+ srcElements,
+ destElements,
+ i;
+
+ if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
+ (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
+ // IE copies events bound via attachEvent when using cloneNode.
+ // Calling detachEvent on the clone will also remove the events
+ // from the original. In order to get around this, we use some
+ // proprietary methods to clear the events. Thanks to MooTools
+ // guys for this hotness.
+
+ cloneFixAttributes( elem, clone );
+
+ // Using Sizzle here is crazy slow, so we use getElementsByTagName
+ // instead
+ srcElements = getAll( elem );
+ destElements = getAll( clone );
+
+ // Weird iteration because IE will replace the length property
+ // with an element if you are cloning the body and one of the
+ // elements on the page has a name or id of "length"
+ for ( i = 0; srcElements[i]; ++i ) {
+ // Ensure that the destination node is not null; Fixes #9587
+ if ( destElements[i] ) {
+ cloneFixAttributes( srcElements[i], destElements[i] );
+ }
+ }
+ }
+
+ // Copy the events from the original to the clone
+ if ( dataAndEvents ) {
+ cloneCopyEvent( elem, clone );
+
+ if ( deepDataAndEvents ) {
+ srcElements = getAll( elem );
+ destElements = getAll( clone );
+
+ for ( i = 0; srcElements[i]; ++i ) {
+ cloneCopyEvent( srcElements[i], destElements[i] );
+ }
+ }
+ }
+
+ srcElements = destElements = null;
+
+ // Return the cloned set
+ return clone;
+ },
+
+ clean: function( elems, context, fragment, scripts ) {
+ var checkScriptType;
+
+ context = context || document;
+
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if ( typeof context.createElement === "undefined" ) {
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+ }
+
+ var ret = [], j;
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ if ( typeof elem === "number" ) {
+ elem += "";
+ }
+
+ if ( !elem ) {
+ continue;
+ }
+
+ // Convert html string into DOM nodes
+ if ( typeof elem === "string" ) {
+ if ( !rhtml.test( elem ) ) {
+ elem = context.createTextNode( elem );
+ } else {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(rxhtmlTag, "<$1></$2>");
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+ wrap = wrapMap[ tag ] || wrapMap._default,
+ depth = wrap[0],
+ div = context.createElement("div");
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( depth-- ) {
+ div = div.lastChild;
+ }
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var hasBody = rtbody.test(elem),
+ tbody = tag === "table" && !hasBody ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] === "<table>" && !hasBody ?
+ div.childNodes :
+ [];
+
+ for ( j = tbody.length - 1; j >= 0 ; --j ) {
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+ }
+ }
+ }
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+ div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+ }
+
+ elem = div.childNodes;
+ }
+ }
+
+ // Resets defaultChecked for any radios and checkboxes
+ // about to be appended to the DOM in IE 6/7 (#8060)
+ var len;
+ if ( !jQuery.support.appendChecked ) {
+ if ( elem[0] && typeof (len = elem.length) === "number" ) {
+ for ( j = 0; j < len; j++ ) {
+ findInputs( elem[j] );
+ }
+ } else {
+ findInputs( elem );
+ }
+ }
+
+ if ( elem.nodeType ) {
+ ret.push( elem );
+ } else {
+ ret = jQuery.merge( ret, elem );
+ }
+ }
+
+ if ( fragment ) {
+ checkScriptType = function( elem ) {
+ return !elem.type || rscriptType.test( elem.type );
+ };
+ for ( i = 0; ret[i]; i++ ) {
+ if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+
+ } else {
+ if ( ret[i].nodeType === 1 ) {
+ var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
+
+ ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
+ }
+ fragment.appendChild( ret[i] );
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ cleanData: function( elems ) {
+ var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
+ deleteExpando = jQuery.support.deleteExpando;
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ continue;
+ }
+
+ id = elem[ jQuery.expando ];
+
+ if ( id ) {
+ data = cache[ id ] && cache[ id ][ internalKey ];
+
+ if ( data && data.events ) {
+ for ( var type in data.events ) {
+ if ( special[ type ] ) {
+ jQuery.event.remove( elem, type );
+
+ // This is a shortcut to avoid jQuery.event.remove's overhead
+ } else {
+ jQuery.removeEvent( elem, type, data.handle );
+ }
+ }
+
+ // Null the DOM reference to avoid IE6/7/8 leak (#7054)
+ if ( data.handle ) {
+ data.handle.elem = null;
+ }
+ }
+
+ if ( deleteExpando ) {
+ delete elem[ jQuery.expando ];
+
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+ }
+
+ delete cache[ id ];
+ }
+ }
+ }
+});
+
+function evalScript( i, elem ) {
+ if ( elem.src ) {
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+ } else {
+ jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+}
+
+
+
+
+var ralpha = /alpha\([^)]*\)/i,
+ ropacity = /opacity=([^)]*)/,
+ // fixed for IE9, see #8346
+ rupper = /([A-Z]|^ms)/g,
+ rnumpx = /^-?\d+(?:px)?$/i,
+ rnum = /^-?\d/,
+ rrelNum = /^([\-+])=([\-+.\de]+)/,
+
+ cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+ cssWidth = [ "Left", "Right" ],
+ cssHeight = [ "Top", "Bottom" ],
+ curCSS,
+
+ getComputedStyle,
+ currentStyle;
+
+jQuery.fn.css = function( name, value ) {
+ // Setting 'undefined' is a no-op
+ if ( arguments.length === 2 && value === undefined ) {
+ return this;
+ }
+
+ return jQuery.access( this, name, value, true, function( elem, name, value ) {
+ return value !== undefined ?
+ jQuery.style( elem, name, value ) :
+ jQuery.css( elem, name );
+ });
+};
+
+jQuery.extend({
+ // Add in style property hooks for overriding the default
+ // behavior of getting and setting a style property
+ cssHooks: {
+ opacity: {
+ get: function( elem, computed ) {
+ if ( computed ) {
+ // We should always get a number back from opacity
+ var ret = curCSS( elem, "opacity", "opacity" );
+ return ret === "" ? "1" : ret;
+
+ } else {
+ return elem.style.opacity;
+ }
+ }
+ }
+ },
+
+ // Exclude the following css properties to add px
+ cssNumber: {
+ "fillOpacity": true,
+ "fontWeight": true,
+ "lineHeight": true,
+ "opacity": true,
+ "orphans": true,
+ "widows": true,
+ "zIndex": true,
+ "zoom": true
+ },
+
+ // Add in properties whose names you wish to fix before
+ // setting or getting the value
+ cssProps: {
+ // normalize float css property
+ "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+ },
+
+ // Get and set the style property on a DOM Node
+ style: function( elem, name, value, extra ) {
+ // Don't set styles on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+ return;
+ }
+
+ // Make sure that we're working with the right name
+ var ret, type, origName = jQuery.camelCase( name ),
+ style = elem.style, hooks = jQuery.cssHooks[ origName ];
+
+ name = jQuery.cssProps[ origName ] || origName;
+
+ // Check if we're setting a value
+ if ( value !== undefined ) {
+ type = typeof value;
+
+ // convert relative number strings (+= or -=) to relative numbers. #7345
+ if ( type === "string" && (ret = rrelNum.exec( value )) ) {
+ value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
+ // Fixes bug #9237
+ type = "number";
+ }
+
+ // Make sure that NaN and null values aren't set. See: #7116
+ if ( value == null || type === "number" && isNaN( value ) ) {
+ return;
+ }
+
+ // If a number was passed in, add 'px' to the (except for certain CSS properties)
+ if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+ value += "px";
+ }
+
+ // If a hook was provided, use that value, otherwise just set the specified value
+ if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
+ // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+ // Fixes bug #5509
+ try {
+ style[ name ] = value;
+ } catch(e) {}
+ }
+
+ } else {
+ // If a hook was provided get the non-computed value from there
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+ return ret;
+ }
+
+ // Otherwise just get the value from the style object
+ return style[ name ];
+ }
+ },
+
+ css: function( elem, name, extra ) {
+ var ret, hooks;
+
+ // Make sure that we're working with the right name
+ name = jQuery.camelCase( name );
+ hooks = jQuery.cssHooks[ name ];
+ name = jQuery.cssProps[ name ] || name;
+
+ // cssFloat needs a special treatment
+ if ( name === "cssFloat" ) {
+ name = "float";
+ }
+
+ // If a hook was provided get the computed value from there
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
+ return ret;
+
+ // Otherwise, if a way to get the computed value exists, use that
+ } else if ( curCSS ) {
+ return curCSS( elem, name );
+ }
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( name in options ) {
+ elem.style[ name ] = old[ name ];
+ }
+ }
+});
+
+// DEPRECATED, Use jQuery.css() instead
+jQuery.curCSS = jQuery.css;
+
+jQuery.each(["height", "width"], function( i, name ) {
+ jQuery.cssHooks[ name ] = {
+ get: function( elem, computed, extra ) {
+ var val;
+
+ if ( computed ) {
+ if ( elem.offsetWidth !== 0 ) {
+ return getWH( elem, name, extra );
+ } else {
+ jQuery.swap( elem, cssShow, function() {
+ val = getWH( elem, name, extra );
+ });
+ }
+
+ return val;
+ }
+ },
+
+ set: function( elem, value ) {
+ if ( rnumpx.test( value ) ) {
+ // ignore negative width and height values #1599
+ value = parseFloat( value );
+
+ if ( value >= 0 ) {
+ return value + "px";
+ }
+
+ } else {
+ return value;
+ }
+ }
+ };
+});
+
+if ( !jQuery.support.opacity ) {
+ jQuery.cssHooks.opacity = {
+ get: function( elem, computed ) {
+ // IE uses filters for opacity
+ return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+ ( parseFloat( RegExp.$1 ) / 100 ) + "" :
+ computed ? "1" : "";
+ },
+
+ set: function( elem, value ) {
+ var style = elem.style,
+ currentStyle = elem.currentStyle,
+ opacity = jQuery.isNaN( value ) ? "" : "alpha(opacity=" + value * 100 + ")",
+ filter = currentStyle && currentStyle.filter || style.filter || "";
+
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ style.zoom = 1;
+
+ // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
+ if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
+
+ // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
+ // if "filter:" is present at all, clearType is disabled, we want to avoid this
+ // style.removeAttribute is IE Only, but so apparently is this code path...
+ style.removeAttribute( "filter" );
+
+ // if there there is no filter style applied in a css rule, we are done
+ if ( currentStyle && !currentStyle.filter ) {
+ return;
+ }
+ }
+
+ // otherwise, set new filter values
+ style.filter = ralpha.test( filter ) ?
+ filter.replace( ralpha, opacity ) :
+ filter + " " + opacity;
+ }
+ };
+}
+
+jQuery(function() {
+ // This hook cannot be added until DOM ready because the support test
+ // for it is not run until after DOM ready
+ if ( !jQuery.support.reliableMarginRight ) {
+ jQuery.cssHooks.marginRight = {
+ get: function( elem, computed ) {
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ // Work around by temporarily setting element display to inline-block
+ var ret;
+ jQuery.swap( elem, { "display": "inline-block" }, function() {
+ if ( computed ) {
+ ret = curCSS( elem, "margin-right", "marginRight" );
+ } else {
+ ret = elem.style.marginRight;
+ }
+ });
+ return ret;
+ }
+ };
+ }
+});
+
+if ( document.defaultView && document.defaultView.getComputedStyle ) {
+ getComputedStyle = function( elem, name ) {
+ var ret, defaultView, computedStyle;
+
+ name = name.replace( rupper, "-$1" ).toLowerCase();
+
+ if ( !(defaultView = elem.ownerDocument.defaultView) ) {
+ return undefined;
+ }
+
+ if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
+ ret = computedStyle.getPropertyValue( name );
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
+ ret = jQuery.style( elem, name );
+ }
+ }
+
+ return ret;
+ };
+}
+
+if ( document.documentElement.currentStyle ) {
+ currentStyle = function( elem, name ) {
+ var left,
+ ret = elem.currentStyle && elem.currentStyle[ name ],
+ rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
+ style = elem.style;
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+ // Remember the original values
+ left = style.left;
+
+ // Put in the new values to get a computed value out
+ if ( rsLeft ) {
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ }
+ style.left = name === "fontSize" ? "1em" : (ret || 0);
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ if ( rsLeft ) {
+ elem.runtimeStyle.left = rsLeft;
+ }
+ }
+
+ return ret === "" ? "auto" : ret;
+ };
+}
+
+curCSS = getComputedStyle || currentStyle;
+
+function getWH( elem, name, extra ) {
+
+ // Start with offset property
+ var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+ which = name === "width" ? cssWidth : cssHeight;
+
+ if ( val > 0 ) {
+ if ( extra !== "border" ) {
+ jQuery.each( which, function() {
+ if ( !extra ) {
+ val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
+ }
+ if ( extra === "margin" ) {
+ val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
+ } else {
+ val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
+ }
+ });
+ }
+
+ return val + "px";
+ }
+
+ // Fall back to computed then uncomputed css if necessary
+ val = curCSS( elem, name, name );
+ if ( val < 0 || val == null ) {
+ val = elem.style[ name ] || 0;
+ }
+ // Normalize "", auto, and prepare for extra
+ val = parseFloat( val ) || 0;
+
+ // Add padding, border, margin
+ if ( extra ) {
+ jQuery.each( which, function() {
+ val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
+ if ( extra !== "padding" ) {
+ val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
+ }
+ if ( extra === "margin" ) {
+ val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
+ }
+ });
+ }
+
+ return val + "px";
+}
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.hidden = function( elem ) {
+ var width = elem.offsetWidth,
+ height = elem.offsetHeight;
+
+ return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
+ };
+
+ jQuery.expr.filters.visible = function( elem ) {
+ return !jQuery.expr.filters.hidden( elem );
+ };
+}
+
+
+
+
+var r20 = /%20/g,
+ rbracket = /\[\]$/,
+ rCRLF = /\r?\n/g,
+ rhash = /#.*$/,
+ rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
+ rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+ // #7653, #8125, #8152: local protocol detection
+ rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
+ rnoContent = /^(?:GET|HEAD)$/,
+ rprotocol = /^\/\//,
+ rquery = /\?/,
+ rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+ rselectTextarea = /^(?:select|textarea)/i,
+ rspacesAjax = /\s+/,
+ rts = /([?&])_=[^&]*/,
+ rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
+
+ // Keep a copy of the old load method
+ _load = jQuery.fn.load,
+
+ /* Prefilters
+ * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+ * 2) These are called:
+ * - BEFORE asking for a transport
+ * - AFTER param serialization (s.data is a string if s.processData is true)
+ * 3) key is the dataType
+ * 4) the catchall symbol "*" can be used
+ * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+ */
+ prefilters = {},
+
+ /* Transports bindings
+ * 1) key is the dataType
+ * 2) the catchall symbol "*" can be used
+ * 3) selection will start with transport dataType and THEN go to "*" if needed
+ */
+ transports = {},
+
+ // Document location
+ ajaxLocation,
+
+ // Document location segments
+ ajaxLocParts,
+
+ // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+ allTypes = ["*/"] + ["*"];
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+ ajaxLocation = location.href;
+} catch( e ) {
+ // Use the href attribute of an A element
+ // since IE will modify it given document.location
+ ajaxLocation = document.createElement( "a" );
+ ajaxLocation.href = "";
+ ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+ // dataTypeExpression is optional and defaults to "*"
+ return function( dataTypeExpression, func ) {
+
+ if ( typeof dataTypeExpression !== "string" ) {
+ func = dataTypeExpression;
+ dataTypeExpression = "*";
+ }
+
+ if ( jQuery.isFunction( func ) ) {
+ var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
+ i = 0,
+ length = dataTypes.length,
+ dataType,
+ list,
+ placeBefore;
+
+ // For each dataType in the dataTypeExpression
+ for(; i < length; i++ ) {
+ dataType = dataTypes[ i ];
+ // We control if we're asked to add before
+ // any existing element
+ placeBefore = /^\+/.test( dataType );
+ if ( placeBefore ) {
+ dataType = dataType.substr( 1 ) || "*";
+ }
+ list = structure[ dataType ] = structure[ dataType ] || [];
+ // then we add to the structure accordingly
+ list[ placeBefore ? "unshift" : "push" ]( func );
+ }
+ }
+ };
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
+ dataType /* internal */, inspected /* internal */ ) {
+
+ dataType = dataType || options.dataTypes[ 0 ];
+ inspected = inspected || {};
+
+ inspected[ dataType ] = true;
+
+ var list = structure[ dataType ],
+ i = 0,
+ length = list ? list.length : 0,
+ executeOnly = ( structure === prefilters ),
+ selection;
+
+ for(; i < length && ( executeOnly || !selection ); i++ ) {
+ selection = list[ i ]( options, originalOptions, jqXHR );
+ // If we got redirected to another dataType
+ // we try there if executing only and not done already
+ if ( typeof selection === "string" ) {
+ if ( !executeOnly || inspected[ selection ] ) {
+ selection = undefined;
+ } else {
+ options.dataTypes.unshift( selection );
+ selection = inspectPrefiltersOrTransports(
+ structure, options, originalOptions, jqXHR, selection, inspected );
+ }
+ }
+ }
+ // If we're only executing or nothing was selected
+ // we try the catchall dataType if not done already
+ if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
+ selection = inspectPrefiltersOrTransports(
+ structure, options, originalOptions, jqXHR, "*", inspected );
+ }
+ // unnecessary when only executing (prefilters)
+ // but it'll be ignored by the caller in that case
+ return selection;
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+ var key, deep,
+ flatOptions = jQuery.ajaxSettings.flatOptions || {};
+ for( key in src ) {
+ if ( src[ key ] !== undefined ) {
+ ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
+ }
+ }
+ if ( deep ) {
+ jQuery.extend( true, target, deep );
+ }
+}
+
+jQuery.fn.extend({
+ load: function( url, params, callback ) {
+ if ( typeof url !== "string" && _load ) {
+ return _load.apply( this, arguments );
+
+ // Don't do a request if no elements are being requested
+ } else if ( !this.length ) {
+ return this;
+ }
+
+ var off = url.indexOf( " " );
+ if ( off >= 0 ) {
+ var selector = url.slice( off, url.length );
+ url = url.slice( 0, off );
+ }
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params ) {
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = undefined;
+
+ // Otherwise, build a param string
+ } else if ( typeof params === "object" ) {
+ params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+ type = "POST";
+ }
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ // Complete callback (responseText is used internally)
+ complete: function( jqXHR, status, responseText ) {
+ // Store the response as specified by the jqXHR object
+ responseText = jqXHR.responseText;
+ // If successful, inject the HTML into all the matched elements
+ if ( jqXHR.isResolved() ) {
+ // #4825: Get the actual response in case
+ // a dataFilter is present in ajaxSettings
+ jqXHR.done(function( r ) {
+ responseText = r;
+ });
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(responseText.replace(rscript, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ responseText );
+ }
+
+ if ( callback ) {
+ self.each( callback, [ responseText, status, jqXHR ] );
+ }
+ }
+ });
+
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param( this.serializeArray() );
+ },
+
+ serializeArray: function() {
+ return this.map(function(){
+ return this.elements ? jQuery.makeArray( this.elements ) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ ( this.checked || rselectTextarea.test( this.nodeName ) ||
+ rinput.test( this.type ) );
+ })
+ .map(function( i, elem ){
+ var val = jQuery( this ).val();
+
+ return val == null ?
+ null :
+ jQuery.isArray( val ) ?
+ jQuery.map( val, function( val, i ){
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }) :
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
+ jQuery.fn[ o ] = function( f ){
+ return this.bind( o, f );
+ };
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+ jQuery[ method ] = function( url, data, callback, type ) {
+ // shift arguments if data argument was omitted
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = undefined;
+ }
+
+ return jQuery.ajax({
+ type: method,
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ };
+});
+
+jQuery.extend({
+
+ getScript: function( url, callback ) {
+ return jQuery.get( url, undefined, callback, "script" );
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get( url, data, callback, "json" );
+ },
+
+ // Creates a full fledged settings object into target
+ // with both ajaxSettings and settings fields.
+ // If target is omitted, writes into ajaxSettings.
+ ajaxSetup: function( target, settings ) {
+ if ( settings ) {
+ // Building a settings object
+ ajaxExtend( target, jQuery.ajaxSettings );
+ } else {
+ // Extending ajaxSettings
+ settings = target;
+ target = jQuery.ajaxSettings;
+ }
+ ajaxExtend( target, settings );
+ return target;
+ },
+
+ ajaxSettings: {
+ url: ajaxLocation,
+ isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+ global: true,
+ type: "GET",
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ /*
+ timeout: 0,
+ data: null,
+ dataType: null,
+ username: null,
+ password: null,
+ cache: null,
+ traditional: false,
+ headers: {},
+ */
+
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ text: "text/plain",
+ json: "application/json, text/javascript",
+ "*": allTypes
+ },
+
+ contents: {
+ xml: /xml/,
+ html: /html/,
+ json: /json/
+ },
+
+ responseFields: {
+ xml: "responseXML",
+ text: "responseText"
+ },
+
+ // List of data converters
+ // 1) key format is "source_type destination_type" (a single space in-between)
+ // 2) the catchall symbol "*" can be used for source_type
+ converters: {
+
+ // Convert anything to text
+ "* text": window.String,
+
+ // Text to html (true = no transformation)
+ "text html": true,
+
+ // Evaluate text as a json expression
+ "text json": jQuery.parseJSON,
+
+ // Parse text as xml
+ "text xml": jQuery.parseXML
+ },
+
+ // For options that shouldn't be deep extended:
+ // you can add your own custom options here if
+ // and when you create one that shouldn't be
+ // deep extended (see ajaxExtend)
+ flatOptions: {
+ context: true,
+ url: true
+ }
+ },
+
+ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+ ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+ // Main method
+ ajax: function( url, options ) {
+
+ // If url is an object, simulate pre-1.5 signature
+ if ( typeof url === "object" ) {
+ options = url;
+ url = undefined;
+ }
+
+ // Force options to be an object
+ options = options || {};
+
+ var // Create the final options object
+ s = jQuery.ajaxSetup( {}, options ),
+ // Callbacks context
+ callbackContext = s.context || s,
+ // Context for global events
+ // It's the callbackContext if one was provided in the options
+ // and if it's a DOM node or a jQuery collection
+ globalEventContext = callbackContext !== s &&
+ ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
+ jQuery( callbackContext ) : jQuery.event,
+ // Deferreds
+ deferred = jQuery.Deferred(),
+ completeDeferred = jQuery._Deferred(),
+ // Status-dependent callbacks
+ statusCode = s.statusCode || {},
+ // ifModified key
+ ifModifiedKey,
+ // Headers (they are sent all at once)
+ requestHeaders = {},
+ requestHeadersNames = {},
+ // Response headers
+ responseHeadersString,
+ responseHeaders,
+ // transport
+ transport,
+ // timeout handle
+ timeoutTimer,
+ // Cross-domain detection vars
+ parts,
+ // The jqXHR state
+ state = 0,
+ // To know if global events are to be dispatched
+ fireGlobals,
+ // Loop variable
+ i,
+ // Fake xhr
+ jqXHR = {
+
+ readyState: 0,
+
+ // Caches the header
+ setRequestHeader: function( name, value ) {
+ if ( !state ) {
+ var lname = name.toLowerCase();
+ name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+ requestHeaders[ name ] = value;
+ }
+ return this;
+ },
+
+ // Raw string
+ getAllResponseHeaders: function() {
+ return state === 2 ? responseHeadersString : null;
+ },
+
+ // Builds headers hashtable if needed
+ getResponseHeader: function( key ) {
+ var match;
+ if ( state === 2 ) {
+ if ( !responseHeaders ) {
+ responseHeaders = {};
+ while( ( match = rheaders.exec( responseHeadersString ) ) ) {
+ responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+ }
+ }
+ match = responseHeaders[ key.toLowerCase() ];
+ }
+ return match === undefined ? null : match;
+ },
+
+ // Overrides response content-type header
+ overrideMimeType: function( type ) {
+ if ( !state ) {
+ s.mimeType = type;
+ }
+ return this;
+ },
+
+ // Cancel the request
+ abort: function( statusText ) {
+ statusText = statusText || "abort";
+ if ( transport ) {
+ transport.abort( statusText );
+ }
+ done( 0, statusText );
+ return this;
+ }
+ };
+
+ // Callback for when everything is done
+ // It is defined here because jslint complains if it is declared
+ // at the end of the function (which would be more logical and readable)
+ function done( status, nativeStatusText, responses, headers ) {
+
+ // Called once
+ if ( state === 2 ) {
+ return;
+ }
+
+ // State is "done" now
+ state = 2;
+
+ // Clear timeout if it exists
+ if ( timeoutTimer ) {
+ clearTimeout( timeoutTimer );
+ }
+
+ // Dereference transport for early garbage collection
+ // (no matter how long the jqXHR object will be used)
+ transport = undefined;
+
+ // Cache response headers
+ responseHeadersString = headers || "";
+
+ // Set readyState
+ jqXHR.readyState = status > 0 ? 4 : 0;
+
+ var isSuccess,
+ success,
+ error,
+ statusText = nativeStatusText,
+ response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
+ lastModified,
+ etag;
+
+ // If successful, handle type chaining
+ if ( status >= 200 && status < 300 || status === 304 ) {
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+
+ if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
+ jQuery.lastModified[ ifModifiedKey ] = lastModified;
+ }
+ if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
+ jQuery.etag[ ifModifiedKey ] = etag;
+ }
+ }
+
+ // If not modified
+ if ( status === 304 ) {
+
+ statusText = "notmodified";
+ isSuccess = true;
+
+ // If we have data
+ } else {
+
+ try {
+ success = ajaxConvert( s, response );
+ statusText = "success";
+ isSuccess = true;
+ } catch(e) {
+ // We have a parsererror
+ statusText = "parsererror";
+ error = e;
+ }
+ }
+ } else {
+ // We extract error from statusText
+ // then normalize statusText and status for non-aborts
+ error = statusText;
+ if( !statusText || status ) {
+ statusText = "error";
+ if ( status < 0 ) {
+ status = 0;
+ }
+ }
+ }
+
+ // Set data for the fake xhr object
+ jqXHR.status = status;
+ jqXHR.statusText = "" + ( nativeStatusText || statusText );
+
+ // Success/Error
+ if ( isSuccess ) {
+ deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+ } else {
+ deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+ }
+
+ // Status-dependent callbacks
+ jqXHR.statusCode( statusCode );
+ statusCode = undefined;
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
+ [ jqXHR, s, isSuccess ? success : error ] );
+ }
+
+ // Complete
+ completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+ // Handle the global AJAX counter
+ if ( !( --jQuery.active ) ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ }
+ }
+
+ // Attach deferreds
+ deferred.promise( jqXHR );
+ jqXHR.success = jqXHR.done;
+ jqXHR.error = jqXHR.fail;
+ jqXHR.complete = completeDeferred.done;
+
+ // Status-dependent callbacks
+ jqXHR.statusCode = function( map ) {
+ if ( map ) {
+ var tmp;
+ if ( state < 2 ) {
+ for( tmp in map ) {
+ statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
+ }
+ } else {
+ tmp = map[ jqXHR.status ];
+ jqXHR.then( tmp, tmp );
+ }
+ }
+ return this;
+ };
+
+ // Remove hash character (#7531: and string promotion)
+ // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+ // We also use the url parameter if available
+ s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+ // Extract dataTypes list
+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
+
+ // Determine if a cross-domain request is in order
+ if ( s.crossDomain == null ) {
+ parts = rurl.exec( s.url.toLowerCase() );
+ s.crossDomain = !!( parts &&
+ ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
+ ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
+ ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
+ );
+ }
+
+ // Convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
+ s.data = jQuery.param( s.data, s.traditional );
+ }
+
+ // Apply prefilters
+ inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+ // If request was aborted inside a prefiler, stop there
+ if ( state === 2 ) {
+ return false;
+ }
+
+ // We can fire global events as of now if asked to
+ fireGlobals = s.global;
+
+ // Uppercase the type
+ s.type = s.type.toUpperCase();
+
+ // Determine if request has content
+ s.hasContent = !rnoContent.test( s.type );
+
+ // Watch for a new set of requests
+ if ( fireGlobals && jQuery.active++ === 0 ) {
+ jQuery.event.trigger( "ajaxStart" );
+ }
+
+ // More options handling for requests with no content
+ if ( !s.hasContent ) {
+
+ // If data is available, append data to url
+ if ( s.data ) {
+ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
+ // #9682: remove data so that it's not used in an eventual retry
+ delete s.data;
+ }
+
+ // Get ifModifiedKey before adding the anti-cache parameter
+ ifModifiedKey = s.url;
+
+ // Add anti-cache in url if needed
+ if ( s.cache === false ) {
+
+ var ts = jQuery.now(),
+ // try replacing _= if it is there
+ ret = s.url.replace( rts, "$1_=" + ts );
+
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
+ }
+ }
+
+ // Set the correct header, if data is being sent
+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+ jqXHR.setRequestHeader( "Content-Type", s.contentType );
+ }
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ ifModifiedKey = ifModifiedKey || s.url;
+ if ( jQuery.lastModified[ ifModifiedKey ] ) {
+ jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
+ }
+ if ( jQuery.etag[ ifModifiedKey ] ) {
+ jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
+ }
+ }
+
+ // Set the Accepts header for the server, depending on the dataType
+ jqXHR.setRequestHeader(
+ "Accept",
+ s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+ s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+ s.accepts[ "*" ]
+ );
+
+ // Check for headers option
+ for ( i in s.headers ) {
+ jqXHR.setRequestHeader( i, s.headers[ i ] );
+ }
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+ // Abort if not done already
+ jqXHR.abort();
+ return false;
+
+ }
+
+ // Install callbacks on deferreds
+ for ( i in { success: 1, error: 1, complete: 1 } ) {
+ jqXHR[ i ]( s[ i ] );
+ }
+
+ // Get transport
+ transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+ // If no transport, we auto-abort
+ if ( !transport ) {
+ done( -1, "No Transport" );
+ } else {
+ jqXHR.readyState = 1;
+ // Send global event
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+ }
+ // Timeout
+ if ( s.async && s.timeout > 0 ) {
+ timeoutTimer = setTimeout( function(){
+ jqXHR.abort( "timeout" );
+ }, s.timeout );
+ }
+
+ try {
+ state = 1;
+ transport.send( requestHeaders, done );
+ } catch (e) {
+ // Propagate exception as error if not done
+ if ( state < 2 ) {
+ done( -1, e );
+ // Simply rethrow otherwise
+ } else {
+ jQuery.error( e );
+ }
+ }
+ }
+
+ return jqXHR;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a, traditional ) {
+ var s = [],
+ add = function( key, value ) {
+ // If value is a function, invoke it and return its value
+ value = jQuery.isFunction( value ) ? value() : value;
+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+ };
+
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
+ if ( traditional === undefined ) {
+ traditional = jQuery.ajaxSettings.traditional;
+ }
+
+ // If an array was passed in, assume that it is an array of form elements.
+ if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+ // Serialize the form elements
+ jQuery.each( a, function() {
+ add( this.name, this.value );
+ });
+
+ } else {
+ // If traditional, encode the "old" way (the way 1.3.2 or older
+ // did it), otherwise encode params recursively.
+ for ( var prefix in a ) {
+ buildParams( prefix, a[ prefix ], traditional, add );
+ }
+ }
+
+ // Return the resulting serialization
+ return s.join( "&" ).replace( r20, "+" );
+ }
+});
+
+function buildParams( prefix, obj, traditional, add ) {
+ if ( jQuery.isArray( obj ) ) {
+ // Serialize array item.
+ jQuery.each( obj, function( i, v ) {
+ if ( traditional || rbracket.test( prefix ) ) {
+ // Treat each array item as a scalar.
+ add( prefix, v );
+
+ } else {
+ // If array item is non-scalar (array or object), encode its
+ // numeric index to resolve deserialization ambiguity issues.
+ // Note that rack (as of 1.0.0) can't currently deserialize
+ // nested arrays properly, and attempting to do so may cause
+ // a server error. Possible fixes are to modify rack's
+ // deserialization algorithm or to provide an option or flag
+ // to force array serialization to be shallow.
+ buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
+ }
+ });
+
+ } else if ( !traditional && obj != null && typeof obj === "object" ) {
+ // Serialize object item.
+ for ( var name in obj ) {
+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+ }
+
+ } else {
+ // Serialize scalar item.
+ add( prefix, obj );
+ }
+}
+
+// This is still on the jQuery object... for now
+// Want to move this to jQuery.ajax some day
+jQuery.extend({
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+ etag: {}
+
+});
+
+/* Handles responses to an ajax request:
+ * - sets all responseXXX fields accordingly
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+
+ var contents = s.contents,
+ dataTypes = s.dataTypes,
+ responseFields = s.responseFields,
+ ct,
+ type,
+ finalDataType,
+ firstDataType;
+
+ // Fill responseXXX fields
+ for( type in responseFields ) {
+ if ( type in responses ) {
+ jqXHR[ responseFields[type] ] = responses[ type ];
+ }
+ }
+
+ // Remove auto dataType and get content-type in the process
+ while( dataTypes[ 0 ] === "*" ) {
+ dataTypes.shift();
+ if ( ct === undefined ) {
+ ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
+ }
+ }
+
+ // Check if we're dealing with a known content-type
+ if ( ct ) {
+ for ( type in contents ) {
+ if ( contents[ type ] && contents[ type ].test( ct ) ) {
+ dataTypes.unshift( type );
+ break;
+ }
+ }
+ }
+
+ // Check to see if we have a response for the expected dataType
+ if ( dataTypes[ 0 ] in responses ) {
+ finalDataType = dataTypes[ 0 ];
+ } else {
+ // Try convertible dataTypes
+ for ( type in responses ) {
+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+ finalDataType = type;
+ break;
+ }
+ if ( !firstDataType ) {
+ firstDataType = type;
+ }
+ }
+ // Or just use first one
+ finalDataType = finalDataType || firstDataType;
+ }
+
+ // If we found a dataType
+ // We add the dataType to the list if needed
+ // and return the corresponding response
+ if ( finalDataType ) {
+ if ( finalDataType !== dataTypes[ 0 ] ) {
+ dataTypes.unshift( finalDataType );
+ }
+ return responses[ finalDataType ];
+ }
+}
+
+// Chain conversions given the request and the original response
+function ajaxConvert( s, response ) {
+
+ // Apply the dataFilter if provided
+ if ( s.dataFilter ) {
+ response = s.dataFilter( response, s.dataType );
+ }
+
+ var dataTypes = s.dataTypes,
+ converters = {},
+ i,
+ key,
+ length = dataTypes.length,
+ tmp,
+ // Current and previous dataTypes
+ current = dataTypes[ 0 ],
+ prev,
+ // Conversion expression
+ conversion,
+ // Conversion function
+ conv,
+ // Conversion functions (transitive conversion)
+ conv1,
+ conv2;
+
+ // For each dataType in the chain
+ for( i = 1; i < length; i++ ) {
+
+ // Create converters map
+ // with lowercased keys
+ if ( i === 1 ) {
+ for( key in s.converters ) {
+ if( typeof key === "string" ) {
+ converters[ key.toLowerCase() ] = s.converters[ key ];
+ }
+ }
+ }
+
+ // Get the dataTypes
+ prev = current;
+ current = dataTypes[ i ];
+
+ // If current is auto dataType, update it to prev
+ if( current === "*" ) {
+ current = prev;
+ // If no auto and dataTypes are actually different
+ } else if ( prev !== "*" && prev !== current ) {
+
+ // Get the converter
+ conversion = prev + " " + current;
+ conv = converters[ conversion ] || converters[ "* " + current ];
+
+ // If there is no direct converter, search transitively
+ if ( !conv ) {
+ conv2 = undefined;
+ for( conv1 in converters ) {
+ tmp = conv1.split( " " );
+ if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
+ conv2 = converters[ tmp[1] + " " + current ];
+ if ( conv2 ) {
+ conv1 = converters[ conv1 ];
+ if ( conv1 === true ) {
+ conv = conv2;
+ } else if ( conv2 === true ) {
+ conv = conv1;
+ }
+ break;
+ }
+ }
+ }
+ }
+ // If we found no converter, dispatch an error
+ if ( !( conv || conv2 ) ) {
+ jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
+ }
+ // If found converter is not an equivalence
+ if ( conv !== true ) {
+ // Convert with 1 or 2 converters accordingly
+ response = conv ? conv( response ) : conv2( conv1(response) );
+ }
+ }
+ }
+ return response;
+}
+
+
+
+
+var jsc = jQuery.now(),
+ jsre = /(\=)\?(&|$)|\?\?/i;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+ jsonp: "callback",
+ jsonpCallback: function() {
+ return jQuery.expando + "_" + ( jsc++ );
+ }
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+ var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
+ ( typeof s.data === "string" );
+
+ if ( s.dataTypes[ 0 ] === "jsonp" ||
+ s.jsonp !== false && ( jsre.test( s.url ) ||
+ inspectData && jsre.test( s.data ) ) ) {
+
+ var responseContainer,
+ jsonpCallback = s.jsonpCallback =
+ jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
+ previous = window[ jsonpCallback ],
+ url = s.url,
+ data = s.data,
+ replace = "$1" + jsonpCallback + "$2";
+
+ if ( s.jsonp !== false ) {
+ url = url.replace( jsre, replace );
+ if ( s.url === url ) {
+ if ( inspectData ) {
+ data = data.replace( jsre, replace );
+ }
+ if ( s.data === data ) {
+ // Add callback manually
+ url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
+ }
+ }
+ }
+
+ s.url = url;
+ s.data = data;
+
+ // Install callback
+ window[ jsonpCallback ] = function( response ) {
+ responseContainer = [ response ];
+ };
+
+ // Clean-up function
+ jqXHR.always(function() {
+ // Set callback back to previous value
+ window[ jsonpCallback ] = previous;
+ // Call if it was a function and we have a response
+ if ( responseContainer && jQuery.isFunction( previous ) ) {
+ window[ jsonpCallback ]( responseContainer[ 0 ] );
+ }
+ });
+
+ // Use data converter to retrieve json after script execution
+ s.converters["script json"] = function() {
+ if ( !responseContainer ) {
+ jQuery.error( jsonpCallback + " was not called" );
+ }
+ return responseContainer[ 0 ];
+ };
+
+ // force json dataType
+ s.dataTypes[ 0 ] = "json";
+
+ // Delegate to script
+ return "script";
+ }
+});
+
+
+
+
+// Install script dataType
+jQuery.ajaxSetup({
+ accepts: {
+ script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+ },
+ contents: {
+ script: /javascript|ecmascript/
+ },
+ converters: {
+ "text script": function( text ) {
+ jQuery.globalEval( text );
+ return text;
+ }
+ }
+});
+
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+ if ( s.cache === undefined ) {
+ s.cache = false;
+ }
+ if ( s.crossDomain ) {
+ s.type = "GET";
+ s.global = false;
+ }
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+ // This transport only deals with cross domain requests
+ if ( s.crossDomain ) {
+
+ var script,
+ head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
+
+ return {
+
+ send: function( _, callback ) {
+
+ script = document.createElement( "script" );
+
+ script.async = "async";
+
+ if ( s.scriptCharset ) {
+ script.charset = s.scriptCharset;
+ }
+
+ script.src = s.url;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+ if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+
+ // Remove the script
+ if ( head && script.parentNode ) {
+ head.removeChild( script );
+ }
+
+ // Dereference the script
+ script = undefined;
+
+ // Callback if not abort
+ if ( !isAbort ) {
+ callback( 200, "success" );
+ }
+ }
+ };
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709 and #4378).
+ head.insertBefore( script, head.firstChild );
+ },
+
+ abort: function() {
+ if ( script ) {
+ script.onload( 0, 1 );
+ }
+ }
+ };
+ }
+});
+
+
+
+
+var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
+ xhrOnUnloadAbort = window.ActiveXObject ? function() {
+ // Abort all pending requests
+ for ( var key in xhrCallbacks ) {
+ xhrCallbacks[ key ]( 0, 1 );
+ }
+ } : false,
+ xhrId = 0,
+ xhrCallbacks;
+
+// Functions to create xhrs
+function createStandardXHR() {
+ try {
+ return new window.XMLHttpRequest();
+ } catch( e ) {}
+}
+
+function createActiveXHR() {
+ try {
+ return new window.ActiveXObject( "Microsoft.XMLHTTP" );
+ } catch( e ) {}
+}
+
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+ /* Microsoft failed to properly
+ * implement the XMLHttpRequest in IE7 (can't request local files),
+ * so we use the ActiveXObject when it is available
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+ * we need a fallback.
+ */
+ function() {
+ return !this.isLocal && createStandardXHR() || createActiveXHR();
+ } :
+ // For all other browsers, use the standard XMLHttpRequest object
+ createStandardXHR;
+
+// Determine support properties
+(function( xhr ) {
+ jQuery.extend( jQuery.support, {
+ ajax: !!xhr,
+ cors: !!xhr && ( "withCredentials" in xhr )
+ });
+})( jQuery.ajaxSettings.xhr() );
+
+// Create transport if the browser can provide an xhr
+if ( jQuery.support.ajax ) {
+
+ jQuery.ajaxTransport(function( s ) {
+ // Cross domain only allowed if supported through XMLHttpRequest
+ if ( !s.crossDomain || jQuery.support.cors ) {
+
+ var callback;
+
+ return {
+ send: function( headers, complete ) {
+
+ // Get a new xhr
+ var xhr = s.xhr(),
+ handle,
+ i;
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if ( s.username ) {
+ xhr.open( s.type, s.url, s.async, s.username, s.password );
+ } else {
+ xhr.open( s.type, s.url, s.async );
+ }
+
+ // Apply custom fields if provided
+ if ( s.xhrFields ) {
+ for ( i in s.xhrFields ) {
+ xhr[ i ] = s.xhrFields[ i ];
+ }
+ }
+
+ // Override mime type if needed
+ if ( s.mimeType && xhr.overrideMimeType ) {
+ xhr.overrideMimeType( s.mimeType );
+ }
+
+ // X-Requested-With header
+ // For cross-domain requests, seeing as conditions for a preflight are
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
+ // (it can always be set on a per-request basis or even using ajaxSetup)
+ // For same-domain requests, won't change header if already provided.
+ if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+ headers[ "X-Requested-With" ] = "XMLHttpRequest";
+ }
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ for ( i in headers ) {
+ xhr.setRequestHeader( i, headers[ i ] );
+ }
+ } catch( _ ) {}
+
+ // Do send the request
+ // This may raise an exception which is actually
+ // handled in jQuery.ajax (so no try/catch here)
+ xhr.send( ( s.hasContent && s.data ) || null );
+
+ // Listener
+ callback = function( _, isAbort ) {
+
+ var status,
+ statusText,
+ responseHeaders,
+ responses,
+ xml;
+
+ // Firefox throws exceptions when accessing properties
+ // of an xhr when a network error occured
+ // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+ try {
+
+ // Was never called and is aborted or complete
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+ // Only called once
+ callback = undefined;
+
+ // Do not keep as active anymore
+ if ( handle ) {
+ xhr.onreadystatechange = jQuery.noop;
+ if ( xhrOnUnloadAbort ) {
+ delete xhrCallbacks[ handle ];
+ }
+ }
+
+ // If it's an abort
+ if ( isAbort ) {
+ // Abort it manually if needed
+ if ( xhr.readyState !== 4 ) {
+ xhr.abort();
+ }
+ } else {
+ status = xhr.status;
+ responseHeaders = xhr.getAllResponseHeaders();
+ responses = {};
+ xml = xhr.responseXML;
+
+ // Construct response list
+ if ( xml && xml.documentElement /* #4958 */ ) {
+ responses.xml = xml;
+ }
+ responses.text = xhr.responseText;
+
+ // Firefox throws an exception when accessing
+ // statusText for faulty cross-domain requests
+ try {
+ statusText = xhr.statusText;
+ } catch( e ) {
+ // We normalize with Webkit giving an empty statusText
+ statusText = "";
+ }
+
+ // Filter status for non standard behaviors
+
+ // If the request is local and we have data: assume a success
+ // (success with no data won't get notified, that's the best we
+ // can do given current implementations)
+ if ( !status && s.isLocal && !s.crossDomain ) {
+ status = responses.text ? 200 : 404;
+ // IE - #1450: sometimes returns 1223 when it should be 204
+ } else if ( status === 1223 ) {
+ status = 204;
+ }
+ }
+ }
+ } catch( firefoxAccessException ) {
+ if ( !isAbort ) {
+ complete( -1, firefoxAccessException );
+ }
+ }
+
+ // Call complete if needed
+ if ( responses ) {
+ complete( status, statusText, responses, responseHeaders );
+ }
+ };
+
+ // if we're in sync mode or it's in cache
+ // and has been retrieved directly (IE6 & IE7)
+ // we need to manually fire the callback
+ if ( !s.async || xhr.readyState === 4 ) {
+ callback();
+ } else {
+ handle = ++xhrId;
+ if ( xhrOnUnloadAbort ) {
+ // Create the active xhrs callbacks list if needed
+ // and attach the unload handler
+ if ( !xhrCallbacks ) {
+ xhrCallbacks = {};
+ jQuery( window ).unload( xhrOnUnloadAbort );
+ }
+ // Add to list of active xhrs callbacks
+ xhrCallbacks[ handle ] = callback;
+ }
+ xhr.onreadystatechange = callback;
+ }
+ },
+
+ abort: function() {
+ if ( callback ) {
+ callback(0,1);
+ }
+ }
+ };
+ }
+ });
+}
+
+
+
+
+var elemdisplay = {},
+ iframe, iframeDoc,
+ rfxtypes = /^(?:toggle|show|hide)$/,
+ rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
+ timerId,
+ fxAttrs = [
+ // height animations
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+ // width animations
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+ // opacity animations
+ [ "opacity" ]
+ ],
+ fxNow;
+
+jQuery.fn.extend({
+ show: function( speed, easing, callback ) {
+ var elem, display;
+
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("show", 3), speed, easing, callback);
+
+ } else {
+ for ( var i = 0, j = this.length; i < j; i++ ) {
+ elem = this[i];
+
+ if ( elem.style ) {
+ display = elem.style.display;
+
+ // Reset the inline display of this element to learn if it is
+ // being hidden by cascaded rules or not
+ if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
+ display = elem.style.display = "";
+ }
+
+ // Set elements which have been overridden with display: none
+ // in a stylesheet to whatever the default browser style is
+ // for such an element
+ if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
+ jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
+ }
+ }
+ }
+
+ // Set the display of most of the elements in a second loop
+ // to avoid the constant reflow
+ for ( i = 0; i < j; i++ ) {
+ elem = this[i];
+
+ if ( elem.style ) {
+ display = elem.style.display;
+
+ if ( display === "" || display === "none" ) {
+ elem.style.display = jQuery._data(elem, "olddisplay") || "";
+ }
+ }
+ }
+
+ return this;
+ }
+ },
+
+ hide: function( speed, easing, callback ) {
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("hide", 3), speed, easing, callback);
+
+ } else {
+ for ( var i = 0, j = this.length; i < j; i++ ) {
+ if ( this[i].style ) {
+ var display = jQuery.css( this[i], "display" );
+
+ if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
+ jQuery._data( this[i], "olddisplay", display );
+ }
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( i = 0; i < j; i++ ) {
+ if ( this[i].style ) {
+ this[i].style.display = "none";
+ }
+ }
+
+ return this;
+ }
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2, callback ) {
+ var bool = typeof fn === "boolean";
+
+ if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+ this._toggle.apply( this, arguments );
+
+ } else if ( fn == null || bool ) {
+ this.each(function() {
+ var state = bool ? fn : jQuery(this).is(":hidden");
+ jQuery(this)[ state ? "show" : "hide" ]();
+ });
+
+ } else {
+ this.animate(genFx("toggle", 3), fn, fn2, callback);
+ }
+
+ return this;
+ },
+
+ fadeTo: function( speed, to, easing, callback ) {
+ return this.filter(":hidden").css("opacity", 0).show().end()
+ .animate({opacity: to}, speed, easing, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ if ( jQuery.isEmptyObject( prop ) ) {
+ return this.each( optall.complete, [ false ] );
+ }
+
+ // Do not change referenced properties as per-property easing will be lost
+ prop = jQuery.extend( {}, prop );
+
+ return this[ optall.queue === false ? "each" : "queue" ](function() {
+ // XXX 'this' does not always have a nodeName when running the
+ // test suite
+
+ if ( optall.queue === false ) {
+ jQuery._mark( this );
+ }
+
+ var opt = jQuery.extend( {}, optall ),
+ isElement = this.nodeType === 1,
+ hidden = isElement && jQuery(this).is(":hidden"),
+ name, val, p,
+ display, e,
+ parts, start, end, unit;
+
+ // will store per property easing and be used to determine when an animation is complete
+ opt.animatedProperties = {};
+
+ for ( p in prop ) {
+
+ // property name normalization
+ name = jQuery.camelCase( p );
+ if ( p !== name ) {
+ prop[ name ] = prop[ p ];
+ delete prop[ p ];
+ }
+
+ val = prop[ name ];
+
+ // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
+ if ( jQuery.isArray( val ) ) {
+ opt.animatedProperties[ name ] = val[ 1 ];
+ val = prop[ name ] = val[ 0 ];
+ } else {
+ opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
+ }
+
+ if ( val === "hide" && hidden || val === "show" && !hidden ) {
+ return opt.complete.call( this );
+ }
+
+ if ( isElement && ( name === "height" || name === "width" ) ) {
+ // Make sure that nothing sneaks out
+ // Record all 3 overflow attributes because IE does not
+ // change the overflow attribute when overflowX and
+ // overflowY are set to the same value
+ opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
+
+ // Set display property to inline-block for height/width
+ // animations on inline elements that are having width/height
+ // animated
+ if ( jQuery.css( this, "display" ) === "inline" &&
+ jQuery.css( this, "float" ) === "none" ) {
+ if ( !jQuery.support.inlineBlockNeedsLayout ) {
+ this.style.display = "inline-block";
+
+ } else {
+ display = defaultDisplay( this.nodeName );
+
+ // inline-level elements accept inline-block;
+ // block-level elements need to be inline with layout
+ if ( display === "inline" ) {
+ this.style.display = "inline-block";
+
+ } else {
+ this.style.display = "inline";
+ this.style.zoom = 1;
+ }
+ }
+ }
+ }
+ }
+
+ if ( opt.overflow != null ) {
+ this.style.overflow = "hidden";
+ }
+
+ for ( p in prop ) {
+ e = new jQuery.fx( this, opt, p );
+ val = prop[ p ];
+
+ if ( rfxtypes.test(val) ) {
+ e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
+
+ } else {
+ parts = rfxnum.exec( val );
+ start = e.cur();
+
+ if ( parts ) {
+ end = parseFloat( parts[2] );
+ unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
+
+ // We need to compute starting value
+ if ( unit !== "px" ) {
+ jQuery.style( this, p, (end || 1) + unit);
+ start = ((end || 1) / e.cur()) * start;
+ jQuery.style( this, p, start + unit);
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] ) {
+ end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
+ }
+
+ e.custom( start, end, unit );
+
+ } else {
+ e.custom( start, val, "" );
+ }
+ }
+ }
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ stop: function( clearQueue, gotoEnd ) {
+ if ( clearQueue ) {
+ this.queue([]);
+ }
+
+ this.each(function() {
+ var timers = jQuery.timers,
+ i = timers.length;
+ // clear marker counters if we know they won't be
+ if ( !gotoEnd ) {
+ jQuery._unmark( true, this );
+ }
+ while ( i-- ) {
+ if ( timers[i].elem === this ) {
+ if (gotoEnd) {
+ // force the next step to be the last
+ timers[i](true);
+ }
+
+ timers.splice(i, 1);
+ }
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if ( !gotoEnd ) {
+ this.dequeue();
+ }
+
+ return this;
+ }
+
+});
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+ setTimeout( clearFxNow, 0 );
+ return ( fxNow = jQuery.now() );
+}
+
+function clearFxNow() {
+ fxNow = undefined;
+}
+
+// Generate parameters to create a standard animation
+function genFx( type, num ) {
+ var obj = {};
+
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
+ obj[ this ] = type;
+ });
+
+ return obj;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show", 1),
+ slideUp: genFx("hide", 1),
+ slideToggle: genFx("toggle", 1),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" },
+ fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
+ return this.animate( props, speed, easing, callback );
+ };
+});
+
+jQuery.extend({
+ speed: function( speed, easing, fn ) {
+ var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function( noUnmark ) {
+ if ( jQuery.isFunction( opt.old ) ) {
+ opt.old.call( this );
+ }
+
+ if ( opt.queue !== false ) {
+ jQuery.dequeue( this );
+ } else if ( noUnmark !== false ) {
+ jQuery._unmark( this );
+ }
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ) {
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ options.orig = options.orig || {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+ // Simple function for setting a style value
+ update: function() {
+ if ( this.options.step ) {
+ this.options.step.call( this.elem, this.now, this );
+ }
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+ },
+
+ // Get the current size
+ cur: function() {
+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
+ return this.elem[ this.prop ];
+ }
+
+ var parsed,
+ r = jQuery.css( this.elem, this.prop );
+ // Empty strings, null, undefined and "auto" are converted to 0,
+ // complex values such as "rotate(1rad)" are returned as is,
+ // simple values such as "10px" are parsed to Float.
+ return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
+ },
+
+ // Start an animation from one number to another
+ custom: function( from, to, unit ) {
+ var self = this,
+ fx = jQuery.fx;
+
+ this.startTime = fxNow || createFxNow();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
+ this.now = this.start;
+ this.pos = this.state = 0;
+
+ function t( gotoEnd ) {
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
+ timerId = setInterval( fx.tick, fx.interval );
+ }
+ },
+
+ // Simple 'show' function
+ show: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
+
+ // Start by showing the element
+ jQuery( this.elem ).show();
+ },
+
+ // Simple 'hide' function
+ hide: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function( gotoEnd ) {
+ var t = fxNow || createFxNow(),
+ done = true,
+ elem = this.elem,
+ options = this.options,
+ i, n;
+
+ if ( gotoEnd || t >= options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ options.animatedProperties[ this.prop ] = true;
+
+ for ( i in options.animatedProperties ) {
+ if ( options.animatedProperties[i] !== true ) {
+ done = false;
+ }
+ }
+
+ if ( done ) {
+ // Reset the overflow
+ if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
+
+ jQuery.each( [ "", "X", "Y" ], function (index, value) {
+ elem.style[ "overflow" + value ] = options.overflow[index];
+ });
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( options.hide ) {
+ jQuery(elem).hide();
+ }
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( options.hide || options.show ) {
+ for ( var p in options.animatedProperties ) {
+ jQuery.style( elem, p, options.orig[p] );
+ }
+ }
+
+ // Execute the complete function
+ options.complete.call( elem );
+ }
+
+ return false;
+
+ } else {
+ // classical easing cannot be used with an Infinity duration
+ if ( options.duration == Infinity ) {
+ this.now = t;
+ } else {
+ n = t - this.startTime;
+ this.state = n / options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
+ this.now = this.start + ((this.end - this.start) * this.pos);
+ }
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+};
+
+jQuery.extend( jQuery.fx, {
+ tick: function() {
+ for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
+ if ( !timers[i]() ) {
+ timers.splice(i--, 1);
+ }
+ }
+
+ if ( !timers.length ) {
+ jQuery.fx.stop();
+ }
+ },
+
+ interval: 13,
+
+ stop: function() {
+ clearInterval( timerId );
+ timerId = null;
+ },
+
+ speeds: {
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+ },
+
+ step: {
+ opacity: function( fx ) {
+ jQuery.style( fx.elem, "opacity", fx.now );
+ },
+
+ _default: function( fx ) {
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+ fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
+ } else {
+ fx.elem[ fx.prop ] = fx.now;
+ }
+ }
+ }
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+ };
+}
+
+// Try to restore the default display value of an element
+function defaultDisplay( nodeName ) {
+
+ if ( !elemdisplay[ nodeName ] ) {
+
+ var body = document.body,
+ elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
+ display = elem.css( "display" );
+
+ elem.remove();
+
+ // If the simple way fails,
+ // get element's real default display by attaching it to a temp iframe
+ if ( display === "none" || display === "" ) {
+ // No iframe to use yet, so create it
+ if ( !iframe ) {
+ iframe = document.createElement( "iframe" );
+ iframe.frameBorder = iframe.width = iframe.height = 0;
+ }
+
+ body.appendChild( iframe );
+
+ // Create a cacheable copy of the iframe document on first call.
+ // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
+ // document to it; WebKit & Firefox won't allow reusing the iframe document.
+ if ( !iframeDoc || !iframe.createElement ) {
+ iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
+ iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" );
+ iframeDoc.close();
+ }
+
+ elem = iframeDoc.createElement( nodeName );
+
+ iframeDoc.body.appendChild( elem );
+
+ display = jQuery.css( elem, "display" );
+
+ body.removeChild( iframe );
+ }
+
+ // Store the correct default display
+ elemdisplay[ nodeName ] = display;
+ }
+
+ return elemdisplay[ nodeName ];
+}
+
+
+
+
+var rtable = /^t(?:able|d|h)$/i,
+ rroot = /^(?:body|html)$/i;
+
+if ( "getBoundingClientRect" in document.documentElement ) {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0], box;
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ try {
+ box = elem.getBoundingClientRect();
+ } catch(e) {}
+
+ var doc = elem.ownerDocument,
+ docElem = doc.documentElement;
+
+ // Make sure we're not dealing with a disconnected DOM node
+ if ( !box || !jQuery.contains( docElem, elem ) ) {
+ return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
+ }
+
+ var body = doc.body,
+ win = getWindow(doc),
+ clientTop = docElem.clientTop || body.clientTop || 0,
+ clientLeft = docElem.clientLeft || body.clientLeft || 0,
+ scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
+ scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
+ top = box.top + scrollTop - clientTop,
+ left = box.left + scrollLeft - clientLeft;
+
+ return { top: top, left: left };
+ };
+
+} else {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0];
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ jQuery.offset.initialize();
+
+ var computedStyle,
+ offsetParent = elem.offsetParent,
+ prevOffsetParent = elem,
+ doc = elem.ownerDocument,
+ docElem = doc.documentElement,
+ body = doc.body,
+ defaultView = doc.defaultView,
+ prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+ top = elem.offsetTop,
+ left = elem.offsetLeft;
+
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ break;
+ }
+
+ computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+ top -= elem.scrollTop;
+ left -= elem.scrollLeft;
+
+ if ( elem === offsetParent ) {
+ top += elem.offsetTop;
+ left += elem.offsetLeft;
+
+ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevOffsetParent = offsetParent;
+ offsetParent = elem.offsetParent;
+ }
+
+ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevComputedStyle = computedStyle;
+ }
+
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+ top += body.offsetTop;
+ left += body.offsetLeft;
+ }
+
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ top += Math.max( docElem.scrollTop, body.scrollTop );
+ left += Math.max( docElem.scrollLeft, body.scrollLeft );
+ }
+
+ return { top: top, left: left };
+ };
+}
+
+jQuery.offset = {
+ initialize: function() {
+ var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
+ html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+
+ jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
+
+ container.innerHTML = html;
+ body.insertBefore( container, body.firstChild );
+ innerDiv = container.firstChild;
+ checkDiv = innerDiv.firstChild;
+ td = innerDiv.nextSibling.firstChild.firstChild;
+
+ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+ checkDiv.style.position = "fixed";
+ checkDiv.style.top = "20px";
+
+ // safari subtracts parent border width here which is 5px
+ this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
+ checkDiv.style.position = checkDiv.style.top = "";
+
+ innerDiv.style.overflow = "hidden";
+ innerDiv.style.position = "relative";
+
+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
+
+ body.removeChild( container );
+ jQuery.offset.initialize = jQuery.noop;
+ },
+
+ bodyOffset: function( body ) {
+ var top = body.offsetTop,
+ left = body.offsetLeft;
+
+ jQuery.offset.initialize();
+
+ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
+ top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
+ left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
+ }
+
+ return { top: top, left: left };
+ },
+
+ setOffset: function( elem, options, i ) {
+ var position = jQuery.css( elem, "position" );
+
+ // set position first, in-case top/left are set even on static elem
+ if ( position === "static" ) {
+ elem.style.position = "relative";
+ }
+
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curCSSTop = jQuery.css( elem, "top" ),
+ curCSSLeft = jQuery.css( elem, "left" ),
+ calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
+ props = {}, curPosition = {}, curTop, curLeft;
+
+ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+ if ( calculatePosition ) {
+ curPosition = curElem.position();
+ curTop = curPosition.top;
+ curLeft = curPosition.left;
+ } else {
+ curTop = parseFloat( curCSSTop ) || 0;
+ curLeft = parseFloat( curCSSLeft ) || 0;
+ }
+
+ if ( jQuery.isFunction( options ) ) {
+ options = options.call( elem, i, curOffset );
+ }
+
+ if (options.top != null) {
+ props.top = (options.top - curOffset.top) + curTop;
+ }
+ if (options.left != null) {
+ props.left = (options.left - curOffset.left) + curLeft;
+ }
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+
+jQuery.fn.extend({
+ position: function() {
+ if ( !this[0] ) {
+ return null;
+ }
+
+ var elem = this[0],
+
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent(),
+
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
+ offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
+
+ // Add offsetParent borders
+ parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
+ parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
+
+ // Subtract the two offsets
+ return {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ },
+
+ offsetParent: function() {
+ return this.map(function() {
+ var offsetParent = this.offsetParent || document.body;
+ while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent;
+ });
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+ var method = "scroll" + name;
+
+ jQuery.fn[ method ] = function( val ) {
+ var elem, win;
+
+ if ( val === undefined ) {
+ elem = this[ 0 ];
+
+ if ( !elem ) {
+ return null;
+ }
+
+ win = getWindow( elem );
+
+ // Return the scroll offset
+ return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+ jQuery.support.boxModel && win.document.documentElement[ method ] ||
+ win.document.body[ method ] :
+ elem[ method ];
+ }
+
+ // Set the scroll offset
+ return this.each(function() {
+ win = getWindow( this );
+
+ if ( win ) {
+ win.scrollTo(
+ !i ? val : jQuery( win ).scrollLeft(),
+ i ? val : jQuery( win ).scrollTop()
+ );
+
+ } else {
+ this[ method ] = val;
+ }
+ });
+ };
+});
+
+function getWindow( elem ) {
+ return jQuery.isWindow( elem ) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
+}
+
+
+
+
+// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function( i, name ) {
+
+ var type = name.toLowerCase();
+
+ // innerHeight and innerWidth
+ jQuery.fn[ "inner" + name ] = function() {
+ var elem = this[0];
+ return elem && elem.style ?
+ parseFloat( jQuery.css( elem, type, "padding" ) ) :
+ null;
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn[ "outer" + name ] = function( margin ) {
+ var elem = this[0];
+ return elem && elem.style ?
+ parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
+ null;
+ };
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ var elem = this[0];
+ if ( !elem ) {
+ return size == null ? null : this;
+ }
+
+ if ( jQuery.isFunction( size ) ) {
+ return this.each(function( i ) {
+ var self = jQuery( this );
+ self[ type ]( size.call( this, i, self[ type ]() ) );
+ });
+ }
+
+ if ( jQuery.isWindow( elem ) ) {
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
+ var docElemProp = elem.document.documentElement[ "client" + name ],
+ body = elem.document.body;
+ return elem.document.compatMode === "CSS1Compat" && docElemProp ||
+ body && body[ "client" + name ] || docElemProp;
+
+ // Get document width or height
+ } else if ( elem.nodeType === 9 ) {
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ return Math.max(
+ elem.documentElement["client" + name],
+ elem.body["scroll" + name], elem.documentElement["scroll" + name],
+ elem.body["offset" + name], elem.documentElement["offset" + name]
+ );
+
+ // Get or set width or height on the element
+ } else if ( size === undefined ) {
+ var orig = jQuery.css( elem, type ),
+ ret = parseFloat( orig );
+
+ return jQuery.isNaN( ret ) ? orig : ret;
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ } else {
+ return this.css( type, typeof size === "string" ? size : size + "px" );
+ }
+ };
+
+});
+
+
+// Expose jQuery to the global object
+window.jQuery = window.$ = jQuery;
+})(window); \ No newline at end of file
diff --git a/lib/scripts/jquery/jquery.min.js b/lib/scripts/jquery/jquery.min.js
new file mode 100644
index 000000000..3684c36b5
--- /dev/null
+++ b/lib/scripts/jquery/jquery.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.6.4 http://jquery.com/ | http://jquery.org/license */
+(function(a,b){function cu(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cr(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cq(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cp(){cn=b}function co(){setTimeout(cp,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function bZ(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function bY(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bA.test(a)?d(a,e):bY(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)bY(a+"["+e+"]",b[e],c,d);else d(a,b)}function bX(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bW(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bP,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bW(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bW(a,c,d,e,"*",g));return l}function bV(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bL),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function by(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bt:bu;if(d>0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bv(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bd,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bk(a){f.nodeName(a,"input")?bj(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bj)}function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bh(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bg(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)f.event.add(b,h+(g[h][i].namespace?".":"")+g[h][i].namespace,g[h][i],g[h][i].data)}}}}function bf(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function V(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(Q.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function U(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function M(a,b){return(a&&a!=="*"?a+".":"")+b.replace(y,"`").replace(z,"&")}function L(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;i<s.length;i++)g=s[i],g.origType.replace(w,"")===a.type?q.push(g.selector):s.splice(i--,1);e=f(a.target).closest(q,a.currentTarget);for(j=0,k=e.length;j<k;j++){m=e[j];for(i=0;i<s.length;i++){g=s[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,d=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,d=f(a.relatedTarget).closest(g.selector)[0],d&&f.contains(h,d)&&(d=h);(!d||d!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){e=p[j];if(c&&e.level>c)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function J(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function D(){return!0}function C(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function K(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(K,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.4",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;B.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:H?function(a){return a==null?"":H.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?F.call(c,a):e.merge(c,a)}return c},inArray:function(a,b){if(!b)return-1;if(I)return I.call(b,a);for(var c=0,d=b.length;c<d;c++)if(b[c]===a)return c;return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=G.call(arguments,2),g=function(){return a.apply(c,f.concat(G.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=s.exec(a)||t.exec(a)||u.exec(a)||a.indexOf("compatible")<0&&v.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){J["[object "+b+"]"]=b.toLowerCase()}),A=e.uaMatch(z),A.browser&&(e.browser[A.browser]=!0,e.browser.version=A.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?C=function(){c.removeEventListener("DOMContentLoaded",C,!1),e.ready()}:c.attachEvent&&(C=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",C),e.ready())});return e}(),g="done fail isResolved isRejected promise then always pipe".split(" "),h=[].slice;f.extend({_Deferred:function(){var a=[],b,c,d,e={done:function(){if(!d){var c=arguments,g,h,i,j,k;b&&(k=b,b=0);for(g=0,h=c.length;g<h;g++)i=c[g],j=f.type(i),j==="array"?e.done.apply(e,i):j==="function"&&a.push(i);k&&e.resolveWith(k[0],k[1])}return this},resolveWith:function(e,f){if(!d&&!b&&!c){f=f||[],c=1;try{while(a[0])a.shift().apply(e,f)}finally{b=[e,f],c=0}}return this},resolve:function(){e.resolveWith(this,arguments);return this},isResolved:function(){return!!c||!!b},cancel:function(){d=1,a=[];return this}};return e},Deferred:function(a){var b=f._Deferred(),c=f._Deferred(),d;f.extend(b,{then:function(a,c){b.done(a).fail(c);return this},always:function(){return b.done.apply(b,arguments).fail.apply(this,arguments)},fail:c.done,rejectWith:c.resolveWith,reject:c.resolve,isRejected:c.isResolved,pipe:function(a,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[c,"reject"]},function(a,c){var e=c[0],g=c[1],h;f.isFunction(e)?b[a](function(){h=e.apply(this,arguments),h&&f.isFunction(h.promise)?h.promise().then(d.resolve,d.reject):d[g+"With"](this===b?d:this,[h])}):b[a](d[g])})}).promise()},promise:function(a){if(a==null){if(d)return d;d=a={}}var c=g.length;while(c--)a[g[c]]=b[g[c]];return a}}),b.done(c.cancel).fail(b.cancel),delete b.cancel,a&&a.call(b,b);return b},when:function(a){function i(a){return function(c){b[a]=arguments.length>1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c<d;c++)b[c]&&f.isFunction(b[c].promise)?b[c].promise().then(i(c),g.reject):--e;e||g.resolveWith(g,b)}else g!==a&&g.resolveWith(g,d?[a]:[]);return g.promise()}}),f.support=function(){var a=c.createElement("div"),b=c.documentElement,d,e,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;a.setAttribute("className","t"),a.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-1000px",top:"-1000px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i=f.expando,j=typeof c=="string",k=a.nodeType,l=k?f.cache:a,m=k?a[f.expando]:a[f.expando]&&f.expando;if((!m||e&&m&&l[m]&&!l[m][i])&&j&&d===b)return;m||(k?a[f.expando]=m=++f.uuid:m=f.expando),l[m]||(l[m]={},k||(l[m].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?l[m][i]=f.extend(l[m][i],c):l[m]=f.extend(l[m],c);g=l[m],e&&(g[i]||(g[i]={}),g=g[i]),d!==b&&(g[f.camelCase(c)]=d);if(c==="events"&&!g[c])return g[i]&&g[i].events;j?(h=g[c],h==null&&(h=g[f.camelCase(c)])):h=g;return h}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e=f.expando,g=a.nodeType,h=g?f.cache:a,i=g?a[f.expando]:f.expando;if(!h[i])return;if(b){d=c?h[i][e]:h[i];if(d){d[b]||(b=f.camelCase(b)),delete d[b];if(!l(d))return}}if(c){delete h[i][e];if(!l(h[i]))return}var j=h[i][e];f.support.deleteExpando||!h.setInterval?delete h[i]:h[i]=null,j?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=j):g&&(f.support.deleteExpando?delete a[f.expando]:a.removeAttribute?a.removeAttribute(f.expando):a[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h<i;h++)g=e[h].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),k(this[0],g,d[g]))}}return d}if(typeof a=="object")return this.each(function(){f.data(this,a)});var j=a.split(".");j[1]=j[1]?"."+j[1]:"";if(c===b){d=this.triggerHandler("getData"+j[1]+"!",[j[0]]),d===b&&this.length&&(d=f.data(this[0],a),d=k(this[0],a,d));return d===b&&j[1]?this.data(j[0]):d}return this.each(function(){var b=f(this),d=[j[0],c];b.triggerHandler("setData"+j[1]+"!",d),f.data(this,a,c),b.triggerHandler("changeData"+j[1]+"!",d)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,c){a&&(c=(c||"fx")+"mark",f.data(a,c,(f.data(a,c,b,!0)||0)+1,!0))},_unmark:function(a,c,d){a!==!0&&(d=c,c=a,a=!1);if(c){d=d||"fx";var e=d+"mark",g=a?0:(f.data(c,e,b,!0)||1)-1;g?f.data(c,e,g,!0):(f.removeData(c,e,!0),m(c,d,"mark"))}},queue:function(a,c,d){if(a){c=(c||"fx")+"queue";var e=f.data(a,c,b,!0);d&&(!e||f.isArray(d)?e=f.data(a,c,f.makeArray(d),!0):e.push(d));return e||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e;d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),d.call(a,function(){f.dequeue(a,b)})),c.length||(f.removeData(a,b+"queue",!0),m(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(){var c=this;setTimeout(function(){f.dequeue(c,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f._Deferred(),!0))h++,l.done(m);m();return d.promise()}});var n=/[\n\t\r]/g,o=/\s+/,p=/\r/g,q=/^(?:button|input)$/i,r=/^(?:button|input|object|select|textarea)$/i,s=/^a(?:rea)?$/i,t=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,u,v;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(o);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(o);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(n," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(o);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ";for(var c=0,d=this.length;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(n," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h<i;h++){var j=e[h];if(j.selected&&(f.support.optDisabled?!j.disabled:j.getAttribute("disabled")===null)&&(!j.parentNode.disabled||!f.nodeName(j.parentNode,"optgroup"))){b=f(j).val();if(g)return b;d.push(b)}}if(g&&!d.length&&e.length)return f(e[c]).val();return d},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=v:u&&(i=u)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.attr(a,b,""),a.removeAttribute(b),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(u&&f.nodeName(a,"button"))return u.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(u&&f.nodeName(a,"button"))return u.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==null?g:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabIndex=f.propHooks.tabIndex,v={get:function(a,c){var d;return f.prop(a,c)===!0||(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(u=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var w=/\.(.*)$/,x=/^(?:textarea|input|select)$/i,y=/\./g,z=/ /g,A=/[^\w\s.|`]/g,B=function(a){return a.replace(A,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=C;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=C);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),B).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j<p.length;j++){q=p[j];if(l||n.test(q.namespace))f.event.remove(a,r,q.handler,j),p.splice(j--,1)}continue}o=f.event.special[h]||{};for(j=e||0;j<p.length;j++){q=p[j];if(d.guid===q.guid){if(l||n.test(q.namespace))e==null&&p.splice(j--,1),o.remove&&o.remove.call(a,q);if(e!=null)break}}if(p.length===0||e!=null&&p.length===1)(!o.teardown||o.teardown.call(a,m)===!1)&&f.removeEvent(a,h,s.handle),g=null,delete
+t[h]}if(f.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,f.isEmptyObject(s)&&f.removeData(a,b,!0)}}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){var h=c.type||c,i=[],j;h.indexOf("!")>=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h<i;h++){var j=d[h];if(e||c.namespace_re.test(j.namespace)){c.handler=j.handler,c.data=j.data,c.handleObj=j;var k=j.handler.apply(this,g);k!==b&&(c.result=k,k===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[f.expando])return a;var d=a;a=f.Event(d);for(var e=this.props.length,g;e;)g=this.props[--e],a[g]=d[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=a.target.ownerDocument||c,i=h.documentElement,j=h.body;a.pageX=a.clientX+(i&&i.scrollLeft||j&&j.scrollLeft||0)-(i&&i.clientLeft||j&&j.clientLeft||0),a.pageY=a.clientY+(i&&i.scrollTop||j&&j.scrollTop||0)-(i&&i.clientTop||j&&j.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:f.proxy,special:{ready:{setup:f.bindReady,teardown:f.noop},live:{add:function(a){f.event.add(this,M(a.origType,a.selector),f.extend({},a,{handler:L,guid:a.handler.guid}))},remove:function(a){f.event.remove(this,M(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!this.preventDefault)return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?D:C):this.type=a,b&&f.extend(this,b),this.timeStamp=f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=D;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=D;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=D,this.stopPropagation()},isDefaultPrevented:C,isPropagationStopped:C,isImmediatePropagationStopped:C};var E=function(a){var b=a.relatedTarget,c=!1,d=a.type;a.type=a.data,b!==this&&(b&&(c=f.contains(this,b)),c||(f.event.handle.apply(this,arguments),a.type=d))},F=function(a){a.type=a.data,f.event.handle.apply(this,arguments)};f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={setup:function(c){f.event.add(this,b,c&&c.selector?F:E,a)},teardown:function(a){f.event.remove(this,b,a&&a.selector?F:E)}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(a,b){if(!f.nodeName(this,"form"))f.event.add(this,"click.specialSubmit",function(a){var b=a.target,c=f.nodeName(b,"input")||f.nodeName(b,"button")?b.type:"";(c==="submit"||c==="image")&&f(b).closest("form").length&&J("submit",this,arguments)}),f.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,c=f.nodeName(b,"input")||f.nodeName(b,"button")?b.type:"";(c==="text"||c==="password")&&f(b).closest("form").length&&a.keyCode===13&&J("submit",this,arguments)});else return!1},teardown:function(a){f.event.remove(this,".specialSubmit")}});if(!f.support.changeBubbles){var G,H=function(a){var b=f.nodeName(a,"input")?a.type:"",c=a.value;b==="radio"||b==="checkbox"?c=a.checked:b==="select-multiple"?c=a.selectedIndex>-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},I=function(c){var d=c.target,e,g;if(!!x.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=H(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:I,beforedeactivate:I,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&I.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&I.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",H(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in G)f.event.add(this,c+".specialChange",G[c]);return x.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return x.test(this.nodeName)}},G=f.event.special.change.filters,G.focus=G.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i<j;i++)f.event.add(this[i],a,g,d);return this}}),f.fn.extend({unbind:function(a,b){if(typeof a=="object"&&!a.preventDefault)for(var c in a)this.unbind(c,a[c]);else for(var d=0,e=this.length;d<e;d++)f.event.remove(this[d],a,b);return this},delegate:function(a,b,c,d){return this.live(b,c,d,a)},undelegate:function(a,b,c){return arguments.length===0?this.unbind("live"):this.die(b,null,c,a)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f.data(this,"lastToggle"+a.guid)||0)%d;f.data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var K={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};f.each(["live","die"],function(a,c){f.fn[c]=function(a,d,e,g){var h,i=0,j,k,l,m=g||this.selector,n=g?this:f(this.context);if(typeof a=="object"&&!a.preventDefault){for(var o in a)n[c](o,d,a[o],m);return this}if(c==="die"&&!a&&g&&g.charAt(0)==="."){n.unbind(g);return this}if(d===!1||f.isFunction(d))e=d||C,d=b;a=(a||"").split(" ");while((h=a[i++])!=null){j=w.exec(h),k="",j&&(k=j[0],h=h.replace(w,""));if(h==="hover"){a.push("mouseenter"+k,"mouseleave"+k);continue}l=h,K[h]?(a.push(K[h]+k),h=h+k):h=(K[h]||h)+k;if(c==="live")for(var p=0,q=n.length;p<q;p++)f.event.add(n[p],"live."+M(h,m),{data:d,selector:m,handler:e,origType:h,origHandler:e,preType:l});else n.unbind("live."+M(h,m),e)}return this}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}if(i.nodeType===1){f||(i.sizcache=c,i.sizset=g);if(typeof b!="string"){if(i===b){j=!0;break}}else if(k.filter(b,[i]).length>0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}i.nodeType===1&&!f&&(i.sizcache=c,i.sizset=g);if(i.nodeName.toLowerCase()===b){j=i;break}i=i[a]}d[g]=j}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},k.matches=function(a,b){return k(a,null,null,b)},k.matchesSelector=function(a,b){return k(b,null,null,[a]).length>0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e<f;e++){var g,h=l.order[e];if(g=l.leftMatch[h].exec(a)){var j=g[1];g.splice(1,1);if(j.substr(j.length-1)!=="\\"){g[1]=(g[1]||"").replace(i,""),d=l.find[h](g,b,c);if(d!=null){a=a.replace(l.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},k.filter=function(a,c,d,e){var f,g,h=a,i=[],j=c,m=c&&c[0]&&k.isXML(c[0]);while(a&&c.length){for(var n in l.filter)if((f=l.leftMatch[n].exec(a))!=null&&f[2]){var o,p,q=l.filter[n],r=f[1];g=!1,f.splice(1,1);if(r.substr(r.length-1)==="\\")continue;j===i&&(i=[]);if(l.preFilter[n]){f=l.preFilter[n](f,j,d,i,e,m);if(!f)g=o=!0;else if(f===!0)continue}if(f)for(var s=0;(p=j[s])!=null;s++)if(p){o=q(p,f,s,j);var t=e^!!o;d&&o!=null?t?g=!0:j[s]=!1:t&&(i.push(p),g=!0)}if(o!==b){d||(j=i),a=a.replace(l.match[n],"");if(!g)return[];break}}if(a===h)if(g==null)k.error(a);else break;h=a}return j},k.error=function(a){throw"Syntax error, unrecognized expression: "+a};var l=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!j.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&k.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&k.filter(b,a,!0)}},"":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("parentNode",b,f,a,e,c)},"~":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("previousSibling",b,f,a,e,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(i,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}k.error(e)},CHILD:function(a,b){var c=b[1],d=a;switch(c){case"only":case"first":while(d=d.previousSibling)if(d.nodeType===1)return!1;if(c==="first")return!0;d=a;case"last":while(d=d.nextSibling)if(d.nodeType===1)return!1;return!0;case"nth":var e=b[2],f=b[3];if(e===1&&f===0)return!0;var g=b[0],h=a.parentNode;if(h&&(h.sizcache!==g||!a.nodeIndex)){var i=0;for(d=h.firstChild;d;d=d.nextSibling)d.nodeType===1&&(d.nodeIndex=++i);h.sizcache=g}var j=a.nodeIndex-f;return e===0?j===0:j%e===0&&j/e>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c<f;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var r,s;c.documentElement.compareDocumentPosition?r=function(a,b){if(a===b){g=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(r=function(a,b){if(a===b){g=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],h=a.parentNode,i=b.parentNode,j=h;if(h===i)return s(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return s(e[k],f[k]);return k===c?s(a,f[k],-1):s(e[k],b,1)},s=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),k.getText=function(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=k.getText(c.childNodes));return b},function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g<h;g++)k(a,f[g],d);return k.filter(e,d)};f.find=k,f.expr=k.selectors,f.expr[":"]=f.expr.filters,f.unique=k.uniqueSort,f.text=k.getText,f.isXMLDoc=k.isXML,f.contains=k.contains}();var N=/Until$/,O=/^(?:parents|prevUntil|prevAll)/,P=/,/,Q=/^.[^:#\[\.,]*$/,R=Array.prototype.slice,S=f.expr.match.POS,T={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(V(this,a,!1),"not",a)},filter:function(a){return this.pushStack(V(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d<e;d++)i=a[d],j[i]||(j[i]=S.test(i)?f(i,b||this.context):i);while(g&&g.ownerDocument&&g!==b){for(i in j)h=j[i],(h.jquery?h.index(g)>-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=S.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(l?l.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(U(c[0])||U(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=R.call(arguments);N.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!T[a]?f.unique(e):e,(this.length>1||P.test(d))&&O.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|object|embed|option|style)/i,bb=/checked\s*(?:[^=]|=\s*.checked.)/i,bc=/\/(java|ecma)script/i,bd=/^\s*<!(?:\[CDATA\[|\-\-)/,be={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};be.optgroup=be.option,be.tbody=be.tfoot=be.colgroup=be.caption=be.thead,be.th=be.td,f.support.htmlSerialize||(be._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!be[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bb.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bf(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bl)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i;b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof a[0]=="string"&&a[0].length<512&&i===c&&a[0].charAt(0)==="<"&&!ba.test(a[0])&&(f.support.checkClone||!bb.test(a[0]))&&(g=!0,h=f.fragments[a[0]],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean
+(a,i,e,d)),g&&(f.fragments[a[0]]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bh(a,d),e=bi(a),g=bi(d);for(h=0;e[h];++h)g[h]&&bh(e[h],g[h])}if(b){bg(a,d);if(c){e=bi(a),g=bi(d);for(h=0;e[h];++h)bg(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=be[l]||be._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bk(k[i]);else bk(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||bc.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.expando,g=f.event.special,h=f.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&f.noData[j.nodeName.toLowerCase()])continue;c=j[f.expando];if(c){b=d[c]&&d[c][e];if(b&&b.events){for(var k in b.events)g[k]?f.event.remove(j,k):f.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[f.expando]:j.removeAttribute&&j.removeAttribute(f.expando),delete d[c]}}}});var bm=/alpha\([^)]*\)/i,bn=/opacity=([^)]*)/,bo=/([A-Z]|^ms)/g,bp=/^-?\d+(?:px)?$/i,bq=/^-?\d/,br=/^([\-+])=([\-+.\de]+)/,bs={position:"absolute",visibility:"hidden",display:"block"},bt=["Left","Right"],bu=["Top","Bottom"],bv,bw,bx;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bv(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=br.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bv)return bv(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return by(a,b,d);f.swap(a,bs,function(){e=by(a,b,d)});return e}},set:function(a,b){if(!bp.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bn.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bm,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bm.test(g)?g.replace(bm,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bv(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bw=function(a,c){var d,e,g;c=c.replace(bo,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bx=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bp.test(d)&&bq.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bv=bw||bx,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bz=/%20/g,bA=/\[\]$/,bB=/\r?\n/g,bC=/#.*$/,bD=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bE=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bF=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bG=/^(?:GET|HEAD)$/,bH=/^\/\//,bI=/\?/,bJ=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bK=/^(?:select|textarea)/i,bL=/\s+/,bM=/([?&])_=[^&]*/,bN=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bO=f.fn.load,bP={},bQ={},bR,bS,bT=["*/"]+["*"];try{bR=e.href}catch(bU){bR=c.createElement("a"),bR.href="",bR=bR.href}bS=bN.exec(bR.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bO)return bO.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bJ,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bK.test(this.nodeName)||bE.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bB,"\r\n")}}):{name:b.name,value:c.replace(bB,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?bX(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),bX(a,b);return a},ajaxSettings:{url:bR,isLocal:bF.test(bS[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bT},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bV(bP),ajaxTransport:bV(bQ),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?bZ(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=b$(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bD.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bC,"").replace(bH,bS[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bL),d.crossDomain==null&&(r=bN.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bS[1]&&r[2]==bS[2]&&(r[3]||(r[1]==="http:"?80:443))==(bS[3]||(bS[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bW(bP,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bG.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bI.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bM,"$1_="+x);d.url=y+(y===d.url?(bI.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bT+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bW(bQ,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){s<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bz,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cq("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cr(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cq("hide",3),a,b,c);for(var d=0,e=this.length;d<e;d++)if(this[d].style){var g=f.css(this[d],"display");g!=="none"&&!f._data(this[d],"olddisplay")&&f._data(this[d],"olddisplay",g)}for(d=0;d<e;d++)this[d].style&&(this[d].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cq("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return this[e.queue===!1?"each":"queue"](function(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(f.support.inlineBlockNeedsLayout?(j=cr(this.nodeName),j==="inline"?this.style.display="inline-block":(this.style.display="inline",this.style.zoom=1)):this.style.display="inline-block"))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)k=new f.fx(this,b,i),h=a[i],cj.test(h)?k[h==="toggle"?d?"show":"hide":h]():(l=ck.exec(h),m=k.cur(),l?(n=parseFloat(l[2]),o=l[3]||(f.cssNumber[i]?"":"px"),o!=="px"&&(f.style(this,i,(n||1)+o),m=(n||1)/k.cur()*m,f.style(this,i,m+o)),l[1]&&(n=(l[1]==="-="?-1:1)*n+m),k.custom(m,n,o)):k.custom(m,h,""));return!0})},stop:function(a,b){a&&this.queue([]),this.each(function(){var a=f.timers,c=a.length;b||f._unmark(!0,this);while(c--)a[c].elem===this&&(b&&a[c](!0),a.splice(c,1))}),b||this.dequeue();return this}}),f.each({slideDown:cq("show",1),slideUp:cq("hide",1),slideToggle:cq("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default,d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue!==!1?f.dequeue(this):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function g(a){return d.step(a)}var d=this,e=f.fx;this.startTime=cn||co(),this.start=a,this.end=b,this.unit=c||this.unit||(f.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,g.elem=this.elem,g()&&f.timers.push(g)&&!cl&&(cl=setInterval(e.tick,e.interval))},show:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=cn||co(),c=!0,d=this.elem,e=this.options,g,h;if(a||b>=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b<a.length;++b)a[b]()||a.splice(b--,1);a.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cl),cl=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cs=/^t(?:able|d|h)$/i,ct=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cu(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);f.offset.initialize();var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.offset.doesNotAddBorder&&(!f.offset.doesAddBorderForTableAndCells||!cs.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={initialize:function(){var a=c.body,b=c.createElement("div"),d,e,g,h,i=parseFloat(f.css(a,"marginTop"))||0,j="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=ct.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!ct.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cu(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cu(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNaN(j)?i:j}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file
diff --git a/lib/scripts/jquery/update.sh b/lib/scripts/jquery/update.sh
new file mode 100755
index 000000000..fde46f4d7
--- /dev/null
+++ b/lib/scripts/jquery/update.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# This script loads the latest jQuery and jQuery-UI 1.* versions from Google's CDN
+#
+# It also loads the 'smoothness' jQuery-UI theme and all referenced images.
+#
+# @author Andreas Gohr <andi@splitbrain.org>
+# @link https://code.google.com/apis/libraries/devguide.html#jquery
+
+# load jQuery
+wget -nv https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js -O jquery.min.js
+wget -nv https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js -O jquery.js
+
+# load jQuery-UI
+wget -nv https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js -O jquery-ui.min.js
+wget -nv https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.js -O jquery-ui.js
+
+# load the smoothness theme
+mkdir -p jquery-ui-theme/images
+wget -nv https://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/smoothness/jquery-ui.css -O jquery-ui-theme/smoothness.css
+images=`gawk 'match($0, /url\((images\/[^\)]+)\)/, m) { print m[1] }' jquery-ui-theme/smoothness.css`
+for img in $images
+do
+ wget -nv https://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/smoothness/$img -O jquery-ui-theme/$img
+done
+
+# remove font family declarations from smoothness CSS
+sed -i "s/font-family:[^;]*; \?//" jquery-ui-theme/smoothness.css
diff --git a/lib/scripts/linkwiz.js b/lib/scripts/linkwiz.js
new file mode 100644
index 000000000..5075a0ab8
--- /dev/null
+++ b/lib/scripts/linkwiz.js
@@ -0,0 +1,308 @@
+/**
+ * The Link Wizard
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+var dw_linkwiz = {
+ $wiz: null,
+ $entry: null,
+ result: null,
+ timer: null,
+ textArea: null,
+ selected: null,
+ selection: null,
+
+ /**
+ * Initialize the dw_linkwizard by creating the needed HTML
+ * and attaching the eventhandlers
+ */
+ init: function($editor){
+ // position relative to the text area
+ var pos = $editor.position();
+
+ // create HTML Structure
+ dw_linkwiz.$wiz = jQuery(document.createElement('div'))
+ .dialog({
+ autoOpen: false,
+ draggable: true,
+ title: LANG.linkwiz,
+ resizable: false
+ })
+ .html(
+ '<div>'+LANG.linkto+' <input type="text" class="edit" id="link__wiz_entry" autocomplete="off" /></div>'+
+ '<div id="link__wiz_result"></div>'
+ )
+ .parent()
+ .attr('id','link__wiz')
+ .css({
+ 'position': 'absolute',
+ 'top': (pos.top+20)+'px',
+ 'left': (pos.left+80)+'px'
+ })
+ .hide()
+ .appendTo('.dokuwiki:first');
+
+ dw_linkwiz.textArea = $editor[0];
+ dw_linkwiz.result = jQuery('#link__wiz_result')[0];
+
+ // scrollview correction on arrow up/down gets easier
+ jQuery(dw_linkwiz.result).css('position', 'relative');
+
+ dw_linkwiz.$entry = jQuery('#link__wiz_entry');
+
+ // attach event handlers
+ jQuery('#link__wiz_close').click(dw_linkwiz.hide);
+ dw_linkwiz.$entry.keyup(dw_linkwiz.onEntry);
+ jQuery(dw_linkwiz.result).delegate('a', 'click', dw_linkwiz.onResultClick);
+ },
+
+ /**
+ * handle all keyup events in the entry field
+ */
+ onEntry: function(e){
+ if(e.keyCode == 37 || e.keyCode == 39){ //left/right
+ return true; //ignore
+ }
+ if(e.keyCode == 27){
+ dw_linkwiz.hide();
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ if(e.keyCode == 38){ //Up
+ dw_linkwiz.select(dw_linkwiz.selected -1);
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ if(e.keyCode == 40){ //Down
+ dw_linkwiz.select(dw_linkwiz.selected +1);
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ if(e.keyCode == 13){ //Enter
+ if(dw_linkwiz.selected > -1){
+ var $obj = dw_linkwiz.$getResult(dw_linkwiz.selected);
+ if($obj.length > 0){
+ dw_linkwiz.resultClick($obj.find('a')[0]);
+ }
+ }else if(dw_linkwiz.$entry.val()){
+ dw_linkwiz.insertLink(dw_linkwiz.$entry.val());
+ }
+
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ dw_linkwiz.autocomplete();
+ },
+
+ /**
+ * Get one of the results by index
+ *
+ * @param int result div to return
+ * @returns DOMObject or null
+ */
+ getResult: function(num){
+ DEPRECATED('use dw_linkwiz.$getResult()[0] instead');
+ return dw_linkwiz.$getResult()[0] || null;
+ },
+
+ /**
+ * Get one of the results by index
+ *
+ * @param int result div to return
+ * @returns jQuery object
+ */
+ $getResult: function(num) {
+ return jQuery(dw_linkwiz.result).find('div').eq(num);
+ },
+
+ /**
+ * Select the given result
+ */
+ select: function(num){
+ if(num < 0){
+ dw_linkwiz.deselect();
+ return;
+ }
+
+ var $obj = dw_linkwiz.$getResult(num);
+ if ($obj.length === 0) {
+ return;
+ }
+
+ dw_linkwiz.deselect();
+ $obj.addClass('selected');
+
+ // make sure the item is viewable in the scroll view
+
+ //getting child position within the parent
+ var childPos = $obj.position().top;
+ //getting difference between the childs top and parents viewable area
+ var yDiff = childPos + $obj.outerHeight() - jQuery(dw_linkwiz.result).innerHeight();
+
+ if (childPos < 0) {
+ //if childPos is above viewable area (that's why it goes negative)
+ jQuery(dw_linkwiz.result)[0].scrollTop += childPos;
+ } else if(yDiff > 0) {
+ // if difference between childs top and parents viewable area is
+ // greater than the height of a childDiv
+ jQuery(dw_linkwiz.result)[0].scrollTop += yDiff;
+ }
+
+ dw_linkwiz.selected = num;
+ },
+
+ /**
+ * deselect a result if any is selected
+ */
+ deselect: function(){
+ if(dw_linkwiz.selected > -1){
+ dw_linkwiz.$getResult(dw_linkwiz.selected).removeClass('selected');
+ }
+ dw_linkwiz.selected = -1;
+ },
+
+ /**
+ * Handle clicks in the result set an dispatch them to
+ * resultClick()
+ */
+ onResultClick: function(e){
+ if(!jQuery(this).is('a')) {
+ return;
+ }
+ e.stopPropagation();
+ e.preventDefault();
+ dw_linkwiz.resultClick(this);
+ return false;
+ },
+
+ /**
+ * Handles the "click" on a given result anchor
+ */
+ resultClick: function(a){
+ dw_linkwiz.$entry.val(a.title);
+ if(a.title == '' || a.title.substr(a.title.length-1) == ':'){
+ dw_linkwiz.autocomplete_exec();
+ }else{
+ if (jQuery(a.nextSibling).is('span')) {
+ dw_linkwiz.insertLink(a.nextSibling.innerHTML);
+ }else{
+ dw_linkwiz.insertLink('');
+ }
+ }
+ },
+
+ /**
+ * Insert the id currently in the entry box to the textarea,
+ * replacing the current selection or at the cursor position.
+ * When no selection is available the given title will be used
+ * as link title instead
+ */
+ insertLink: function(title){
+ var link = dw_linkwiz.$entry.val(),
+ sel, stxt;
+ if(!link) {
+ return;
+ }
+
+ sel = getSelection(dw_linkwiz.textArea);
+ if(sel.start == 0 && sel.end == 0) {
+ sel = dw_linkwiz.selection;
+ }
+
+ stxt = sel.getText();
+
+ // don't include trailing space in selection
+ if(stxt.charAt(stxt.length - 1) == ' '){
+ sel.end--;
+ stxt = sel.getText();
+ }
+
+ if(!stxt && !DOKU_UHC) {
+ stxt=title;
+ }
+
+ // prepend colon inside namespaces for non namespace pages
+ if(dw_linkwiz.textArea.form.id.value.indexOf(':') != -1 &&
+ link.indexOf(':') == -1){
+ link = ':' + link;
+ }
+
+ var so = link.length+3;
+
+ link = '[['+link+'|';
+ if(stxt) {
+ link += stxt;
+ }
+ link += ']]';
+
+ pasteText(sel,link,{startofs: so, endofs: 2});
+ dw_linkwiz.hide();
+
+ // reset the entry to the parent namespace
+ dw_linkwiz.$entry.val(dw_linkwiz.$entry.val().replace(/[^:]*$/, ''));
+ },
+
+ /**
+ * Start the page/namespace lookup timer
+ *
+ * Calls autocomplete_exec when the timer runs out
+ */
+ autocomplete: function(){
+ if(dw_linkwiz.timer !== null){
+ window.clearTimeout(dw_linkwiz.timer);
+ dw_linkwiz.timer = null;
+ }
+
+ dw_linkwiz.timer = window.setTimeout(dw_linkwiz.autocomplete_exec,350);
+ },
+
+ /**
+ * Executes the AJAX call for the page/namespace lookup
+ */
+ autocomplete_exec: function(){
+ var $res = jQuery(dw_linkwiz.result);
+ dw_linkwiz.deselect();
+ $res.html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />')
+ .load(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'linkwiz',
+ q: dw_linkwiz.$entry.val()
+ }
+ );
+ },
+
+ /**
+ * Show the link wizard
+ */
+ show: function(){
+ dw_linkwiz.selection = getSelection(dw_linkwiz.textArea);
+ dw_linkwiz.$wiz.show();
+ dw_linkwiz.$entry.focus();
+ dw_linkwiz.autocomplete();
+ },
+
+ /**
+ * Hide the link wizard
+ */
+ hide: function(){
+ dw_linkwiz.$wiz.hide();
+ dw_linkwiz.textArea.focus();
+ },
+
+ /**
+ * Toggle the link wizard
+ */
+ toggle: function(){
+ if(dw_linkwiz.$wiz.css('display') == 'none'){
+ dw_linkwiz.show();
+ }else{
+ dw_linkwiz.hide();
+ }
+ }
+};
diff --git a/lib/scripts/locktimer.js b/lib/scripts/locktimer.js
new file mode 100644
index 000000000..96f963c08
--- /dev/null
+++ b/lib/scripts/locktimer.js
@@ -0,0 +1,126 @@
+/**
+ * Class managing the timer to display a warning on a expiring lock
+ */
+var dw_locktimer = {
+ timeout: 0,
+ draft: false,
+ timerID: null,
+ lasttime: null,
+ msg: LANG.willexpire,
+ pageid: '',
+
+ /**
+ * Initialize the lock timer
+ *
+ * @param int timeout Length of timeout in seconds
+ * @param string msg Deprecated; The expiry message
+ * @param bool draft Whether to save drafts
+ * @param string edid Optional; ID of an edit object which has to be present
+ */
+ init: function(timeout,msg,draft,edid){
+ var $edit;
+
+ switch (arguments.length) {
+ case 4:
+ DEPRECATED('Setting the locktimer expiry message is deprecated');
+ dw_locktimer.msg = msg;
+ break;
+ case 3:
+ edid = draft;
+ case 2:
+ draft = msg;
+ }
+ edid = edid || 'wiki__text';
+
+ $edit = jQuery('#' + edid);
+ if($edit.length === 0 || $edit.attr('readonly')) {
+ return;
+ }
+
+ // init values
+ dw_locktimer.timeout = timeout*1000;
+ dw_locktimer.draft = draft;
+ dw_locktimer.lasttime = new Date();
+
+ dw_locktimer.pageid = jQuery('#dw__editform input[name=id]').val();
+ if(!dw_locktimer.pageid) {
+ return;
+ }
+
+ // register refresh event
+ $edit.keypress(dw_locktimer.refresh);
+ // start timer
+ dw_locktimer.reset();
+ },
+
+ /**
+ * (Re)start the warning timer
+ */
+ reset: function(){
+ dw_locktimer.clear();
+ dw_locktimer.timerID = window.setTimeout(dw_locktimer.warning, dw_locktimer.timeout);
+ },
+
+ /**
+ * Display the warning about the expiring lock
+ */
+ warning: function(){
+ dw_locktimer.clear();
+ alert(fixtxt(dw_locktimer.msg));
+ },
+
+ /**
+ * Remove the current warning timer
+ */
+ clear: function(){
+ if(dw_locktimer.timerID !== null){
+ window.clearTimeout(dw_locktimer.timerID);
+ dw_locktimer.timerID = null;
+ }
+ },
+
+ /**
+ * Refresh the lock via AJAX
+ *
+ * Called on keypresses in the edit area
+ */
+ refresh: function(){
+ var now = new Date(),
+ params = 'call=lock&id=' + dw_locktimer.pageid + '&';
+
+ // refresh every minute only
+ if(now.getTime() - dw_locktimer.lasttime.getTime() <= 30*1000) {
+ return;
+ }
+
+ // POST everything necessary for draft saving
+ if(dw_locktimer.draft && jQuery('#dw__editform textarea[name=wikitext]').length > 0){
+ params += jQuery('#dw__editform').find('input[name=prefix], ' +
+ 'textarea[name=wikitext], ' +
+ 'input[name=suffix], ' +
+ 'input[name=date]').serialize();
+ }
+
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ params,
+ dw_locktimer.refreshed,
+ 'html'
+ );
+ dw_locktimer.lasttime = now;
+ },
+
+ /**
+ * Callback. Resets the warning timer
+ */
+ refreshed: function(data){
+ var error = data.charAt(0);
+ data = data.substring(1);
+
+ jQuery('#draft__status').html(data);
+ if(error != '1') {
+ return; // locking failed
+ }
+ dw_locktimer.reset();
+ }
+};
diff --git a/lib/scripts/media.js b/lib/scripts/media.js
new file mode 100644
index 000000000..841baa93f
--- /dev/null
+++ b/lib/scripts/media.js
@@ -0,0 +1,940 @@
+/**
+ * JavaScript functionality for the media management popup
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+
+var dw_mediamanager = {
+ keepopen: false,
+ hide: false,
+ popup: false,
+ display: false,
+ ext: false,
+ $popup: null,
+
+ // Image insertion opts
+ align: false,
+ link: false,
+ size: false,
+ forbidden_opts: {},
+
+ // File list options
+ view_opts: {list: false, sort: false},
+
+ layout_width: 0,
+
+ // The minimum height of the full-screen mediamanager in px
+ minHeights: {thumbs: 200, rows: 100},
+
+ init: function () {
+ var $content, $tree;
+ $content = jQuery('#media__content');
+ $tree = jQuery('#media__tree');
+
+ dw_mediamanager.prepare_content($content);
+
+ dw_mediamanager.attachoptions();
+ dw_mediamanager.initpopup();
+
+ // add the action to autofill the "upload as" field
+ $content.delegate('#upload__file', 'change', dw_mediamanager.suggest)
+ // Attach the image selector action to all links
+ .delegate('a.select', 'click', dw_mediamanager.select)
+ // Attach deletion confirmation dialog to the delete buttons
+ .delegate('#media__content a.btn_media_delete', 'click',
+ dw_mediamanager.confirmattach)
+ .delegate('#mediamanager__done_form', 'submit', dw_mediamanager.list);
+
+ $tree.dw_tree({toggle_selector: 'img',
+ load_data: function (show_sublist, $clicky) {
+ // get the enclosed link (is always the first one)
+ var $link = $clicky.parent().find('div.li a.idx_dir');
+
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ $link[0].search.substr(1) + '&call=medians',
+ show_sublist,
+ 'html'
+ );
+ },
+
+ toggle_display: function ($clicky, opening) {
+ $clicky.attr('src',
+ DOKU_BASE + 'lib/images/' +
+ (opening ? 'minus' : 'plus') + '.gif');
+ }});
+ $tree.delegate('a', 'click', dw_mediamanager.list);
+
+ // Init view property
+ dw_mediamanager.set_fileview_list();
+
+ dw_mediamanager.init_options();
+
+ dw_mediamanager.image_diff();
+ dw_mediamanager.init_ajax_uploader();
+
+ // changing opened tab in the file list panel
+ jQuery('#mediamanager__page div.filelist').delegate('ul.tabs a', 'click', dw_mediamanager.list)
+ // loading file details
+ .delegate('div.panelContent a', 'click', dw_mediamanager.details)
+ // search form
+ .delegate('#dw__mediasearch', 'submit', dw_mediamanager.list)
+ // "upload as" field autofill
+ .delegate('#upload__file', 'change', dw_mediamanager.suggest)
+ // uploaded images
+ .delegate('.qq-upload-file a', 'click', dw_mediamanager.details);
+
+ // changing opened tab in the file details panel
+ jQuery('#mediamanager__page div.file').delegate('ul.tabs a', 'click', dw_mediamanager.details)
+ // "update new version" button
+ .delegate('#mediamanager__btn_update', 'submit', dw_mediamanager.list)
+ // revisions form
+ .delegate('#page__revisions', 'submit', dw_mediamanager.details)
+ .delegate('#page__revisions a', 'click', dw_mediamanager.details)
+ // meta edit form
+ .delegate('#mediamanager__save_meta', 'submit', dw_mediamanager.details)
+ // delete button
+ .delegate('#mediamanager__btn_delete', 'submit', dw_mediamanager.details)
+ // "restore this version" button
+ .delegate('#mediamanager__btn_restore', 'submit', dw_mediamanager.details)
+ // less/more recent buttons in media revisions form
+ .delegate('.btn_newer, .btn_older', 'submit', dw_mediamanager.details);
+
+ dw_mediamanager.update_resizable();
+ dw_mediamanager.layout_width = jQuery("#mediamanager__page").width();
+ jQuery(window).resize(dw_mediamanager.window_resize);
+ },
+
+ init_options: function () {
+ var $options = jQuery('div.filelist div.panelHeader form.options'),
+ $listType, $sortBy, $both;
+ if ($options.length === 0) {
+ return;
+ }
+
+ $listType = $options.find('li.listType');
+ $sortBy = $options.find('li.sortBy');
+ $both = $listType.add($sortBy);
+
+ // Remove the submit button
+ $options.find('input[type=submit]').parent().hide();
+
+ // Prepare HTML for jQuery UI buttonset
+ $both.find('label').each(function () {
+ var $this = jQuery(this);
+ $this.children('input').appendTo($this.parent());
+ });
+
+ // Init buttonset
+ $both.buttonset();
+
+ // Change handlers
+ $listType.children('input').change(function (event) {
+ dw_mediamanager.set_fileview_list();
+ });
+ $sortBy.children('input').change(function (event) {
+ dw_mediamanager.set_fileview_sort();
+ dw_mediamanager.list.call(jQuery('#dw__mediasearch')[0] || this, event);
+ });
+ },
+
+ /**
+ * build the popup window
+ *
+ * @author Dominik Eckelmann <eckelmann@cosmocode.de>
+ */
+ initpopup: function () {
+ var opts, $insp, $insbtn;
+
+ dw_mediamanager.$popup = jQuery(document.createElement('div'))
+ .attr('id', 'media__popup_content')
+ .dialog({autoOpen: false, width: 280, modal: true,
+ draggable: true, title: LANG.mediatitle,
+ resizable: false});
+
+ opts = [{id: 'link', label: LANG.mediatarget,
+ btns: ['lnk', 'direct', 'nolnk', 'displaylnk']},
+ {id: 'align', label: LANG.mediaalign,
+ btns: ['noalign', 'left', 'center', 'right']},
+ {id: 'size', label: LANG.mediasize,
+ btns: ['small', 'medium', 'large', 'original']}
+ ];
+
+ jQuery.each(opts, function (_, opt) {
+ var $p, $l;
+ $p = jQuery(document.createElement('p'))
+ .attr('id', 'media__' + opt.id);
+
+ if (dw_mediamanager.display === "2") {
+ $p.hide();
+ }
+
+ $l = jQuery(document.createElement('label'))
+ .text(opt.label);
+ $p.append($l);
+
+ jQuery.each(opt.btns, function (i, text) {
+ var $btn, $img;
+ $btn = jQuery(document.createElement('button'))
+ .addClass('button')
+ .attr('id', "media__" + opt.id + "btn" + (i + 1))
+ .attr('title', LANG['media' + text])
+ .click(bind(dw_mediamanager.setOpt, opt.id));
+
+ $img = jQuery(document.createElement('img'))
+ .attr('src', DOKU_BASE + 'lib/images/media_' +
+ opt.id + '_' + text + '.png');
+
+ $btn.append($img);
+ $p.append($btn);
+ });
+
+ dw_mediamanager.$popup.append($p);
+ });
+
+ // insert button
+ $insp = jQuery(document.createElement('p'));
+ dw_mediamanager.$popup.append($insp);
+
+ $insbtn = jQuery(document.createElement('input'))
+ .attr('id', 'media__sendbtn')
+ .attr('type', 'button')
+ .addClass('button')
+ .val(LANG.mediainsert);
+ $insp.append($insbtn);
+ },
+
+ /**
+ * Insert the clicked image into the opener's textarea
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Dominik Eckelmann <eckelmann@cosmocode.de>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ insert: function (id) {
+ var opts, alignleft, alignright, edid, s;
+
+ // set syntax options
+ dw_mediamanager.$popup.dialog('close');
+
+ opts = '';
+ alignleft = '';
+ alignright = '';
+
+ if ({img: 1, swf: 1}[dw_mediamanager.ext] === 1) {
+
+ if (dw_mediamanager.link === '4') {
+ opts = '?linkonly';
+ } else {
+
+ if (dw_mediamanager.link === "3" && dw_mediamanager.ext === 'img') {
+ opts = '?nolink';
+ } else if (dw_mediamanager.link === "2" && dw_mediamanager.ext === 'img') {
+ opts = '?direct';
+ }
+
+ s = parseInt(dw_mediamanager.size, 10);
+
+ if (s && s >= 1 && s < 4) {
+ opts += (opts.length)?'&':'?';
+ opts += dw_mediamanager.size + '00';
+ if (dw_mediamanager.ext === 'swf') {
+ switch (s) {
+ case 1:
+ opts += 'x62';
+ break;
+ case 2:
+ opts += 'x123';
+ break;
+ case 3:
+ opts += 'x185';
+ break;
+ }
+ }
+ }
+ if (dw_mediamanager.align !== '1') {
+ alignleft = dw_mediamanager.align === '2' ? '' : ' ';
+ alignright = dw_mediamanager.align === '4' ? '' : ' ';
+ }
+ }
+ }
+ edid = String.prototype.match.call(document.location, /&edid=([^&]+)/);
+ opener.insertTags(edid ? edid[1] : 'wiki__text',
+ '{{'+alignleft+id+opts+alignright+'|','}}','');
+
+ if(!dw_mediamanager.keepopen) {
+ window.close();
+ }
+ opener.focus();
+ return false;
+ },
+
+ /**
+ * Prefills the wikiname.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ suggest: function(){
+ var $file, $name, text;
+
+ $file = jQuery(this);
+ $name = jQuery('#upload__name');
+
+ if ($name.val() != '') return;
+
+ if(!$file.length || !$name.length) {
+ return;
+ }
+
+ text = $file.val();
+ text = text.substr(text.lastIndexOf('/')+1);
+ text = text.substr(text.lastIndexOf('\\')+1);
+ $name.val(text);
+ },
+
+ /**
+ * list the content of a namespace using AJAX
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ list: function (event) {
+ var $link, $content, params;
+
+ if (event) {
+ event.preventDefault();
+ }
+
+ jQuery('div.success, div.info, div.error, div.notify').remove();
+
+ $link = jQuery(this);
+
+ //popup
+ $content = jQuery('#media__content');
+
+ if ($content.length === 0) {
+ //fullscreen media manager
+ $content = jQuery('div.filelist');
+
+ if ($link.hasClass('idx_dir')) {
+ //changing namespace
+ jQuery('div.file').empty();
+ jQuery('div.namespaces .selected').removeClass('selected');
+ $link.addClass('selected');
+ }
+ }
+
+ params = 'call=medialist&';
+
+ if ($link[0].search) {
+ params += $link[0].search.substr(1);
+ } else if ($link.is('form')) {
+ params += dw_mediamanager.form_params($link);
+ } else if ($link.closest('form').length > 0) {
+ params += dw_mediamanager.form_params($link.closest('form'));
+ }
+
+ // fetch the subtree
+ dw_mediamanager.update_content($content, params);
+ },
+
+ /**
+ * Returns form parameters
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ form_params: function ($form) {
+ if (!$form.length) return;
+ var action = '';
+ var i = $form[0].action.indexOf('?');
+ if (i >= 0) action = $form[0].action.substr(i+1);
+ return action+'&'+$form.serialize();
+ },
+
+ set_fileview_list: function (new_type) {
+ dw_mediamanager.set_fileview_opt(['list', 'listType', function (new_type) {
+ jQuery('div.filelist div.panelContent ul')
+ .toggleClass('rows', new_type === 'rows')
+ .toggleClass('thumbs', new_type === 'thumbs');
+ }], new_type);
+
+ // FIXME: Move to onchange handler (opt[2])?
+ dw_mediamanager.resize();
+ },
+
+ set_fileview_sort: function (new_sort) {
+ dw_mediamanager.set_fileview_opt(['sort', 'sortBy', function (new_sort) {
+ // FIXME
+ }], new_sort);
+ },
+
+ set_fileview_opt: function (opt, new_val) {
+ if (typeof new_val === 'undefined') {
+ new_val = jQuery('form.options li.' + opt[1] + ' input')
+ .filter(':checked').val();
+ // if new_val is still undefined (because form.options is not in active tab), set to most spacious option
+ if (typeof new_val === 'undefined') {
+ new_val = 'thumbs';
+ }
+ }
+
+ if (new_val !== dw_mediamanager.view_opts[opt[0]]) {
+ opt[2](new_val);
+
+ DokuCookie.setValue(opt[0], new_val);
+
+ dw_mediamanager.view_opts[opt[0]] = new_val;
+ }
+ },
+
+ /**
+ * Lists the content of the right column (image details) using AJAX
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ details: function (event) {
+ var $link, $content, params, update_list;
+ $link = jQuery(this);
+ event.preventDefault();
+
+ jQuery('div.success, div.info, div.error, div.notify').remove();
+
+ if ($link[0].id == 'mediamanager__btn_delete' && !confirm(LANG.del_confirm)) {
+ return false;
+ }
+ if ($link[0].id == 'mediamanager__btn_restore' && !confirm(LANG.restore_confirm)) {
+ return false;
+ }
+
+ $content = jQuery('div.file');
+ params = 'call=mediadetails&';
+
+ if ($link[0].search) {
+ params += $link[0].search.substr(1);
+ } else if ($link.is('form')) {
+ params += dw_mediamanager.form_params($link);
+ } else if ($link.closest('form').length > 0) {
+ params += dw_mediamanager.form_params($link.closest('form'));
+ }
+
+ update_list = ($link[0].id == 'mediamanager__btn_delete' ||
+ $link[0].id == 'mediamanager__btn_restore');
+
+ dw_mediamanager.update_content($content, params, update_list);
+ },
+
+ update_content: function ($content, params, update_list) {
+ var $container;
+
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ params,
+ function (data) {
+ dw_mediamanager.$resizables().resizable('destroy');
+
+ if (update_list) {
+ dw_mediamanager.list.call(jQuery('input[value="Apply"]')[0]);
+ }
+
+ $content.html(data);
+
+ dw_mediamanager.prepare_content($content);
+ dw_mediamanager.updatehide();
+
+ dw_mediamanager.update_resizable();
+ dw_behaviour.revisionBoxHandler();
+
+ // Make sure that the list view style stays the same
+ dw_mediamanager.set_fileview_list(dw_mediamanager.view_opts.list);
+
+ dw_mediamanager.image_diff();
+ dw_mediamanager.init_ajax_uploader();
+ dw_mediamanager.init_options();
+
+ },
+ 'html'
+ );
+ $container = $content.find('div.panelContent');
+ if ($container.length === 0) {
+ $container = $content;
+ }
+ $container.html('<img src="' + DOKU_BASE + 'lib/images/loading.gif" alt="..." class="load" />');
+ },
+
+ window_resize: function () {
+ dw_mediamanager.resize();
+
+ dw_mediamanager.opacity_slider();
+ dw_mediamanager.portions_slider();
+ },
+
+ $resizables: function () {
+ return jQuery('#mediamanager__page').find('div.namespaces, div.filelist');
+ },
+
+ /**
+ * Updates mediamanager layout
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ update_resizable: function () {
+ $resizables = dw_mediamanager.$resizables();
+
+ $resizables.resizable({
+ handles: 'e',
+ resize: function(event, ui){
+ var widthFull = jQuery('#mediamanager__page').width();
+ var widthResizables = 0;
+ $resizables.each(function() {
+ widthResizables += jQuery(this).width();
+ });
+ var $filePanel = jQuery('#mediamanager__page div.panel.file');
+
+ // set max width of resizable column
+ var widthOtherResizable = widthResizables - jQuery(this).width();
+ var minWidthNonResizable = parseFloat($filePanel.css("min-width"));
+ var maxWidth = widthFull - (widthOtherResizable + minWidthNonResizable);
+ $resizables.resizable( "option", "maxWidth", maxWidth );
+
+ // width of file panel in % = 100% - width of resizables in %
+ // this calculates with 99.99 and not 100 to overcome rounding errors
+ var relWidthNonResizable = 99.99 - (100 * widthResizables / widthFull);
+ // set width of file panel
+ $filePanel.width(relWidthNonResizable+'%');
+
+ // FIXME: please fix without browser sniffing
+ if (!jQuery.browser.webkit) {
+ $resizables.each(function() {
+ w = jQuery(this).width();
+ w = (99.99 * w / widthFull);
+ w += "%";
+ jQuery(this).width(w);
+ });
+ }
+
+ dw_mediamanager.opacity_slider();
+ dw_mediamanager.portions_slider();
+ }
+ });
+
+ dw_mediamanager.resize();
+ },
+
+ resize: function () {
+ var $contents = jQuery('#mediamanager__page div.panelContent'),
+ height = jQuery(window).height() - jQuery(document.body).height() +
+ Math.max.apply(null, jQuery.map($contents, function (v) {
+ return jQuery(v).height();
+ }));
+
+ // If the screen is too small, don’t try to resize
+ if (height < dw_mediamanager.minHeights[dw_mediamanager.view_opts.list]) {
+ $contents.add(dw_mediamanager.$resizables()).height('auto');
+ } else {
+ $contents.height(height);
+ dw_mediamanager.$resizables().each(function () {
+ var $this = jQuery(this);
+ $this.height(height + $this.find('div.panelContent').offset().top -
+ $this.offset().top);
+ });
+ }
+ },
+
+ /**
+ * Prints 'select' for image difference representation type
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ image_diff: function () {
+ if (jQuery('#mediamanager__difftype').length) return;
+
+ $form = jQuery('#mediamanager__form_diffview');
+ if (!$form.length) return;
+
+ $label = jQuery(document.createElement('label'));
+ $label.append('<span>'+LANG.media_diff+'</span> ');
+ $select = jQuery(document.createElement('select'))
+ .attr('id', 'mediamanager__difftype')
+ .attr('name', 'difftype')
+ .change(dw_mediamanager.change_diff_type);
+ $select.append(new Option(LANG.media_diff_both, "both"));
+ $select.append(new Option(LANG.media_diff_opacity, "opacity"));
+ $select.append(new Option(LANG.media_diff_portions, "portions"));
+ $label.append($select);
+ $form.append($label);
+
+ // for IE
+ var select = document.getElementById('mediamanager__difftype');
+ select.options[0].text = LANG.media_diff_both;
+ select.options[1].text = LANG.media_diff_opacity;
+ select.options[2].text = LANG.media_diff_portions;
+ },
+
+ /**
+ * Handles selection of image difference representation type
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ change_diff_type: function () {
+ $select = jQuery('#mediamanager__difftype');
+ $content = jQuery('#mediamanager__diff');
+
+ params = dw_mediamanager.form_params($select.closest('form'))+'&call=mediadiff';
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ params,
+ function (data) {
+ $content.html(data);
+ dw_mediamanager.portions_slider();
+ dw_mediamanager.opacity_slider();
+ },
+ 'html'
+ );
+ },
+
+ /**
+ * Sets options for opacity diff slider
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ opacity_slider: function () {
+ var $slider = jQuery( "#mediamanager__diff div.slider" );
+ if (!$slider.length) return;
+
+ var $image = jQuery('#mediamanager__diff div.imageDiff.opacity div.image1 img');
+ if (!$image.length) return;
+ $slider.width($image.width()-20);
+
+ $slider.slider();
+ $slider.slider("option", "min", 0);
+ $slider.slider("option", "max", 0.999);
+ $slider.slider("option", "step", 0.001);
+ $slider.slider("option", "value", 0.5);
+ $slider.bind("slide", function(event, ui) {
+ jQuery('#mediamanager__diff div.imageDiff.opacity div.image2 img').css({ opacity: $slider.slider("option", "value")});
+ });
+ },
+
+ /**
+ * Sets options for red line diff slider
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ portions_slider: function () {
+ var $image1 = jQuery('#mediamanager__diff div.imageDiff.portions div.image1 img');
+ var $image2 = jQuery('#mediamanager__diff div.imageDiff.portions div.image2 img');
+ if (!$image1.length || !$image2.length) return;
+
+ var $div = jQuery("#mediamanager__diff");
+ if (!$div.length) return;
+
+ $div.width('100%');
+ $image2.parent().width('97%');
+ $image1.width('100%');
+ $image2.width('100%');
+
+ if ($image1.width() < $div.width()) {
+ $div.width($image1.width());
+ }
+
+ $image2.parent().width('50%');
+ $image2.width($image1.width());
+ $image1.width($image1.width());
+
+ var $slider = jQuery("#mediamanager__diff div.slider");
+ if (!$slider.length) return;
+ $slider.width($image1.width()-20);
+
+ $slider.slider();
+ $slider.slider("option", "min", 0);
+ $slider.slider("option", "max", 97);
+ $slider.slider("option", "step", 1);
+ $slider.slider("option", "value", 50);
+ $slider.bind("slide", function(event, ui) {
+ jQuery('#mediamanager__diff div.imageDiff.portions div.image2').css({ width: $slider.slider("option", "value")+'%'});
+ });
+ },
+
+ /**
+ * Parse a URI query string to an associative array
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ params_toarray: function (str) {
+ var vars = [], hash;
+ var hashes = str.split('&');
+ for(var i = 0; i < hashes.length; i++) {
+ hash = hashes[i].split('=');
+ vars[decodeURIComponent(hash[0])] = decodeURIComponent(hash[1]);
+ }
+ return vars;
+ },
+
+ init_ajax_uploader: function () {
+ if (!jQuery('#mediamanager__uploader').length) return;
+ if (jQuery('.qq-upload-list').length) return;
+
+ var params = dw_mediamanager.form_params(jQuery('#dw__upload'))+'&call=mediaupload';
+ params = dw_mediamanager.params_toarray(params);
+
+ var uploader = new qq.FileUploaderExtended({
+ element: document.getElementById('mediamanager__uploader'),
+ action: DOKU_BASE + 'lib/exe/ajax.php',
+ params: params
+ });
+ },
+
+ prepare_content: function ($content) {
+ // hide syntax example
+ $content.find('div.example:visible').hide();
+ },
+
+ /**
+ * shows the popup for a image link
+ */
+ select: function(event){
+ var $link, id, dot, ext;
+
+ event.preventDefault();
+
+ $link = jQuery(this);
+ id = $link.attr('name').substr(2);
+
+ if(!opener){
+ // if we don't run in popup display example
+ // the id's are a bit wierd and jQuery('#ex_wiki_dokuwiki-128.png')
+ // will not be found by Sizzle (the CSS Selector Engine
+ // used by jQuery), hence the document.getElementById() call
+ jQuery(document.getElementById('ex_'+id.replace(/:/g,'_').replace(/^_/,''))).dw_toggle();
+ return;
+ }
+
+ dw_mediamanager.ext = false;
+ dot = id.lastIndexOf(".");
+
+ if (-1 === dot) {
+ dw_mediamanager.insert(id);
+ return;
+ }
+
+ ext = id.substr(dot);
+
+ if ({'.jpg':1, '.jpeg':1, '.png':1, '.gif':1, '.swf':1}[ext] !== 1) {
+ dw_mediamanager.insert(id);
+ return;
+ }
+
+ // remove old callback from the insert button and set the new one.
+ jQuery('#media__sendbtn').unbind().click(bind(dw_mediamanager.insert, id));
+
+ dw_mediamanager.unforbid('ext');
+ if (ext === '.swf') {
+ dw_mediamanager.ext = 'swf';
+ dw_mediamanager.forbid('ext', {link: ['1', '2'],
+ size: ['4']});
+ } else {
+ dw_mediamanager.ext = 'img';
+ }
+
+ // Set to defaults
+ dw_mediamanager.setOpt('link');
+ dw_mediamanager.setOpt('align');
+ dw_mediamanager.setOpt('size');
+
+ // toggle buttons for detail and linked image, original size
+ jQuery('#media__linkbtn1, #media__linkbtn2, #media__sizebtn4')
+ .toggle(dw_mediamanager.ext === 'img');
+
+ dw_mediamanager.$popup.dialog('open');
+
+ jQuery('#media__sendbtn').focus();
+ },
+
+ /**
+ * Deletion confirmation dialog to the delete buttons.
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ confirmattach: function(e){
+ if(!confirm(LANG.del_confirm + "\n" + jQuery(this).attr('title'))) {
+ e.preventDefault();
+ }
+ },
+
+ /**
+ * Creates checkboxes for additional options
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ attachoptions: function(){
+ var $obj, opts;
+
+ $obj = jQuery('#media__opts');
+ if($obj.length === 0) {
+ return;
+ }
+
+ opts = [];
+ // keep open
+ if(opener){
+ opts.push(['keepopen', 'keepopen']);
+ }
+ opts.push(['hide', 'hidedetails']);
+
+ jQuery.each(opts,
+ function(_, opt) {
+ var $box, $lbl;
+ $box = jQuery(document.createElement('input'))
+ .attr('type', 'checkbox')
+ .attr('id', 'media__' + opt[0])
+ .click(bind(dw_mediamanager.toggleOption,
+ opt[0]));
+
+ if(DokuCookie.getValue(opt[0])){
+ $box.prop('checked', true);
+ dw_mediamanager[opt[0]] = true;
+ }
+
+ $lbl = jQuery(document.createElement('label'))
+ .attr('for', 'media__' + opt[0])
+ .text(LANG[opt[1]]);
+
+ $obj.append($box, $lbl, document.createElement('br'));
+ });
+
+ dw_mediamanager.updatehide();
+ },
+
+ /**
+ * Generalized toggler
+ *
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ toggleOption: function (variable) {
+ if (jQuery(this).prop('checked')) {
+ DokuCookie.setValue(variable, 1);
+ dw_mediamanager[variable] = true;
+ } else {
+ DokuCookie.setValue(variable, '');
+ dw_mediamanager[variable] = false;
+ }
+ if (variable === 'hide') {
+ dw_mediamanager.updatehide();
+ }
+ },
+
+ /**
+ * Sets the visibility of the image details accordingly to the
+ * chosen hide state
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ updatehide: function(){
+ jQuery('#media__content div.detail').dw_toggle(!dw_mediamanager.hide);
+ },
+
+ /**
+ * set media insertion option
+ *
+ * @author Dominik Eckelmann <eckelmann@cosmocode.de>
+ */
+ setOpt: function(opt, e){
+ var val, i;
+ if (typeof e !== 'undefined') {
+ val = this.id.substring(this.id.length - 1);
+ } else {
+ val = dw_mediamanager.getOpt(opt);
+ }
+
+ if (val === false) {
+ DokuCookie.setValue(opt,'');
+ dw_mediamanager[opt] = false;
+ return;
+ }
+
+ if (opt === 'link') {
+ if (val !== '4' && dw_mediamanager.link === '4') {
+ dw_mediamanager.unforbid('linkonly');
+ dw_mediamanager.setOpt('align');
+ dw_mediamanager.setOpt('size');
+ } else if (val === '4') {
+ dw_mediamanager.forbid('linkonly', {align: false, size: false});
+ }
+
+ jQuery("#media__size, #media__align").dw_toggle(val !== '4');
+ }
+
+ DokuCookie.setValue(opt, val);
+ dw_mediamanager[opt] = val;
+
+ for (i = 1; i <= 4; i++) {
+ jQuery("#media__" + opt + "btn" + i).removeClass('selected');
+ }
+ jQuery('#media__' + opt + 'btn' + val).addClass('selected');
+ },
+
+ unforbid: function (group) {
+ delete dw_mediamanager.forbidden_opts[group];
+ },
+
+ forbid: function (group, forbids) {
+ dw_mediamanager.forbidden_opts[group] = forbids;
+ },
+
+ allowedOpt: function (opt, val) {
+ var ret = true;
+ jQuery.each(dw_mediamanager.forbidden_opts,
+ function (_, forbids) {
+ ret = forbids[opt] !== false &&
+ jQuery.inArray(val, forbids[opt]) === -1;
+ return ret;
+ });
+ return ret;
+ },
+
+ getOpt: function (opt) {
+ var allowed = bind(dw_mediamanager.allowedOpt, opt);
+
+ // Current value
+ if (dw_mediamanager[opt] !== false && allowed(dw_mediamanager[opt])) {
+ return dw_mediamanager[opt];
+ }
+
+ // From cookie
+ if (DokuCookie.getValue(opt) && allowed(DokuCookie.getValue(opt))) {
+ return DokuCookie.getValue(opt);
+ }
+
+ // size default
+ if (opt === 'size' && allowed('2')) {
+ return '2';
+ }
+
+ // Whatever is allowed, and be it false
+ return jQuery.grep(['1', '2', '3', '4'], allowed)[0] || false;
+ }
+};
+
+// moved from helpers.js temporarily here
+/**
+ * Very simplistic Flash plugin check, probably works for Flash 8 and higher only
+ *
+ */
+function hasFlash(version){
+ var ver = 0, axo;
+ try{
+ if(navigator.plugins !== null && navigator.plugins.length > 0){
+ ver = navigator.plugins["Shockwave Flash"].description.split(' ')[2].split('.')[0];
+ }else{
+ axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+ ver = axo.GetVariable("$version").split(' ')[1].split(',')[0];
+ }
+ }catch(e){ }
+
+ return ver >= version;
+}
+
+jQuery(dw_mediamanager.init);
diff --git a/lib/scripts/page.js b/lib/scripts/page.js
new file mode 100644
index 000000000..5da4a9cc0
--- /dev/null
+++ b/lib/scripts/page.js
@@ -0,0 +1,141 @@
+/**
+ * Page behaviours
+ *
+ * This class adds various behaviours to the rendered page
+ */
+dw_page = {
+ /**
+ * initialize page behaviours
+ */
+ init: function(){
+ dw_page.sectionHighlight();
+ jQuery('a.fn_top').mouseover(dw_page.footnoteDisplay);
+ dw_page.initTocToggle();
+ },
+
+ /**
+ * Highlight the section when hovering over the appropriate section edit button
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ sectionHighlight: function() {
+ jQuery('form.btn_secedit')
+ .mouseover(function(){
+ var $tgt = jQuery(this).parent(),
+ nr = $tgt.attr('class').match(/(\s+|^)editbutton_(\d+)(\s+|$)/)[2];
+
+ // Walk the DOM tree up (first previous siblings, then parents)
+ // until boundary element
+ while($tgt.length > 0 && !$tgt.hasClass('sectionedit' + nr)) {
+ // $.last gives the DOM-ordered last element:
+ // prev if present, else parent.
+ $tgt = $tgt.prev().add($tgt.parent()).last();
+ $tgt.addClass('section_highlight');
+ }
+ })
+ .mouseout(function(){
+ jQuery('.section_highlight').removeClass('section_highlight');
+ });
+ },
+
+ /**
+ * Create/get a insitu popup used by the footnotes
+ *
+ * @param target - the DOM element at which the popup should be aligned at
+ * @param popup_id - the ID of the (new) DOM popup
+ * @return the Popup jQuery object
+ */
+ insituPopup: function(target, popup_id) {
+ // get or create the popup div
+ var $fndiv = jQuery('#' + popup_id);
+
+ // popup doesn't exist, yet -> create it
+ if($fndiv.length === 0){
+ $fndiv = jQuery(document.createElement('div'))
+ .attr('id', popup_id)
+ .addClass('insitu-footnote JSpopup')
+ .mouseleave(function () {jQuery(this).hide();});
+ jQuery('.dokuwiki:first').append($fndiv);
+ }
+
+ // position() does not support hidden elements
+ $fndiv.show().position({
+ my: 'left top',
+ at: 'left center',
+ of: target
+ }).hide();
+
+ return $fndiv;
+ },
+
+ /**
+ * Display an insitu footnote popup
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+ footnoteDisplay: function () {
+ var content = jQuery(jQuery(this).attr('href')) // Footnote text anchor
+ .closest('div.fn').html();
+
+ if (content === null){
+ return;
+ }
+
+ // strip the leading content anchors and their comma separators
+ content = content.replace(/((^|\s*,\s*)<sup>.*?<\/sup>)+\s*/gi, '');
+
+ // prefix ids on any elements with "insitu__" to ensure they remain unique
+ content = content.replace(/\bid=(['"])([^"']+)\1/gi,'id="insitu__$2');
+
+ // now put the content into the wrapper
+ dw_page.insituPopup(this, 'insitu__fn').html(content).show();
+ },
+
+ /**
+ * Adds the toggle switch to the TOC
+ */
+ initTocToggle: function() {
+ var $header, $clicky, $toc, $tocul, setClicky;
+ $header = jQuery('#toc__header');
+ if(!$header.length) {
+ return;
+ }
+ $toc = jQuery('#toc__inside');
+ $tocul = $toc.children('ul.toc');
+
+ setClicky = function(hiding){
+ if(hiding){
+ $clicky.html('<span>+</span>');
+ $clicky[0].className = 'toc_open';
+ }else{
+ $clicky.html('<span>&minus;</span>');
+ $clicky[0].className = 'toc_close';
+ }
+ };
+
+ $clicky = jQuery(document.createElement('span'))
+ .attr('id','toc__toggle');
+ $header.css('cursor','pointer')
+ .click(function () {
+ var hidden;
+
+ // Assert that $toc instantly takes the whole TOC space
+ $toc.css('height', $toc.height()).show();
+
+ hidden = $tocul.stop(true, true).is(':hidden');
+
+ setClicky(!hidden);
+
+ // Start animation and assure that $toc is hidden/visible
+ $tocul.dw_toggle(hidden, function () {
+ $toc.toggle(hidden);
+ });
+ })
+ .prepend($clicky);
+
+ setClicky();
+ }
+};
+
+jQuery(dw_page.init);
diff --git a/lib/scripts/qsearch.js b/lib/scripts/qsearch.js
new file mode 100644
index 000000000..a309f9e29
--- /dev/null
+++ b/lib/scripts/qsearch.js
@@ -0,0 +1,146 @@
+/**
+ * AJAX functions for the pagename quicksearch
+ *
+ * @license GPL2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @author Michal Rezler <m.rezler@centrum.cz>
+ */
+
+var dw_qsearch = {
+
+ $inObj: null,
+ $outObj: null,
+ timer: null,
+
+ /**
+ * initialize the quick search
+ *
+ * Attaches the event handlers
+ *
+ * @param input element (jQuery selector/DOM obj)
+ * @param output element (jQuery selector/DOM obj)
+ */
+ init: function (input, output) {
+ var do_qsearch;
+
+ dw_qsearch.$inObj = jQuery(input);
+ dw_qsearch.$outObj = jQuery(output);
+
+ // objects found?
+ if (dw_qsearch.$inObj.length === 0 ||
+ dw_qsearch.$outObj.length === 0) {
+ return;
+ }
+
+ // attach eventhandler to search field
+ do_qsearch = function () {
+ dw_qsearch.clear_results();
+ var value = dw_qsearch.$inObj.val();
+ if (value === '') {
+ return;
+ }
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'qsearch',
+ q: encodeURI(value)
+ },
+ dw_qsearch.onCompletion,
+ 'html'
+ );
+ };
+
+ dw_qsearch.$inObj.keyup(
+ function() {
+ if(dw_qsearch.timer){
+ window.clearTimeout(dw_qsearch.timer);
+ dw_qsearch.timer = null;
+ }
+ dw_qsearch.clear_results();
+ dw_qsearch.timer = window.setTimeout(do_qsearch, 500);
+ }
+ );
+
+ // attach eventhandler to output field
+ dw_qsearch.$outObj.click(dw_qsearch.clear_results);
+ },
+
+ /**
+ * Empty and hide the output div
+ */
+ clear_results: function(){
+ dw_qsearch.$outObj.hide();
+ dw_qsearch.$outObj.text('');
+ },
+
+ /**
+ * Callback. Reformat and display the results.
+ *
+ * Namespaces are shortened here to keep the results from overflowing
+ * or wrapping
+ *
+ * @param data The result HTML
+ */
+ onCompletion: function(data) {
+ var max, $links, too_big;
+
+ if (data === '') { return; }
+
+ dw_qsearch.$outObj
+ .html(data)
+ .show()
+ .css('white-space', 'nowrap');
+
+ // shorten namespaces if too long
+ max = dw_qsearch.$outObj[0].clientWidth;
+ $links = dw_qsearch.$outObj.find('a');
+ too_big = (document.documentElement.dir === 'rtl')
+ ? function (l) { return l.offsetLeft < 0; }
+ : function (l) { return l.offsetWidth + l.offsetLeft > max; };
+
+ $links.each(function () {
+ var start, length, replace, nsL, nsR, eli, runaway;
+
+ if (!too_big(this)) {
+ return;
+ }
+
+ nsL = this.innerText.indexOf('(');
+ nsR = this.innerText.indexOf(')');
+ eli = 0;
+ runaway = 0;
+
+ while((nsR - nsL > 3) && too_big(this) && runaway++ < 500) {
+ if(eli !== 0){
+ // elipsis already inserted
+ if( (eli - nsL) > (nsR - eli) ){
+ // cut left
+ start = eli - 2;
+ length = 2;
+ }else{
+ // cut right
+ start = eli + 1;
+ length = 1;
+ }
+ replace = '';
+ }else{
+ // replace middle with ellipsis
+ start = Math.floor( nsL + ((nsR-nsL)/2) );
+ length = 1;
+ replace = '…';
+ }
+ this.innerText = substr_replace(this.innerText,
+ replace, start, length);
+
+ eli = this.innerText.indexOf('…');
+ nsL = this.innerText.indexOf('(');
+ nsR = this.innerText.indexOf(')');
+ }
+ });
+ }
+};
+
+jQuery(function () {
+ dw_qsearch.init('#qsearch__in','#qsearch__out');
+});
diff --git a/lib/scripts/script.js b/lib/scripts/script.js
new file mode 100644
index 000000000..5fddb0431
--- /dev/null
+++ b/lib/scripts/script.js
@@ -0,0 +1,63 @@
+// if jQuery was loaded, let's make it noConflict here.
+if ('function' === typeof jQuery && 'function' === typeof jQuery.noConflict) {
+ jQuery.noConflict();
+}
+
+/**
+ * Some browser detection
+ */
+var clientPC = navigator.userAgent.toLowerCase(); // Get client info
+var is_macos = navigator.appVersion.indexOf('Mac') != -1;
+var is_gecko = ((clientPC.indexOf('gecko')!=-1) && (clientPC.indexOf('spoofer')==-1) &&
+ (clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0')==-1));
+var is_safari = ((clientPC.indexOf('applewebkit')!=-1) && (clientPC.indexOf('spoofer')==-1));
+var is_khtml = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ));
+if (clientPC.indexOf('opera')!=-1) {
+ var is_opera = true;
+ var is_opera_preseven = (window.opera && !document.childNodes);
+ var is_opera_seven = (window.opera && document.childNodes);
+}
+
+/**
+ * Prints a animated gif to show the search is performed
+ *
+ * Because we need to modify the DOM here before the document is loaded
+ * and parsed completely we have to rely on document.write()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function showLoadBar(){
+
+ document.write('<img src="'+DOKU_BASE+'lib/images/loading.gif" '+
+ 'width="150" height="12" alt="..." />');
+
+ /* this does not work reliable in IE
+ obj = $(id);
+
+ if(obj){
+ obj.innerHTML = '<img src="'+DOKU_BASE+'lib/images/loading.gif" '+
+ 'width="150" height="12" alt="..." />';
+ obj.style.display="block";
+ }
+ */
+}
+
+/**
+ * Disables the animated gif to show the search is done
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function hideLoadBar(id){
+ jQuery('#' + id).hide();
+}
+
+/**
+ * Handler to close all open Popups
+ */
+function closePopups(){
+ jQuery('div.JSpopup').hide();
+}
+
+jQuery(function () {
+ jQuery(document).click(closePopups);
+});
diff --git a/lib/scripts/textselection.js b/lib/scripts/textselection.js
new file mode 100644
index 000000000..bd80e9341
--- /dev/null
+++ b/lib/scripts/textselection.js
@@ -0,0 +1,233 @@
+/**
+ * Text selection related functions.
+ */
+
+/**
+ * selection prototype
+ *
+ * Object that capsulates the selection in a textarea. Returned by getSelection.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function selection_class(){
+ this.start = 0;
+ this.end = 0;
+ this.obj = null;
+ this.rangeCopy = null;
+ this.scroll = 0;
+ this.fix = 0;
+
+ this.getLength = function(){
+ return this.end - this.start;
+ };
+
+ this.getText = function(){
+ return (!this.obj) ? '' : this.obj.value.substring(this.start,this.end);
+ };
+}
+
+/**
+ * Get current selection/cursor position in a given textArea
+ *
+ * @link http://groups.drupal.org/node/1210
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @link http://linebyline.blogspot.com/2006/11/textarea-cursor-position-in-internet.html
+ * @returns object - a selection object
+ */
+function getSelection(textArea) {
+ var sel = new selection_class();
+
+ sel.obj = textArea;
+ sel.start = textArea.value.length;
+ sel.end = textArea.value.length;
+ textArea.focus();
+ if(document.getSelection) { // Mozilla et al.
+ sel.start = textArea.selectionStart;
+ sel.end = textArea.selectionEnd;
+ sel.scroll = textArea.scrollTop;
+ } else if(document.selection) { // MSIE
+ /*
+ * This huge lump of code is neccessary to work around two MSIE bugs:
+ *
+ * 1. Selections trim newlines at the end of the code
+ * 2. Selections count newlines as two characters
+ */
+
+ // The current selection
+ sel.rangeCopy = document.selection.createRange().duplicate();
+ if (textArea.tagName === 'INPUT') {
+ var before_range = textArea.createTextRange();
+ before_range.expand('textedit'); // Selects all the text
+ } else {
+ var before_range = document.body.createTextRange();
+ before_range.moveToElementText(textArea); // Selects all the text
+ }
+ before_range.setEndPoint("EndToStart", sel.rangeCopy); // Moves the end where we need it
+
+ var before_finished = false, selection_finished = false;
+ var before_text, selection_text;
+ // Load the text values we need to compare
+ before_text = before_range.text;
+ selection_text = sel.rangeCopy.text;
+
+ sel.start = before_text.length;
+ sel.end = sel.start + selection_text.length;
+
+ // Check each range for trimmed newlines by shrinking the range by 1 character and seeing
+ // if the text property has changed. If it has not changed then we know that IE has trimmed
+ // a \r\n from the end.
+ do {
+ if (!before_finished) {
+ if (before_range.compareEndPoints("StartToEnd", before_range) == 0) {
+ before_finished = true;
+ } else {
+ before_range.moveEnd("character", -1);
+ if (before_range.text == before_text) {
+ sel.start += 2;
+ sel.end += 2;
+ } else {
+ before_finished = true;
+ }
+ }
+ }
+ if (!selection_finished) {
+ if (sel.rangeCopy.compareEndPoints("StartToEnd", sel.rangeCopy) == 0) {
+ selection_finished = true;
+ } else {
+ sel.rangeCopy.moveEnd("character", -1);
+ if (sel.rangeCopy.text == selection_text) {
+ sel.end += 2;
+ } else {
+ selection_finished = true;
+ }
+ }
+ }
+ } while ((!before_finished || !selection_finished));
+
+
+ // count number of newlines in str to work around stupid IE selection bug
+ var countNL = function(str) {
+ var m = str.split("\r\n");
+ if (!m || !m.length) return 0;
+ return m.length-1;
+ };
+ sel.fix = countNL(sel.obj.value.substring(0,sel.start));
+
+ }
+ return sel;
+}
+
+/**
+ * Set the selection
+ *
+ * You need to get a selection object via getSelection() first, then modify the
+ * start and end properties and pass it back to this function.
+ *
+ * @link http://groups.drupal.org/node/1210
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param object selection - a selection object as returned by getSelection()
+ */
+function setSelection(selection){
+ if(document.getSelection){ // FF
+ // what a pleasure in FF ;)
+ selection.obj.setSelectionRange(selection.start,selection.end);
+ if(selection.scroll) selection.obj.scrollTop = selection.scroll;
+ } else if(document.selection) { // IE
+ selection.rangeCopy.collapse(true);
+ selection.rangeCopy.moveStart('character',selection.start - selection.fix);
+ selection.rangeCopy.moveEnd('character',selection.end - selection.start);
+ selection.rangeCopy.select();
+ }
+}
+
+/**
+ * Inserts the given text at the current cursor position or replaces the current
+ * selection
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string text - the new text to be pasted
+ * @param objct selecttion - selection object returned by getSelection
+ * @param int opts.startofs - number of charcters at the start to skip from new selection
+ * @param int opts.endofs - number of characters at the end to skip from new selection
+ * @param bool opts.nosel - set true if new text should not be selected
+ */
+function pasteText(selection,text,opts){
+ if(!opts) opts = {};
+ // replace the content
+
+ selection.obj.value =
+ selection.obj.value.substring(0, selection.start) + text +
+ selection.obj.value.substring(selection.end, selection.obj.value.length);
+
+ // set new selection
+ if (is_opera) {
+ // Opera replaces \n by \r\n when inserting text.
+ selection.end = selection.start + text.replace(/\r?\n/g, '\r\n').length;
+ } else {
+ selection.end = selection.start + text.length;
+ }
+
+ // modify the new selection if wanted
+ if(opts.startofs) selection.start += opts.startofs;
+ if(opts.endofs) selection.end -= opts.endofs;
+
+ // no selection wanted? set cursor to end position
+ if(opts.nosel) selection.start = selection.end;
+
+ setSelection(selection);
+}
+
+
+/**
+ * Format selection
+ *
+ * Apply tagOpen/tagClose to selection in textarea, use sampleText instead
+ * of selection if there is none.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function insertTags(textAreaID, tagOpen, tagClose, sampleText){
+ var txtarea = jQuery('#' + textAreaID)[0];
+
+ var selection = getSelection(txtarea);
+ var text = selection.getText();
+ var opts;
+
+ // don't include trailing space in selection
+ if(text.charAt(text.length - 1) == ' '){
+ selection.end--;
+ text = selection.getText();
+ }
+
+ if(!text){
+ // nothing selected, use the sample text and select it
+ text = sampleText;
+ opts = {
+ startofs: tagOpen.length,
+ endofs: tagClose.length
+ };
+ }else{
+ // place cursor at the end
+ opts = {
+ nosel: true
+ };
+ }
+
+ // surround with tags
+ text = tagOpen + text + tagClose;
+
+ // do it
+ pasteText(selection,text,opts);
+}
+
+/**
+ * Wraps around pasteText() for backward compatibility
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function insertAtCarret(textAreaID, text){
+ var txtarea = jQuery('#' + textAreaID)[0];
+ var selection = getSelection(txtarea);
+ pasteText(selection,text,{nosel: true});
+}
+
diff --git a/lib/scripts/toolbar.js b/lib/scripts/toolbar.js
new file mode 100644
index 000000000..04d30c1a6
--- /dev/null
+++ b/lib/scripts/toolbar.js
@@ -0,0 +1,255 @@
+// used to identify pickers
+var pickercounter=0;
+
+/**
+ * Create a toolbar
+ *
+ * @param string tbid ID of the element where to insert the toolbar
+ * @param string edid ID of the editor textarea
+ * @param array tb Associative array defining the buttons
+ * @param bool allowblock Allow buttons creating multiline content
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function initToolbar(tbid,edid,tb, allowblock){
+ var $toolbar, $edit;
+ if (typeof tbid == 'string') {
+ $toolbar = jQuery('#' + tbid);
+ } else {
+ $toolbar = jQuery(tbid);
+ }
+
+ $edit = jQuery('#' + edid);
+
+ if ($toolbar.length == 0 || $edit.length == 0 || $edit.attr('readOnly')) {
+ return;
+ }
+
+ if (typeof allowblock === 'undefined') {
+ allowblock = true;
+ }
+
+ //empty the toolbar area:
+ $toolbar.html('');
+
+ jQuery.each(tb, function (k, val) {
+ if (!tb.hasOwnProperty(k) || (!allowblock && val.block === true)) {
+ return;
+ }
+ var actionFunc, $btn;
+
+ // create new button (jQuery object)
+ $btn = jQuery(createToolButton(val.icon, val.title, val.key, val.id,
+ val['class']));
+
+ // type is a tb function -> assign it as onclick
+ actionFunc = 'tb_'+val.type;
+ if( jQuery.isFunction(window[actionFunc]) ){
+ $btn.bind('click', bind(window[actionFunc],$btn,val,edid) );
+ $toolbar.append($btn);
+ return;
+ }
+
+ // type is a init function -> execute it
+ actionFunc = 'addBtnAction'+val.type.charAt(0).toUpperCase()+val.type.substring(1);
+ if( jQuery.isFunction(window[actionFunc]) ){
+ if(window[actionFunc]($btn, val, edid)){
+ $toolbar.append($btn);
+ }
+ return;
+ }
+
+ alert('unknown toolbar type: '+val.type+' '+actionFunc);
+ });
+}
+
+/**
+ * Button action for format buttons
+ *
+ * @param DOMElement btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @author Gabriel Birke <birke@d-scribe.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tb_format(btn, props, edid) {
+ var sample = props.title || props.sample;
+ insertTags(edid,
+ fixtxt(props.open),
+ fixtxt(props.close),
+ fixtxt(sample));
+ pickerClose();
+ return false;
+}
+
+/**
+ * Button action for format buttons
+ *
+ * This works exactly as tb_format() except that, if multiple lines
+ * are selected, each line will be formatted seperately
+ *
+ * @param DOMElement btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @author Gabriel Birke <birke@d-scribe.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tb_formatln(btn, props, edid) {
+ var sample = props.title || props.sample,
+ opts,
+ selection = getSelection(jQuery('#'+edid)[0]);
+
+ sample = fixtxt(sample);
+ props.open = fixtxt(props.open);
+ props.close = fixtxt(props.close);
+
+ // is something selected?
+ if(selection.getLength()){
+ sample = selection.getText();
+ opts = {nosel: true};
+ }else{
+ opts = {
+ startofs: props.open.length,
+ endofs: props.close.length
+ };
+ }
+
+ sample = sample.split("\n").join(props.close+"\n"+props.open);
+ sample = props.open+sample+props.close;
+
+ pasteText(selection,sample,opts);
+
+ pickerClose();
+ return false;
+}
+
+/**
+ * Button action for insert buttons
+ *
+ * @param DOMElement btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @author Gabriel Birke <birke@d-scribe.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tb_insert(btn, props, edid) {
+ insertAtCarret(edid,fixtxt(props.insert));
+ pickerClose();
+ return false;
+}
+
+/**
+ * Button action for the media popup
+ *
+ * @param DOMElement btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tb_mediapopup(btn, props, edid) {
+ window.open(
+ DOKU_BASE+props.url+encodeURIComponent(NS)+'&edid='+encodeURIComponent(edid),
+ props.name,
+ props.options);
+ return false;
+}
+
+/**
+ * Button action for automatic headlines
+ *
+ * Insert a new headline based on the current section level
+ *
+ * @param DOMElement btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tb_autohead(btn, props, edid){
+ var lvl = currentHeadlineLevel(edid),
+ tags;
+
+ // determine new level
+ lvl += props.mod;
+ if(lvl < 1) lvl = 1;
+ if(lvl > 5) lvl = 5;
+
+ tags = (new Array(8 - lvl)).join('=');
+ insertTags(edid, tags+' ', ' '+tags+"\n", props.text);
+ pickerClose();
+ return false;
+}
+
+
+/**
+ * Add button action for picker buttons and create picker element
+ *
+ * @param jQuery btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @return boolean If button should be appended
+ * @author Gabriel Birke <birke@d-scribe.de>
+ */
+function addBtnActionPicker($btn, props, edid) {
+ var pickerid = 'picker'+(pickercounter++);
+ createPicker(pickerid, props, edid);
+
+ $btn.click(
+ function() {
+ pickerToggle(pickerid,$btn);
+ return false;
+ }
+ );
+
+ return true;
+}
+
+/**
+ * Add button action for the link wizard button
+ *
+ * @param DOMElement btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @return boolean If button should be appended
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+function addBtnActionLinkwiz(btn, props, edid) {
+ dw_linkwiz.init(jQuery('#'+edid));
+ jQuery(btn).click(function(){
+ dw_linkwiz.toggle();
+ return false;
+ });
+ return true;
+}
+
+
+/**
+ * Show/Hide a previosly created picker window
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function pickerToggle(pickerid,$btn){
+ var $picker = jQuery('#' + pickerid),
+ pos = $btn.offset();
+ $picker.toggleClass('a11y')
+ .offset({left: pos.left+3, top: pos.top+$btn[0].offsetHeight+3});
+}
+
+/**
+ * Close all open pickers
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function pickerClose(){
+ jQuery('.picker').addClass('a11y');
+}
+
+
+/**
+ * Replaces \n with linebreaks
+ */
+function fixtxt(str){
+ return str.replace(/\\n/g,"\n");
+}
+
+jQuery(function () {
+ initToolbar('tool__bar','wiki__text',toolbar);
+});
diff --git a/lib/scripts/tree.js b/lib/scripts/tree.js
new file mode 100644
index 000000000..96763053d
--- /dev/null
+++ b/lib/scripts/tree.js
@@ -0,0 +1,93 @@
+jQuery.fn.dw_tree = function(overrides) {
+ var dw_tree = {
+
+ /**
+ * Delay in ms before showing the throbber.
+ * Used to skip the throbber for fast AJAX calls.
+ */
+ throbber_delay: 500,
+
+ $obj: this,
+
+ toggle_selector: 'a.idx_dir',
+
+ init: function () {
+ this.$obj.delegate(this.toggle_selector, 'click', this,
+ this.toggle);
+ },
+
+ /**
+ * Open or close a subtree using AJAX
+ * The contents of subtrees are "cached" until the page is reloaded.
+ * A "loading" indicator is shown only when the AJAX call is slow.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ toggle: function (e) {
+ var $listitem, $sublist, timeout, $clicky, show_sublist, dw_tree, opening;
+
+ e.preventDefault();
+
+ dw_tree = e.data;
+ $clicky = jQuery(this);
+ $listitem = $clicky.closest('li');
+ $sublist = $listitem.find('ul').first();
+ opening = $listitem.hasClass('closed');
+ $listitem.toggleClass('open closed');
+ dw_tree.toggle_display($clicky, opening);
+
+ // if already open, close by hiding the sublist
+ if (!opening) {
+ $sublist.dw_hide();
+ return;
+ }
+
+ show_sublist = function (data) {
+ $sublist.hide();
+ if (typeof data !== 'undefined') {
+ $sublist.html(data);
+ }
+ if ($listitem.hasClass('open')) {
+ // Only show if user didn’t close the list since starting
+ // to load the content
+ $sublist.dw_show();
+ }
+ };
+
+ // just show if already loaded
+ if ($sublist.length > 0) {
+ show_sublist();
+ return;
+ }
+
+ //prepare the new ul
+ $sublist = jQuery('<ul class="idx"/>');
+ $listitem.append($sublist);
+
+ timeout = window.setTimeout(
+ bind(show_sublist, '<li><img src="' + DOKU_BASE + 'lib/images/throbber.gif" alt="loading..." title="loading..." /></li>'), dw_tree.throbber_delay);
+
+ dw_tree.load_data(function (data) {
+ window.clearTimeout(timeout);
+ show_sublist(data);
+ }, $clicky);
+ },
+
+ toggle_display: function ($clicky, opening) {
+ },
+
+ load_data: function (show_data, $clicky) {
+ show_data();
+ }
+ };
+
+ jQuery.extend(dw_tree, overrides);
+
+ if (!overrides.deferInit) {
+ dw_tree.init();
+ }
+
+ return dw_tree;
+};
diff --git a/lib/scripts/tw-sack.js b/lib/scripts/tw-sack.js
new file mode 100644
index 000000000..cc988f5be
--- /dev/null
+++ b/lib/scripts/tw-sack.js
@@ -0,0 +1,139 @@
+/* Simple AJAX Code-Kit (SACK) */
+/* ©2005 Gregory Wild-Smith */
+/* www.twilightuniverse.com */
+/* Software licenced under a modified X11 licence, see documentation or authors website for more details */
+
+function sack(file){
+ this.AjaxFailedAlert = "Your browser does not support the enhanced functionality of this website, and therefore you will have an experience that differs from the intended one.\n";
+ this.requestFile = file;
+ this.method = "POST";
+ this.URLString = "";
+ this.encodeURIString = true;
+ this.execute = false;
+ this.asynchronous = true;
+
+ this.onLoading = function() { };
+ this.onLoaded = function() { };
+ this.onInteractive = function() { };
+ this.onCompletion = function() { };
+ this.afterCompletion = function() { };
+
+ this.createAJAX = function() {
+ try {
+ this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
+ } catch (e) {
+ try {
+ this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
+ } catch (err) {
+ this.xmlhttp = null;
+ }
+ }
+ if(!this.xmlhttp && typeof XMLHttpRequest != "undefined"){
+ this.xmlhttp = new XMLHttpRequest();
+ }
+ if (!this.xmlhttp){
+ this.failed = true;
+ }
+ };
+
+ this.setVar = function(name, value){
+ if (this.URLString.length < 3){
+ this.URLString = name + "=" + value;
+ } else {
+ this.URLString += "&" + name + "=" + value;
+ }
+ };
+
+ this.encVar = function(name, value){
+ var varString = encodeURIComponent(name) + "=" + encodeURIComponent(value);
+ return varString;
+ };
+
+ this.encodeURLString = function(string){
+ varArray = string.split('&');
+ for (i = 0; i < varArray.length; i++){
+ urlVars = varArray[i].split('=');
+ if (urlVars[0].indexOf('amp;') != -1){
+ urlVars[0] = urlVars[0].substring(4);
+ }
+ varArray[i] = this.encVar(urlVars[0],urlVars[1]);
+ }
+ return varArray.join('&');
+ };
+
+ this.runResponse = function(){
+ eval(this.response);
+ };
+
+ this.runAJAX = function(urlstring){
+ DEPRECATED('Please use jQuery.post() or any other of jQuery\'s AJAX methods.');
+
+ this.responseStatus = new Array(2);
+ if(this.failed && this.AjaxFailedAlert){
+ alert(this.AjaxFailedAlert);
+ } else {
+ if (urlstring){
+ if (this.URLString.length){
+ this.URLString = this.URLString + "&" + urlstring;
+ } else {
+ this.URLString = urlstring;
+ }
+ }
+ if (this.encodeURIString){
+ var timeval = new Date().getTime();
+ this.URLString = this.encodeURLString(this.URLString);
+ this.setVar("rndval", timeval);
+ }
+ if (this.element) { this.elementObj = document.getElementById(this.element); }
+ if (this.xmlhttp) {
+ var self = this;
+ if (this.method == "GET") {
+ var totalurlstring = this.requestFile + "?" + this.URLString;
+ this.xmlhttp.open(this.method, totalurlstring, this.asynchronous);
+ } else {
+ this.xmlhttp.open(this.method, this.requestFile, this.asynchronous);
+ }
+ if (this.method == "POST"){
+ try {
+ this.xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
+ } catch (e) {}
+ }
+
+ this.xmlhttp.onreadystatechange = function() {
+ switch (self.xmlhttp.readyState){
+ case 1:
+ self.onLoading();
+ break;
+ case 2:
+ self.onLoaded();
+ break;
+ case 3:
+ self.onInteractive();
+ break;
+ case 4:
+ self.response = self.xmlhttp.responseText;
+ self.responseXML = self.xmlhttp.responseXML;
+ self.responseStatus[0] = self.xmlhttp.status;
+ self.responseStatus[1] = self.xmlhttp.statusText;
+ self.onCompletion();
+ if(self.execute){ self.runResponse(); }
+ if (self.elementObj) {
+ var elemNodeName = self.elementObj.nodeName;
+ elemNodeName.toLowerCase();
+ if (elemNodeName == "input" || elemNodeName == "select" || elemNodeName == "option" || elemNodeName == "textarea"){
+ self.elementObj.value = self.response;
+ } else {
+ self.elementObj.innerHTML = self.response;
+ }
+ }
+ self.afterCompletion();
+ self.URLString = "";
+ break;
+ }
+ };
+ this.xmlhttp.send(this.URLString);
+ }
+ }
+ };
+this.createAJAX();
+}
diff --git a/lib/styles/all.css b/lib/styles/all.css
new file mode 100644
index 000000000..5d7eb7d14
--- /dev/null
+++ b/lib/styles/all.css
@@ -0,0 +1,65 @@
+/**
+ * Basic styles. These styles are needed for basic DokuWiki functions
+ * regardless of the used template. Templates can override them of course
+ */
+
+div.clearer {
+ clear: both;
+ font-size: 0;
+ line-height: 0;
+ height: 0;
+ overflow: hidden;
+}
+
+/* one of the many clearfix versions */
+.group {
+ display: inline-block;
+}
+.group {
+ display: block;
+}
+.group:before,
+.group:after {
+ content: "";
+ display: table;
+}
+.group:after {
+ clear: both;
+}
+
+div.no {
+ display: inline;
+ margin: 0;
+ padding: 0;
+}
+
+.hidden {
+ display: none;
+}
+
+/* image alignment */
+.medialeft {
+ float: left;
+}
+.mediaright {
+ float: right;
+}
+.mediacenter {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+/* table cell alignment */
+.leftalign { text-align: left; }
+.centeralign { text-align: center; }
+.rightalign { text-align: right; }
+
+/* underline */
+em.u {
+ font-style: normal;
+ text-decoration: underline;
+}
+em em.u {
+ font-style: italic;
+}
diff --git a/lib/styles/feed.css b/lib/styles/feed.css
new file mode 100644
index 000000000..44b72d770
--- /dev/null
+++ b/lib/styles/feed.css
@@ -0,0 +1,63 @@
+rss channel, feed, RDF {
+ font: 80% "Lucida Grande", Verdana, Lucida, Helvetica, Arial, sans-serif;
+ background-color: __background__;
+ color: __text__;
+ margin: 0;
+ padding: 0;
+}
+
+
+link, description, language, managingEditor, copyright, lastBuildDate, date,
+pubDate, generator, webMaster, ttl, docs, tagline, author, copyright,
+generator, content, created, issued, modified, subject, id, format, creator,
+category, image {
+ display: none;
+}
+
+item link, entry id {
+ display: block;
+ color: __extern__;
+ text-decoration: underline;
+}
+
+channel title, feed title {
+ display: block;
+ font-size: 200%;
+ font-weight: bolder;
+ color: __extern__;
+ text-decoration: none;
+ border-bottom: 20px solid __background_alt__;
+}
+
+:root:before {
+ content: "This data file is meant to be read in a XML feed reader. See document source."
+}
+
+item, entry {
+ display: block;
+ margin: 1em 180px 1em 1em;
+ border-bottom: 1px solid __border__;
+ padding-bottom: 1em;
+}
+
+item title, entry title {
+ display: block;
+ background: transparent none;
+ border: 0px solid __background_other__;
+ padding: 0;
+ color: __text_alt__;
+ font-size: 1.4em;
+ font-weight: bold;
+}
+
+item pubDate, entry modified, item date {
+ display: inline;
+ color: __text_neu__;
+ font: 1em trebuchet ms, arial, helvetica, sans-serif;
+}
+
+item description, entry summary {
+ display: block;
+ clear: both;
+ padding-top: 0.5em;
+}
diff --git a/lib/styles/index.html b/lib/styles/index.html
new file mode 100644
index 000000000..d614603ac
--- /dev/null
+++ b/lib/styles/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="refresh" content="0; URL=../../" />
+<meta name="robots" content="noindex" />
+<title>nothing here...</title>
+</head>
+<body>
+<!-- this is just here to prevent directory browsing -->
+</body>
+</html>
diff --git a/lib/styles/print.css b/lib/styles/print.css
new file mode 100644
index 000000000..76bc6d3bc
--- /dev/null
+++ b/lib/styles/print.css
@@ -0,0 +1,23 @@
+/**
+ * Basic styles. These styles are needed for basic DokuWiki functions
+ * regardless of the used template. Templates can override them of course
+ */
+
+/* messages with msg() */
+div.error,
+div.info,
+div.success,
+div.notify {
+ display: none;
+}
+
+/* section edit button */
+.secedit {
+ display: none;
+}
+
+/* modal windows */
+.JSpopup,
+#link__wiz {
+ display: none;
+}
diff --git a/lib/styles/screen.css b/lib/styles/screen.css
new file mode 100644
index 000000000..101ed3529
--- /dev/null
+++ b/lib/styles/screen.css
@@ -0,0 +1,103 @@
+/**
+ * Basic styles. These styles are needed for basic DokuWiki functions
+ * regardless of the used template. Templates can override them of course
+ */
+
+/* messages with msg() */
+div.error,
+div.info,
+div.success,
+div.notify {
+ color: #000;
+ background-repeat: no-repeat;
+ background-position: .5em 0;
+ border-bottom: 1px solid;
+ font-size: 90%;
+ margin: 0;
+ padding-left: 3em;
+ overflow: hidden;
+}
+
+div.error {
+ background-color: #fcc;
+ background-image: url(../images/error.png);
+ border-bottom-color: #faa;
+}
+
+div.info {
+ background-color: #ccf;
+ background-image: url(../images/info.png);
+ border-bottom-color: #aaf;
+}
+
+div.success {
+ background-color: #cfc;
+ background-image: url(../images/success.png);
+ border-bottom-color: #afa;
+}
+
+div.notify {
+ background-color: #ffc;
+ background-image: url(../images/notify.png);
+ border-bottom-color: #ffa;
+}
+
+/* modal windows */
+.JSpopup,
+#link__wiz {
+ position: absolute;
+ background-color: #fff;
+ color: #000;
+ z-index: 20;
+ overflow: hidden;
+}
+
+#link__wiz .ui-dialog-content {
+ padding-left: 0;
+ padding-right: 0;
+}
+
+/* media manager popup toggle buttons */
+
+#media__popup_content button.button {
+ border: 1px outset;
+}
+
+#media__popup_content button.selected {
+ border-style: inset;
+}
+
+/* hide something accessibly
+ (e.g. for screen readers or to keep access keys working) */
+.a11y {
+ position: absolute !important;
+ left: -10000px !important;
+ top: auto !important;
+ width: 1px !important;
+ height: 1px !important;
+ overflow: hidden !important;
+}
+
+/* syntax highlighting code */
+.code .br0 { color: #66cc66; }
+.code .co0 { color: #808080; font-style: italic; }
+.code .co1 { color: #808080; font-style: italic; }
+.code .co2 { color: #808080; font-style: italic; }
+.code .co3 { color: #808080; }
+.code .coMULTI { color: #808080; font-style: italic; }
+.code .es0 { color: #000099; font-weight: bold; }
+.code .kw1 { color: #b1b100; }
+.code .kw2 { color: #000000; font-weight: bold; }
+.code .kw3 { color: #000066; }
+.code .kw4 { color: #993333; }
+.code .kw5 { color: #0000ff; }
+.code .me1 { color: #006600; }
+.code .me2 { color: #006600; }
+.code .nu0 { color: #cc66cc; }
+.code .re0 { color: #0000ff; }
+.code .re1 { color: #0000ff; }
+.code .re2 { color: #0000ff; }
+.code .re3 { color: #ff3333; font-weight:bold; }
+.code .re4 { color: #009999; }
+.code .st0 { color: #ff0000; }
+.code .sy0 { color: #66cc66; }
diff --git a/lib/tpl/default/_admin.css b/lib/tpl/default/_admin.css
new file mode 100644
index 000000000..6c8066ba6
--- /dev/null
+++ b/lib/tpl/default/_admin.css
@@ -0,0 +1,48 @@
+#admin__version {
+ clear:left;
+ float: right;
+ color: __text_neu__;
+}
+
+.dokuwiki ul.admin_tasks {
+ font-size: 115%;
+ float: left;
+ width: 40%;
+ list-style-type: none;
+}
+
+.dokuwiki ul.admin_tasks li {
+ line-height: 22px;
+ padding-left: 35px;
+ margin: 1em 0;
+ background: transparent none no-repeat scroll 0 0;
+ text-align: left;
+}
+
+.dokuwiki ul.admin_tasks li div.li {
+ font-weight: bold;
+}
+
+.dokuwiki ul.admin_tasks li.admin_acl {
+ background-image: url(../../images/admin/acl.png);
+}
+
+.dokuwiki ul.admin_tasks li.admin_usermanager {
+ background-image: url(../../images/admin/usermanager.png);
+}
+
+.dokuwiki ul.admin_tasks li.admin_plugin {
+ background-image: url(../../images/admin/plugin.png);
+}
+
+.dokuwiki ul.admin_tasks li.admin_config {
+ background-image: url(../../images/admin/config.png);
+}
+
+.dokuwiki ul.admin_tasks li.admin_revert {
+ background-image: url(../../images/admin/revert.png);
+}
+
+.dokuwiki ul.admin_tasks li.admin_popularity {
+ background-image: url(../../images/admin/popularity.png);
+}
diff --git a/lib/tpl/default/_fileuploader.css b/lib/tpl/default/_fileuploader.css
new file mode 100644
index 000000000..d06bfd519
--- /dev/null
+++ b/lib/tpl/default/_fileuploader.css
@@ -0,0 +1,111 @@
+
+.qq-uploader {
+ position: relative;
+ width: 100%;
+}
+
+.qq-uploader .error {
+ color: #f00;
+ background-color: #fff;
+}
+
+/* select file button */
+
+.qq-upload-button {
+ display: inline-block;
+ border: 1px solid __border__;
+ color: __text__;
+ background: __background__ url(images/buttonshadow.png) repeat-x bottom;
+ text-decoration: none;
+ font-size: 100%;
+ cursor: pointer;
+ margin: 1px 1px 5px;
+ padding: 0.125em 0.4em;
+}
+
+* html .qq-upload-button,
+*+html .qq-upload-button {
+ display: inline;
+}
+
+.qq-upload-button-focus {
+ outline: 1px dotted;
+}
+
+/* drop area */
+
+.qq-upload-drop-area {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ min-height: 70px;
+ z-index: 2;
+ background: __background_neu__;
+ color: __text__;
+ text-align: center;
+}
+
+.qq-upload-drop-area span {
+ display: block;
+ position: absolute;
+ top: 50%;
+ width: 100%;
+ margin-top: -8px;
+ font-size: 120%;
+}
+
+.qq-upload-drop-area-active {
+ background: __background_alt__;
+}
+
+/* list of files to upload */
+
+div.qq-uploader ul {
+ margin: 0;
+ list-style: none;
+}
+
+.qq-uploader li {
+ margin-bottom: 5px;
+ color: __text__;
+}
+
+.qq-uploader li span,
+.qq-uploader li input,
+.qq-uploader li a {
+ margin-right: 5px;
+}
+
+.qq-upload-file {
+ display: block;
+ font-weight: bold;
+}
+
+.qq-upload-spinner {
+ display: inline-block;
+ background: url("../../images/throbber.gif");
+ width: 15px;
+ height: 15px;
+ vertical-align: text-bottom;
+}
+
+.qq-upload-size,
+.qq-upload-cancel {
+ font-size: 85%;
+}
+
+.qq-upload-failed-text {
+ display: none;
+}
+.qq-upload-fail .qq-upload-failed-text {
+ display: inline;
+}
+
+.qq-action-container * {
+ vertical-align: middle;
+}
+.qq-overwrite-check input {
+ margin-left: 10px;
+}
diff --git a/lib/tpl/default/_linkwiz.css b/lib/tpl/default/_linkwiz.css
new file mode 100644
index 000000000..ca8812867
--- /dev/null
+++ b/lib/tpl/default/_linkwiz.css
@@ -0,0 +1,40 @@
+#link__wiz {
+}
+
+#link__wiz_result {
+ background-color: __background__;
+ width: 293px;
+ height: 193px;
+ overflow: auto;
+ border: 1px solid __border__;
+ margin: 3px auto;
+ text-align: left;
+}
+
+#link__wiz_result div.type_u {
+ padding: 3px 3px 3px 22px;
+ background: transparent url(../../images/up.png) 3px 3px no-repeat;
+}
+
+#link__wiz_result div.type_f {
+ padding: 3px 3px 3px 22px;
+ background: transparent url(../../images/page.png) 3px 3px no-repeat;
+}
+
+#link__wiz_result div.type_d {
+ padding: 3px 3px 3px 22px;
+ background: transparent url(../../images/ns.png) 3px 3px no-repeat;
+}
+
+#link__wiz_result div.even {
+ background-color: __background_neu__;
+}
+
+#link__wiz_result div.selected {
+ background-color: __background_alt__;
+}
+
+#link__wiz_result span {
+ display: block;
+ color: __text_neu__;
+}
diff --git a/lib/tpl/default/_mediamanager.css b/lib/tpl/default/_mediamanager.css
new file mode 100644
index 000000000..68fa2e97f
--- /dev/null
+++ b/lib/tpl/default/_mediamanager.css
@@ -0,0 +1,432 @@
+
+/*____________ Layout ____________*/
+
+#mediamanager__page h1 {
+ margin: 0 0 .5em;
+}
+
+#mediamanager__page {
+ min-width: 800px;
+ width: 100%;
+ text-align: left;
+}
+
+#mediamanager__page .panel {
+ float: left;
+}
+
+#mediamanager__page .namespaces {
+ width: 15%;
+ min-width: 120px;
+}
+#mediamanager__page .filelist {
+ width: 50%;
+ min-width: 400px;
+}
+#mediamanager__page .file {
+ width: 35%;
+ min-width: 280px;
+}
+
+#mediamanager__page .panelHeader {
+ background-color: __background_alt__;
+ margin: 0 10px 10px 0;
+ padding: 10px 10px 8px;
+ text-align: left;
+ min-height: 20px;
+ overflow: hidden;
+}
+
+#mediamanager__page .panelContent {
+ overflow-y: auto;
+ overflow-x: hidden;
+ padding: 0;
+ margin: 0 10px 10px 0;
+ position: relative;
+}
+
+#mediamanager__page .file .panelHeader,
+#mediamanager__page .file .panelContent {
+ margin-right: 0;
+}
+
+#mediamanager__page .ui-resizable-e {
+ width: 6px;
+ right: 2px;
+ background: transparent url(images/resizecol.png) center center no-repeat;
+}
+#mediamanager__page .ui-resizable-e:hover {
+ background-color: __background_alt__;
+}
+
+
+/*____________ Namespaces tree ____________*/
+
+#mediamanager__page .namespaces h2 {
+ font-size: 1em;
+ display: inline-block;
+ border-width: 0;
+ padding: .3em .8em;
+ margin: 0 .3em 0 0;
+ border-radius: .5em .5em 0 0;
+ font-weight: normal;
+ background-color: __background_alt__;
+ color: __text__;
+ line-height: 1.5em;
+}
+* html #mediamanager__page .namespaces h2,
+*+html #mediamanager__page .namespaces h2 {
+ display: inline;
+}
+
+#mediamanager__page .namespaces ul {
+ margin-left: .2em;
+ list-style: none;
+}
+#mediamanager__page .namespaces ul ul {
+ margin-left: 1em;
+}
+
+#mediamanager__page .namespaces ul .selected {
+ background-color: __highlight__;
+ font-weight: bold;
+}
+
+/*____________ Panel header ____________*/
+
+#mediamanager__page .panelHeader h3 {
+ float: left;
+ font-weight: normal;
+ font-size: 1em;
+ padding: 0;
+ margin: 0 0 3px;
+}
+
+#mediamanager__page .panelHeader form.options {
+ float: right;
+ margin-top: -3px;
+}
+
+#mediamanager__page .panelHeader ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+#mediamanager__page .panelHeader ul li {
+ color: __text__;
+ float: left;
+ line-height: 1;
+ padding-left: 3px;
+}
+
+#mediamanager__page .panelHeader ul li.listType {
+ padding-left: 30px;
+ background: url('../../images/icon-list.png') 3px 1px no-repeat;
+}
+#mediamanager__page .panelHeader ul li.sortBy {
+ padding-left: 30px;
+ background: url('../../images/icon-sort.png') 3px 1px no-repeat;
+}
+
+#mediamanager__page .panelHeader form.options .ui-buttonset label{
+ font-size: 90%;
+ margin-right: -0.4em;
+}
+#mediamanager__page .panelHeader form.options .ui-buttonset .ui-button-text {
+ padding: .4em .7em;
+ line-height: 1;
+}
+
+/*____________ File list ____________*/
+
+#mediamanager__page .filelist ul {
+ padding: 0;
+ margin: 0;
+}
+
+#mediamanager__page .filelist .panelContent ul li:hover {
+ background-color: __background_alt__;
+}
+
+#mediamanager__page .filelist li dt a {
+ vertical-align: middle;
+ display: table-cell;
+ overflow: hidden;
+}
+* html #mediamanager__page .filelist .thumbs li dt a,
+*+html #mediamanager__page .filelist .thumbs li dt a {
+ display: block;
+}
+* html #mediamanager__page .filelist .rows li dt a,
+*+html #mediamanager__page .filelist .rows li dt a {
+ display: inline;
+}
+
+/* thumbs */
+
+#mediamanager__page .filelist .thumbs li {
+ width: 100px;
+ min-height: 130px;
+ display: inline-block;
+ display: -moz-inline-stack;
+ /* the right margin should visually be 10px, but because of its inline-block nature the whitespace inbetween is about 4px more */
+ margin: 0 6px 10px 0;
+ background-color: __background_neu__;
+ color: __text__;
+ padding: 5px;
+ vertical-align: top;
+ text-align: center;
+ position: relative;
+ line-height: 1.2;
+}
+* html #mediamanager__page .filelist .thumbs li,
+*+html #mediamanager__page .filelist .thumbs li {
+ display: inline;
+ zoom: 1;
+}
+
+#mediamanager__page .filelist .thumbs li dt a {
+ width: 100px;
+ height: 90px;
+}
+
+#mediamanager__page .filelist .thumbs li dt a img {
+ max-width: 90px;
+ max-height: 90px;
+}
+
+#mediamanager__page .filelist .thumbs li .name,
+#mediamanager__page .filelist .thumbs li .size,
+#mediamanager__page .filelist .thumbs li .filesize,
+#mediamanager__page .filelist .thumbs li .date {
+ display: block;
+ overflow: hidden;
+ width: 90px;
+ white-space: nowrap;
+}
+#mediamanager__page .filelist .thumbs li .name {
+ padding: 5px 0;
+ font-weight: bold;
+}
+#mediamanager__page .filelist .thumbs li .date {
+ font-style: italic;
+ white-space: normal;
+}
+
+/* rows */
+
+#mediamanager__page .filelist .rows li {
+ list-style: none;
+ display: block;
+ position: relative;
+ max-height: 50px;
+ margin: 0;
+ margin-bottom: 3px;
+ background-color: __background__;
+ color: __text__;
+ overflow: hidden;
+}
+
+#mediamanager__page .filelist .rows li:nth-child(2n+1) {
+ background-color: __background_neu__;
+}
+
+#mediamanager__page .filelist .rows li dt {
+ float: left;
+ width: 10%;
+ height: 40px;
+ text-align: center;
+}
+
+#mediamanager__page .filelist .rows li dt a {
+ width: 100px;
+ height: 40px;
+}
+
+#mediamanager__page .filelist .rows li dt a img {
+ max-width: 40px;
+ max-height: 40px;
+}
+
+#mediamanager__page .filelist .rows li .name,
+#mediamanager__page .filelist .rows li .size,
+#mediamanager__page .filelist .rows li .filesize,
+#mediamanager__page .filelist .rows li .date {
+ overflow: hidden;
+ float: left;
+ margin-left: 1%;
+ white-space: nowrap;
+}
+
+#mediamanager__page .filelist .rows li .name {
+ width: 30%;
+ font-weight: bold;
+}
+#mediamanager__page .filelist .rows li .size,
+#mediamanager__page .filelist .rows li .filesize {
+ width: 15%;
+}
+#mediamanager__page .filelist .rows li .date {
+ width: 20%;
+ font-style: italic;
+ white-space: normal;
+}
+
+/*____________ Upload panel ____________*/
+
+#mediamanager__page div.upload {
+ padding-bottom: 0.5em;
+}
+
+#media__content #mediamanager__uploader {
+ border-bottom: 1px solid __border__;
+ padding-bottom: 0.5em;
+}
+
+/*____________ File preview ____________*/
+
+#mediamanager__page .file ul.actions {
+ text-align: center;
+ margin: 0 0 5px;
+ list-style: none;
+}
+#mediamanager__page .file ul.actions li {
+ display: inline;
+}
+
+#mediamanager__page .file div.image {
+ margin-bottom: 5px;
+ text-align: center;
+}
+
+#mediamanager__page .file div.image img {
+ width: 100%;
+}
+
+#mediamanager__page .file dl {
+}
+#mediamanager__page .file dl dt {
+ font-weight: bold;
+ display: block;
+ background-color: __background_alt__;
+}
+#mediamanager__page .file dl dd {
+ display: block;
+ background-color: __background_neu__;
+}
+
+
+/*____________ Meta data edit form ____________*/
+
+#mediamanager__page form.meta div.row {
+ margin-bottom: 5px;
+}
+
+#mediamanager__page form.meta label span {
+ display: block;
+}
+
+#mediamanager__page form.meta input {
+ width: 50%;
+}
+
+#mediamanager__page form.meta input.button {
+ width: auto;
+}
+
+#mediamanager__page form.meta textarea.edit {
+ height: 6em;
+ width: 95%;
+ min-width: 95%;
+ max-width: 95%;
+}
+
+/*____________ Revisions form ____________*/
+
+#mediamanager__page #page__revisions ul {
+ margin-left: 10px;
+ list-style-type: none;
+}
+
+#mediamanager__page #page__revisions ul li div.li div {
+ font-size: 90%;
+ color: __text_neu__;
+ padding-left: 18px;
+}
+
+#mediamanager__page #page__revisions ul li div.li input {
+ position: relative;
+ top: 1px;
+}
+
+/* File diff */
+
+#mediamanager__diff table {
+ table-layout: fixed;
+}
+
+#mediamanager__diff td,
+#mediamanager__diff th {
+ width: 48%;
+ margin: 0 5px 10px 0;
+ padding: 0;
+ vertical-align: top;
+ text-align: left;
+}
+
+#mediamanager__diff th {
+ font-weight: normal;
+}
+#mediamanager__diff th a {
+ font-weight: bold;
+}
+#mediamanager__diff th span {
+ font-size: 90%;
+}
+
+#mediamanager__diff dl dd strong{
+ background-color: __highlight__;
+ color: __text__;
+ font-weight: normal;
+}
+
+/* Image diff */
+
+#mediamanager__page .file form.diffView {
+ margin-bottom: 10px;
+ display: block;
+}
+
+#mediamanager__diff div.slider {
+ margin: 10px;
+ width: 95%;
+}
+
+#mediamanager__diff .imageDiff {
+ position: relative;
+}
+#mediamanager__diff .imageDiff .image1,
+#mediamanager__diff .imageDiff .image2 {
+ width: 97%;
+}
+#mediamanager__diff .imageDiff .image2 {
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+#mediamanager__diff .imageDiff.opacity .image2 {
+ -moz-opacity: 0.5;
+ -khtml-opacity: 0.5;
+ opacity: 0.5;
+}
+
+#mediamanager__diff .imageDiff.portions .image2 {
+ border-right: 1px solid red;
+ overflow: hidden;
+}
+
+#mediamanager__diff .imageDiff img {
+ width: 100%;
+}
+
diff --git a/lib/tpl/default/_mediaoptions.css b/lib/tpl/default/_mediaoptions.css
new file mode 100644
index 000000000..81e87aa8e
--- /dev/null
+++ b/lib/tpl/default/_mediaoptions.css
@@ -0,0 +1,18 @@
+
+#media__popup_content p {
+ margin: 0 0 .5em;
+}
+
+#media__popup_content label {
+ float: left;
+ width: 9em;
+}
+
+#media__popup_content .button {
+ margin-right: 1px;
+ cursor: pointer;
+}
+
+#media__popup_content input.button {
+ margin-left: 9em;
+}
diff --git a/lib/tpl/default/_subscription.css b/lib/tpl/default/_subscription.css
new file mode 100644
index 000000000..0792c8c21
--- /dev/null
+++ b/lib/tpl/default/_subscription.css
@@ -0,0 +1,21 @@
+/**
+ * Styles for the subscription page
+ */
+
+form#subscribe__form {
+ display: block;
+ width: 300px;
+ text-align: center;
+}
+
+form#subscribe__form fieldset {
+ text-align: left;
+ margin: 0.5em 0;
+}
+
+form#subscribe__form label {
+ display:block;
+ margin: 0 0.5em 0.5em;
+}
+
+
diff --git a/lib/tpl/default/_tabs.css b/lib/tpl/default/_tabs.css
new file mode 100644
index 000000000..8bfb676a0
--- /dev/null
+++ b/lib/tpl/default/_tabs.css
@@ -0,0 +1,37 @@
+
+.dokuwiki ul.tabs {
+ padding: 0;
+ margin: 0;
+ overflow: hidden;
+}
+.dokuwiki ul.tabs li {
+ float: left;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+.dokuwiki ul.tabs li strong,
+.dokuwiki ul.tabs li a {
+ float: left;
+ padding: .3em .8em;
+ margin: 0 .3em 0 0;
+ background-color: __background_neu__;
+ color: __text__;
+ border-radius: .5em .5em 0 0;
+}
+.dokuwiki ul.tabs li strong {
+ font-weight: normal;
+}
+
+.dokuwiki ul.tabs li a:link,
+.dokuwiki ul.tabs li a:visited {
+}
+.dokuwiki ul.tabs li a:hover,
+.dokuwiki ul.tabs li a:active,
+.dokuwiki ul.tabs li a:focus,
+.dokuwiki ul.tabs li strong {
+ background-color: __background_alt__;
+ color: __text__;
+ text-decoration: none;
+}
diff --git a/lib/tpl/default/design.css b/lib/tpl/default/design.css
new file mode 100644
index 000000000..a94f814aa
--- /dev/null
+++ b/lib/tpl/default/design.css
@@ -0,0 +1,851 @@
+/**
+ * Design elements for default Template
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+
+/* -------------- general elements --------------- */
+
+* { padding: 0; margin: 0; }
+
+body {
+ font: 80% "Lucida Grande", Verdana, Lucida, Helvetica, Arial, sans-serif;
+ background-color: __background__;
+ color: __text__;
+}
+
+/* the document */
+div.dokuwiki div.page {
+ margin: 4px 2em 0 1em;
+ text-align: justify;
+}
+
+div.dokuwiki table {
+ font-size: 100%;
+}
+
+div.dokuwiki tr,
+div.dokuwiki td,
+div.dokuwiki th {
+}
+
+div.dokuwiki img {
+ border: 0;
+}
+
+div.dokuwiki p,
+div.dokuwiki blockquote,
+div.dokuwiki table,
+div.dokuwiki pre {
+ margin: 0 0 1.0em 0;
+}
+
+div.dokuwiki hr {
+ border: 0px;
+ border-top: 1px solid __border__;
+ text-align: center;
+ height: 0px;
+}
+
+div.dokuwiki div.nothing {
+ text-align: center;
+ margin: 2em;
+}
+
+/* ---------------- forms ------------------------ */
+
+div.dokuwiki form {
+ border: none;
+ display: inline;
+}
+
+div.dokuwiki label.block {
+ display: block;
+ text-align: right;
+ font-weight: bold;
+}
+
+div.dokuwiki label.simple {
+ display: block;
+ text-align: left;
+ font-weight: normal;
+}
+
+div.dokuwiki label.block input.edit {
+ width: 50%;
+}
+
+div.dokuwiki fieldset {
+ width: 300px;
+ text-align: center;
+ border: 1px solid __border__;
+ padding: 0.5em;
+ margin: auto;
+}
+
+div.dokuwiki textarea.edit {
+ font-family: monospace, serif;
+ /* second generic font fixes problem with font-size, see
+ http://meyerweb.com/eric/thoughts/2010/02/12/fixed-monospace-sizing/ */
+ font-size: 100%;
+ color: __text__;
+ background-color: __background__;
+ border: 1px solid __border__;
+ padding: 0.3em 0 0 0.3em;
+ /* should just be "width: 100%", but IE8 doesn't like it, see FS#1910 + FS#1667 */
+ width: 700px;
+ min-width: 100%;
+ max-width: 100%;
+}
+
+/* nice alphatransparency background except for IE <7 */
+html>body div.dokuwiki textarea.edit {
+ background: __background__ url(images/inputshadow.png) repeat-x top;
+}
+
+div.dokuwiki input.edit,
+div.dokuwiki select.edit {
+ font-size: 100%;
+ border: 1px solid __border__;
+ color: __text__;
+ background-color: __background__;
+ vertical-align: middle;
+ margin: 1px;
+ padding: 0.20em 0.3em;
+ display: inline;
+}
+
+/* nice alphatransparency background except for IE <7 */
+html>body div.dokuwiki input.edit,
+html>body div.dokuwiki select.edit {
+ background: __background__ url(images/inputshadow.png) repeat-x top;
+}
+
+div.dokuwiki select.edit {
+ padding: 0.1em 0;
+}
+
+div.dokuwiki input.missing {
+ font-size: 100%;
+ border: 1px solid __border__;
+ color: __text__;
+ background-color: #ffcccc;
+ vertical-align: middle;
+ margin: 1px;
+ padding: 0.20em 0.3em;
+ display: inline;
+}
+
+/* disabled style - not understood by IE */
+div.dokuwiki textarea.edit[disabled],
+div.dokuwiki textarea.edit[readonly],
+div.dokuwiki input.edit[disabled],
+div.dokuwiki input.edit[readonly],
+div.dokuwiki input.button[disabled],
+div.dokuwiki select.edit[disabled] {
+ background-color: __background_neu__!important;
+ color: __text_neu__!important;
+}
+
+/* edit form */
+div.dokuwiki div.toolbar,
+div.dokuwiki div#wiki__editbar {
+ margin: 2px 0;
+ text-align: left;
+}
+div.dokuwiki div#size__ctl {
+ float: right;
+ width: 60px;
+ height: 2.7em;
+}
+div.dokuwiki #size__ctl img {
+ cursor: pointer;
+}
+div.dokuwiki div#wiki__editbar div.editButtons {
+ float: left;
+ padding: 0 1.0em 0.7em 0;
+}
+div.dokuwiki div#wiki__editbar div.summary {
+ float: left;
+}
+div.dokuwiki .nowrap {
+ white-space: nowrap;
+}
+div.dokuwiki div#draft__status {
+ float: right;
+ color: __text_alt__;
+}
+
+div.dokuwiki div.license {
+ padding: 0.5em;
+ font-size: 90%;
+ text-align: center;
+}
+
+div.dokuwiki form#dw__editform div.license {
+ clear: left;
+ font-size: 90%;
+}
+
+/* --------- buttons ------------------- */
+
+div.dokuwiki input.button,
+div.dokuwiki button.button {
+ border: 1px solid __border__;
+ color: __text__;
+ background-color: __background__;
+ vertical-align: middle;
+ text-decoration: none;
+ font-size: 100%;
+ cursor: pointer;
+ margin: 1px;
+ padding: 0.125em 0.4em;
+}
+
+/* nice alphatransparency background except for IE <7 */
+html>body div.dokuwiki input.button,
+html>body div.dokuwiki button.button {
+ background: __background__ url(images/buttonshadow.png) repeat-x bottom;
+}
+
+* html div.dokuwiki input.button,
+* html div.dokuwiki button.button {
+ height: 1.8em;
+}
+
+div.dokuwiki div.secedit input.button {
+ border: 1px solid __border__;
+ color: __text__;
+ background-color: __background__;
+ vertical-align: middle;
+ text-decoration: none;
+ margin: 0;
+ padding: 0;
+ font-size: 10px;
+ cursor: pointer;
+ float: right;
+ display: inline;
+}
+
+/* ----------- page navigator ------------- */
+
+div.dokuwiki div.pagenav {
+ margin: 1em 0 0 0;
+}
+
+div.dokuwiki div.pagenav-prev {
+ text-align: right;
+ float: left;
+ width: 49%
+}
+
+div.dokuwiki div.pagenav-next {
+ text-align: left;
+ float: right;
+ width: 49%
+}
+
+/* ----------- type of recent changes select -------- */
+
+div.dokuwiki form#dw__recent select {
+ margin-bottom: 10px;
+}
+
+/* --------------- Links ------------------ */
+
+div.dokuwiki a:link,
+div.dokuwiki a:visited {
+ color: __extern__;
+ text-decoration: none;
+}
+div.dokuwiki a:hover,
+div.dokuwiki a:active {
+ color: __text__;
+ text-decoration: underline;
+}
+
+div.dokuwiki h1 a,
+div.dokuwiki h2 a,
+div.dokuwiki h3 a,
+div.dokuwiki h4 a,
+div.dokuwiki h5 a,
+div.dokuwiki a.nolink {
+ color: __text__ !important;
+ text-decoration: none !important;
+}
+
+/* external link */
+div.dokuwiki a.urlextern {
+ background: transparent url(images/link_icon.gif) 0px 1px no-repeat;
+ padding: 1px 0px 1px 16px;
+}
+
+/* windows share */
+div.dokuwiki a.windows {
+ background: transparent url(images/windows.gif) 0px 1px no-repeat;
+ padding: 1px 0px 1px 16px;
+}
+
+/* interwiki link (icon are set by dokuwiki) */
+div.dokuwiki a.interwiki {
+}
+
+/* link to some embedded media */
+div.dokuwiki a.media {
+}
+
+div.dokuwiki a.urlextern:link,
+div.dokuwiki a.windows:link,
+div.dokuwiki a.interwiki:link {
+ color: __extern__;
+}
+
+div.dokuwiki a.urlextern:visited,
+div.dokuwiki a.windows:visited,
+div.dokuwiki a.interwiki:visited {
+ color: purple;
+}
+div.dokuwiki a.urlextern:hover,
+div.dokuwiki a.urlextern:active,
+div.dokuwiki a.windows:hover,
+div.dokuwiki a.windows:active,
+div.dokuwiki a.interwiki:hover,
+div.dokuwiki a.interwiki:active {
+ color: __text__;
+}
+
+/* email link */
+div.dokuwiki a.mail {
+ background: transparent url(images/mail_icon.gif) 0px 1px no-repeat;
+ padding: 1px 0px 1px 16px;
+}
+
+/* existing wikipage */
+div.dokuwiki a.wikilink1 {
+ color: __existing__ !important;
+}
+
+/* not existing wikipage */
+div.dokuwiki a.wikilink2 {
+ color: __missing__ !important;
+ text-decoration: none !important;
+ border-bottom: dashed 1px __missing__ !important;
+}
+
+/* ------------- Page elements ----------------- */
+
+div.dokuwiki div.preview {
+ background-color: __background_neu__;
+ margin: 0 0 0 2em;
+ padding: 4px;
+ border: 1px dashed __text__;
+}
+
+div.dokuwiki div.breadcrumbs {
+ background-color: __background_neu__;
+ color: __text_neu__;
+ font-size: 80%;
+ padding: 0 0 0 4px;
+}
+
+div.dokuwiki span.user {
+ color: __text_other__;
+ font-size: 90%;
+}
+
+div.dokuwiki li.minor {
+ color: __text_neu__;
+ font-style: italic;
+}
+
+/* embedded images */
+div.dokuwiki img.media {
+ margin: 3px;
+}
+
+div.dokuwiki img.medialeft {
+ border: 0;
+ float: left;
+ margin: 0 1.5em 0 0;
+}
+
+div.dokuwiki img.mediaright {
+ border: 0;
+ float: right;
+ margin: 0 0 0 1.5em;
+}
+
+div.dokuwiki img.mediacenter {
+ border: 0;
+ display: block;
+ margin: 0 auto;
+}
+
+/* smileys */
+div.dokuwiki img.middle {
+ vertical-align: middle;
+}
+
+div.dokuwiki acronym {
+ cursor: help;
+ border-bottom: 1px dotted __text__;
+}
+
+/* general headline setup */
+div.dokuwiki h1,
+div.dokuwiki h2,
+div.dokuwiki h3,
+div.dokuwiki h4,
+div.dokuwiki h5 {
+ color: __text__;
+ background-color: inherit;
+ font-size: 100%;
+ font-weight: normal;
+ margin: 0 0 1em 0;
+ padding: 0.5em 0 0 0;
+ border-bottom: 1px solid __border__;
+ clear: left;
+}
+
+/* special headlines */
+div.dokuwiki h1 {font-size: 160%; margin-left: 0px; font-weight: bold;}
+div.dokuwiki h2 {font-size: 150%; margin-left: 20px;}
+div.dokuwiki h3 {font-size: 140%; margin-left: 40px; border-bottom: none; font-weight: bold;}
+div.dokuwiki h4 {font-size: 120%; margin-left: 60px; border-bottom: none; font-weight: bold;}
+div.dokuwiki h5 {font-size: 100%; margin-left: 80px; border-bottom: none; font-weight: bold;}
+
+/* indent different sections */
+div.dokuwiki div.level1 { margin-left: 3px; }
+div.dokuwiki div.level2 { margin-left: 23px; }
+div.dokuwiki div.level3 { margin-left: 43px; }
+div.dokuwiki div.level4 { margin-left: 63px; }
+div.dokuwiki div.level5 { margin-left: 83px; }
+
+/* unordered lists */
+div.dokuwiki ul {
+ line-height: 1.5em;
+ list-style-type: square;
+ list-style-image: none;
+ margin: 0 0 1em 3.5em;
+ color: __text_alt__;
+}
+
+/* ordered lists */
+div.dokuwiki ol {
+ line-height: 1.5em;
+ list-style-image: none;
+ margin: 0 0 1em 3.5em;
+ color: __text_alt__;
+ font-weight: bold;
+}
+
+/* no bottom gap in between and smaller left margin for nested lists */
+div.dokuwiki li ul,
+div.dokuwiki li ol {
+ margin: 0 0 0 1.5em;
+}
+
+/* the list items overriding the ul/ol definition */
+div.dokuwiki .li {
+ color: __text__;
+ font-weight: normal;
+}
+
+div.dokuwiki ol { list-style-type: decimal; }
+div.dokuwiki ol ol { list-style-type: upper-roman; }
+div.dokuwiki ol ol ol { list-style-type: lower-alpha; }
+div.dokuwiki ol ol ol ol { list-style-type: lower-greek; }
+
+div.dokuwiki li.open {
+ list-style-image: url(images/open.gif);
+ /*list-style-type: circle;*/
+}
+
+div.dokuwiki li.closed {
+ list-style-image: url(images/closed.gif);
+ /*list-style-type: disc;*/
+}
+
+div.dokuwiki blockquote {
+ border-left: 2px solid __border__;
+ padding-left: 3px;
+}
+
+div.dokuwiki pre,
+div.dokuwiki code {
+ font-family: monospace, serif;
+ /* second generic font fixes problem with font-size, see
+ http://meyerweb.com/eric/thoughts/2010/02/12/fixed-monospace-sizing/ */
+ font-size: 100%;
+}
+div.dokuwiki pre {
+ padding: 0.5em;
+ border: 1px dashed __border__;
+ color: __text__;
+ overflow: auto;
+}
+
+/* code blocks by indention */
+div.dokuwiki pre.pre {
+ background-color: __background_other__;
+}
+
+/* code blocks by code tag */
+div.dokuwiki pre.code {
+ background-color: __background_other__;
+}
+
+/* code blocks by file tag */
+div.dokuwiki pre.file {
+ background-color: __background_alt__;
+}
+
+/* filenames for file and code blocks */
+div.dokuwiki dl.file,
+div.dokuwiki dl.code {
+ margin-top: 2em;
+ margin-bottom: 2.5em;
+}
+
+div.dokuwiki dl.file dt,
+div.dokuwiki dl.code dt {
+ border: 1px dashed __border__;
+ display: inline;
+ padding: 0.1em 1em;
+ margin-left: 2em;
+}
+
+div.dokuwiki dl.code dt a,
+div.dokuwiki dl.file dt a {
+ color: __text__;
+}
+
+div.dokuwiki dl.code dt {
+ background-color: __background_other__;
+ border-bottom: 1px solid __background_other__;
+}
+
+div.dokuwiki dl.file dt {
+ background-color: __background_alt__;
+ border-bottom: 1px solid __background_alt__;
+}
+
+
+/* inline tables */
+div.dokuwiki table.inline {
+ background-color: __background__;
+ border-spacing: 0px;
+ border-collapse: collapse;
+}
+
+div.dokuwiki table.inline th {
+ padding: 3px;
+ border: 1px solid __border__;
+ background-color: __background_alt__;
+}
+
+div.dokuwiki table.inline td {
+ padding: 3px;
+ border: 1px solid __border__;
+}
+
+/* ---------- table of contents ------------------- */
+
+div.dokuwiki div.toc {
+ margin: 1.2em 0 0 2em;
+ float: right;
+ width: 200px;
+ font-size: 80%;
+ clear: both;
+}
+
+div.dokuwiki div.tocheader {
+ border: 1px solid __border__;
+ background-color: __background_alt__;
+ text-align: left;
+ font-weight: bold;
+ padding: 3px;
+ margin-bottom: 2px;
+}
+
+div.dokuwiki span.toc_open,
+div.dokuwiki span.toc_close {
+ border: 0.4em solid __background_alt__;
+ float: right;
+ display: block;
+ margin: 0.4em 3px 0 0;
+}
+
+div.dokuwiki span.toc_open span,
+div.dokuwiki span.toc_close span {
+ display: none;
+}
+
+div.dokuwiki span.toc_open {
+ margin-top: 0.4em;
+ border-top: 0.4em solid __text__;
+}
+
+div.dokuwiki span.toc_close {
+ margin-top: 0;
+ border-bottom: 0.4em solid __text__;
+}
+
+div.dokuwiki #toc__inside {
+ border: 1px solid __border__;
+ background-color: __background__;
+ text-align: left;
+ padding: 0.5em 0 0.7em 0;
+}
+
+div.dokuwiki ul.toc {
+ list-style-type: none;
+ list-style-image: none;
+ line-height: 1.2em;
+ padding-left: 1em;
+ margin: 0;
+}
+
+div.dokuwiki ul.toc li {
+ background: transparent url(images/tocdot2.gif) 0 0.6em no-repeat;
+ padding-left: 0.4em;
+}
+
+div.dokuwiki ul.toc li.clear {
+ background-image: none;
+ padding-left: 0.4em;
+}
+
+div.dokuwiki a.toc:link,
+div.dokuwiki a.toc:visited {
+ color: __extern__;
+}
+
+div.dokuwiki a.toc:hover,
+div.dokuwiki a.toc:active {
+ color: __text__;
+}
+
+/* ---------------------------- Diff rendering --------------------------*/
+div.dokuwiki table.diff {
+ background-color: __background__;
+ width: 100%;
+}
+div.dokuwiki td.diff-blockheader {
+ font-weight: bold;
+}
+div.dokuwiki table.diff th {
+ border-bottom: 1px solid __border__;
+ font-size: 110%;
+ width: 50%;
+ font-weight: normal;
+ text-align: left;
+}
+div.dokuwiki table.diff th a {
+ font-weight: bold;
+}
+div.dokuwiki table.diff th span.user {
+ color: __text__;
+ font-size: 80%;
+}
+div.dokuwiki table.diff th span.sum {
+ font-size: 80%;
+ font-weight: bold;
+}
+div.dokuwiki table.diff th.minor {
+ font-style: italic;
+}
+div.dokuwiki table.diff td {
+ font-family: monospace;
+ font-size: 100%;
+}
+div.dokuwiki td.diff-addedline,
+div.dokuwiki span.diff-addedline {
+ background-color: #ddffdd;
+}
+div.dokuwiki td.diff-deletedline,
+div.dokuwiki span.diff-deletedline {
+ background-color: #ffffbb;
+}
+div.dokuwiki td.diff-context {
+ background-color: __background_neu__;
+}
+div.dokuwiki table.diff td.diff-addedline strong,
+div.dokuwiki table.diff td.diff-deletedline strong {
+ color: red;
+}
+
+/* --------------------- footnotes -------------------------------- */
+
+div.dokuwiki div.footnotes {
+ clear: both;
+ border-top: 1px solid __border__;
+ padding-left: 1em;
+ margin-top: 1em;
+}
+
+div.dokuwiki div.fn {
+ font-size: 90%;
+}
+
+div.dokuwiki a.fn_bot {
+ font-weight: bold;
+}
+
+/* insitu-footnotes */
+div.insitu-footnote {
+ font-size: 80%;
+ line-height: 1.2em;
+ border: 1px solid __border__;
+ background-color: __background_other__;
+ text-align: left;
+ padding: 4px;
+ max-width: 40%; /* IE's width is handled in javascript */
+ min-width: 5em;
+}
+
+/* overcome IE issue with one line code or file boxes which require h. scrolling */
+* html .insitu-footnote pre.code,
+* html .insitu-footnote pre.file {
+ padding-bottom: 18px;
+}
+
+/* --------------- search result formating --------------- */
+div.dokuwiki .search_result {
+ margin-bottom: 6px;
+ padding: 0 10px 0 30px;
+}
+
+div.dokuwiki .search_snippet {
+ color: __text_other__;
+ font-size: 12px;
+ margin-left: 20px;
+}
+
+div.dokuwiki .search_sep {
+ color: __text__;
+}
+
+div.dokuwiki .search_hit {
+ color: __text__;
+ background-color: __highlight__;
+}
+div.dokuwiki strong.search_hit {
+ font-weight: normal;
+}
+
+div.dokuwiki div.search_quickresult {
+ margin: 0 0 15px 30px;
+ padding: 0 10px 10px 0;
+ border-bottom: 1px dashed __border__;
+}
+div.dokuwiki div.search_quickresult h3 {
+ margin: 0 0 1.0em 0;
+ font-size: 1em;
+ font-weight: bold;
+}
+
+div.dokuwiki ul.search_quickhits {
+ margin: 0 0 0.5em 1.0em;
+}
+
+div.dokuwiki ul.search_quickhits li {
+ margin: 0 1.0em 0 1.0em;
+ float: left;
+ width: 30%;
+}
+
+div.dokuwiki .section_highlight {
+ background-color: __background_alt__ !important;
+}
+
+/* ------------------ Additional ---------------------- */
+
+div.footerinc {
+ text-align: center;
+}
+.footerinc a img {
+ opacity: 0.5;
+ border: 0;
+}
+
+.footerinc a:hover img {
+ opacity: 1;
+}
+
+/* ---------- AJAX quicksearch ----------- */
+
+div.dokuwiki div.ajax_qsearch {
+ position: absolute;
+ right: 237px;;
+ width: 200px;
+ opacity: 0.9;
+ display: none;
+ font-size: 80%;
+ line-height: 1.2em;
+ border: 1px solid __border__;
+ background-color: __background_other__;
+ text-align: left;
+ padding: 4px;
+}
+
+/* --------- Toolbar -------------------- */
+button.toolbutton {
+ background-color: __background__;
+ padding: 0px;
+ margin: 0 1px 0 0;
+ border: 1px solid __border__;
+ cursor: pointer;
+}
+
+/* nice alphatransparency background except for IE <7 */
+html>body button.toolbutton {
+ background: __background__ url(images/buttonshadow.png) repeat-x bottom;
+}
+
+div.picker {
+ width: 250px;
+ border: 1px solid __border__;
+ background-color: __background_alt__;
+}
+
+div.pk_hl {
+ width: 125px;
+}
+
+button.pickerbutton {
+ padding: 0px;
+ margin: 0 1px 1px 0;
+ border: 0;
+ background-color: transparent;
+ font-size: 80%;
+ cursor: pointer;
+}
+
+/* --------------- Image Details ----------------- */
+
+div.dokuwiki div.img_big {
+ float: left;
+ margin-right: 0.5em;
+}
+
+div.dokuwiki dl.img_tags dt {
+ font-weight: bold;
+ background-color: __background_alt__;
+}
+div.dokuwiki dl.img_tags dd {
+ background-color: __background_neu__;
+}
+
+div.dokuwiki div.imagemeta {
+ color: __text_neu__;
+ font-size: 70%;
+ line-height: 95%;
+}
+
+div.dokuwiki div.imagemeta img.thumb {
+ float: left;
+ margin-right: 0.1em;
+}
+
diff --git a/lib/tpl/default/detail.php b/lib/tpl/default/detail.php
new file mode 100644
index 000000000..503c0ef71
--- /dev/null
+++ b/lib/tpl/default/detail.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * DokuWiki Image Detail Template
+ *
+ * This is the template for displaying image details
+ *
+ * You should leave the doctype at the very top - It should
+ * always be the very first line of a document.
+ *
+ * @link http://dokuwiki.org/templates
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+// must be run from within DokuWiki
+if (!defined('DOKU_INC')) die();
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang']?>" lang="<?php echo $conf['lang']?>" dir="ltr">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>
+ <?php echo hsc(tpl_img_getTag('IPTC.Headline',$IMG))?>
+ [<?php echo strip_tags($conf['title'])?>]
+ </title>
+
+ <?php tpl_metaheaders()?>
+
+ <link rel="shortcut icon" href="<?php echo DOKU_TPL?>images/favicon.ico" />
+</head>
+
+<body>
+<div class="dokuwiki">
+ <?php html_msgarea()?>
+
+ <div class="page">
+ <?php if($ERROR){ print $ERROR; }else{ ?>
+
+ <h1><?php echo hsc(tpl_img_getTag('IPTC.Headline',$IMG))?></h1>
+
+ <div class="img_big">
+ <?php tpl_img(900,700) ?>
+ </div>
+
+ <div class="img_detail">
+ <p class="img_caption">
+ <?php print nl2br(hsc(tpl_img_getTag('simple.title'))); ?>
+ </p>
+
+ <p>&larr; <?php echo $lang['img_backto']?> <?php tpl_pagelink($ID)?></p>
+ <?php
+ $imgNS = getNS($IMG);
+ $authNS = auth_quickaclcheck("$imgNS:*");
+ if ($authNS >= AUTH_UPLOAD) {
+ echo '<p><a href="'.media_managerURL(array('ns' => $imgNS, 'image' => $IMG)).'">'.$lang['img_manager'].'</a></p>';
+ }
+ ?>
+
+ <dl class="img_tags">
+ <?php
+ $config_files = getConfigFiles('mediameta');
+ foreach ($config_files as $config_file) {
+ if(@file_exists($config_file)) include($config_file);
+ }
+
+ foreach($fields as $key => $tag){
+ $t = array();
+ if (!empty($tag[0])) $t = array($tag[0]);
+ if(is_array($tag[3])) $t = array_merge($t,$tag[3]);
+ $value = tpl_img_getTag($t);
+ if ($value) {
+ echo '<dt>'.$lang[$tag[1]].':</dt><dd>';
+ if ($tag[2] == 'date') echo dformat($value);
+ else echo hsc($value);
+ echo '</dd>';
+ }
+ }
+ ?>
+ </dl>
+ <?php //Comment in for Debug// dbg(tpl_img_getTag('Simple.Raw'));?>
+ </div>
+
+ <?php } ?>
+ </div>
+</div>
+</body>
+</html>
+
diff --git a/lib/tpl/default/footer.html b/lib/tpl/default/footer.html
new file mode 100644
index 000000000..38aab7216
--- /dev/null
+++ b/lib/tpl/default/footer.html
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Example footer include
+ *
+ * This file shows you how to use the include hooks. However I recommend to
+ * create your own complete new template instead.
+ */
+
+$tgt = ($conf['target']['extern']) ? 'target="'.$conf['target']['extern'].'"' : '';
+?>
+
+<div class="footerinc">
+
+ <a <?php echo $tgt?> href="<?php echo DOKU_BASE; ?>feed.php" title="Recent changes RSS feed"><img src="<?php echo DOKU_TPL; ?>images/button-rss.png" width="80" height="15" alt="Recent changes RSS feed" /></a>
+
+ <?php
+ $lic = license_img('button');
+ if($lic){
+ ?>
+ <a <?php echo $tgt?> href="<?php echo $license[$conf['license']]['url']?>" rel="license" title="<?php echo $license[$conf['license']]['name']?>"><img src="<?php echo DOKU_BASE.$lic ?>" width="80" height="15" alt="" /></a>
+ <?php } ?>
+
+ <a <?php echo $tgt?> href="http://www.dokuwiki.org/donate" title="Donate"><img src="<?php echo DOKU_TPL; ?>images/button-donate.gif" alt="Donate" width="80" height="15" /></a>
+
+ <a <?php echo $tgt?> href="http://www.php.net" title="Powered by PHP"><img src="<?php echo DOKU_TPL; ?>images/button-php.gif" width="80" height="15" alt="Powered by PHP" /></a>
+
+ <a <?php echo $tgt?> href="http://validator.w3.org/check/referer" title="Valid XHTML 1.0"><img src="<?php echo DOKU_TPL; ?>images/button-xhtml.png" width="80" height="15" alt="Valid XHTML 1.0" /></a>
+
+ <a <?php echo $tgt?> href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3" title="Valid CSS"><img src="<?php echo DOKU_TPL; ?>images/button-css.png" width="80" height="15" alt="Valid CSS" /></a>
+
+ <a <?php echo $tgt?> href="http://dokuwiki.org/" title="Driven by DokuWiki"><img src="<?php echo DOKU_TPL; ?>images/button-dw.png" width="80" height="15" alt="Driven by DokuWiki" /></a>
+
+<?php
+if ($conf['allowdebug']) {
+ echo '<!-- page made in '.round(delta_time(DOKU_START_TIME), 3).' seconds -->';
+}
+?>
+
+
+</div>
+<?php include(dirname(__FILE__).'/dwtb.html') ?>
diff --git a/lib/tpl/default/images/UWEB.png b/lib/tpl/default/images/UWEB.png
new file mode 100644
index 000000000..292ade4ed
--- /dev/null
+++ b/lib/tpl/default/images/UWEB.png
Binary files differ
diff --git a/lib/tpl/default/images/UWEBshadow.png b/lib/tpl/default/images/UWEBshadow.png
new file mode 100644
index 000000000..8c4e5f829
--- /dev/null
+++ b/lib/tpl/default/images/UWEBshadow.png
Binary files differ
diff --git a/lib/tpl/default/images/apple-touch-icon.png b/lib/tpl/default/images/apple-touch-icon.png
new file mode 100644
index 000000000..45fa4e7b0
--- /dev/null
+++ b/lib/tpl/default/images/apple-touch-icon.png
Binary files differ
diff --git a/lib/tpl/default/images/bullet.gif b/lib/tpl/default/images/bullet.gif
new file mode 100644
index 000000000..b43de48a4
--- /dev/null
+++ b/lib/tpl/default/images/bullet.gif
Binary files differ
diff --git a/lib/tpl/default/images/button-cc.gif b/lib/tpl/default/images/button-cc.gif
new file mode 100644
index 000000000..c7a403a9e
--- /dev/null
+++ b/lib/tpl/default/images/button-cc.gif
Binary files differ
diff --git a/lib/tpl/default/images/button-css.png b/lib/tpl/default/images/button-css.png
new file mode 100644
index 000000000..706325e1c
--- /dev/null
+++ b/lib/tpl/default/images/button-css.png
Binary files differ
diff --git a/lib/tpl/default/images/button-donate.gif b/lib/tpl/default/images/button-donate.gif
new file mode 100644
index 000000000..bba284e21
--- /dev/null
+++ b/lib/tpl/default/images/button-donate.gif
Binary files differ
diff --git a/lib/tpl/default/images/button-dw.png b/lib/tpl/default/images/button-dw.png
new file mode 100644
index 000000000..97272d968
--- /dev/null
+++ b/lib/tpl/default/images/button-dw.png
Binary files differ
diff --git a/lib/tpl/default/images/button-php.gif b/lib/tpl/default/images/button-php.gif
new file mode 100644
index 000000000..19aefb08f
--- /dev/null
+++ b/lib/tpl/default/images/button-php.gif
Binary files differ
diff --git a/lib/tpl/default/images/button-rss.png b/lib/tpl/default/images/button-rss.png
new file mode 100644
index 000000000..f2438043f
--- /dev/null
+++ b/lib/tpl/default/images/button-rss.png
Binary files differ
diff --git a/lib/tpl/default/images/button-xhtml.png b/lib/tpl/default/images/button-xhtml.png
new file mode 100644
index 000000000..ec686442c
--- /dev/null
+++ b/lib/tpl/default/images/button-xhtml.png
Binary files differ
diff --git a/lib/tpl/default/images/buttonshadow.png b/lib/tpl/default/images/buttonshadow.png
new file mode 100644
index 000000000..b96ebf759
--- /dev/null
+++ b/lib/tpl/default/images/buttonshadow.png
Binary files differ
diff --git a/lib/tpl/default/images/closed.gif b/lib/tpl/default/images/closed.gif
new file mode 100644
index 000000000..8414d4d69
--- /dev/null
+++ b/lib/tpl/default/images/closed.gif
Binary files differ
diff --git a/lib/tpl/default/images/favicon.ico b/lib/tpl/default/images/favicon.ico
new file mode 100644
index 000000000..8b9616abb
--- /dev/null
+++ b/lib/tpl/default/images/favicon.ico
Binary files differ
diff --git a/lib/tpl/default/images/inputshadow.png b/lib/tpl/default/images/inputshadow.png
new file mode 100644
index 000000000..480044986
--- /dev/null
+++ b/lib/tpl/default/images/inputshadow.png
Binary files differ
diff --git a/lib/tpl/default/images/link_icon.gif b/lib/tpl/default/images/link_icon.gif
new file mode 100644
index 000000000..d0a92f2fa
--- /dev/null
+++ b/lib/tpl/default/images/link_icon.gif
Binary files differ
diff --git a/lib/tpl/default/images/mail_icon.gif b/lib/tpl/default/images/mail_icon.gif
new file mode 100644
index 000000000..437d28fe1
--- /dev/null
+++ b/lib/tpl/default/images/mail_icon.gif
Binary files differ
diff --git a/lib/tpl/default/images/open.gif b/lib/tpl/default/images/open.gif
new file mode 100644
index 000000000..f5d5c7e56
--- /dev/null
+++ b/lib/tpl/default/images/open.gif
Binary files differ
diff --git a/lib/tpl/default/images/resizecol.png b/lib/tpl/default/images/resizecol.png
new file mode 100644
index 000000000..f0111507c
--- /dev/null
+++ b/lib/tpl/default/images/resizecol.png
Binary files differ
diff --git a/lib/tpl/default/images/tocdot2.gif b/lib/tpl/default/images/tocdot2.gif
new file mode 100644
index 000000000..e2b5f15cb
--- /dev/null
+++ b/lib/tpl/default/images/tocdot2.gif
Binary files differ
diff --git a/lib/tpl/default/images/windows.gif b/lib/tpl/default/images/windows.gif
new file mode 100644
index 000000000..64dfeb6fb
--- /dev/null
+++ b/lib/tpl/default/images/windows.gif
Binary files differ
diff --git a/lib/tpl/default/layout.css b/lib/tpl/default/layout.css
new file mode 100644
index 000000000..ded2d87a2
--- /dev/null
+++ b/lib/tpl/default/layout.css
@@ -0,0 +1,79 @@
+/**
+ * Tableless Layout for default template
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author moraes <moraes@tipos.com.br>
+ */
+
+/* -------------- top row --------------- */
+div.dokuwiki .header {
+ padding: 3px 0 0 2px;
+}
+
+div.dokuwiki .pagename {
+ float: left;
+ font-size: 200%;
+ font-weight: bolder;
+ color: __background_alt__;
+ text-align: left;
+ vertical-align: middle;
+}
+
+div.dokuwiki .pagename a {
+ color: __extern__ !important;
+ text-decoration: none !important;
+}
+
+div.dokuwiki .logo {
+ float: right;
+ font-size: 220%;
+ font-weight: bolder;
+ text-align: right;
+ vertical-align: middle;
+}
+
+div.dokuwiki .logo a {
+ color: __background_alt__ !important;
+ text-decoration: none !important;
+ font-variant: small-caps;
+ letter-spacing: 2pt;
+}
+
+/* --------------- top and bottom bar ---------------- */
+div.dokuwiki .bar {
+ border-top: 1px solid __border__;
+ border-bottom: 1px solid __border__;
+ background: __background_alt__;
+ padding: 0.1em 0.15em;
+ clear: both;
+}
+
+div.dokuwiki .bar-left {
+ float: left;
+}
+
+div.dokuwiki .bar-right {
+ float: right;
+ text-align: right;
+}
+
+div.dokuwiki #bar__bottom {
+ margin-bottom: 3px;
+}
+
+/* ------------- File Metadata ----------------------- */
+
+div.dokuwiki div.meta {
+ clear: both;
+ margin-top: 1em;
+ color: __text_alt__;
+ font-size: 70%;
+}
+
+div.dokuwiki div.meta div.user {
+ float: left;
+}
+
+div.dokuwiki div.meta div.doc {
+ text-align: right;
+}
diff --git a/lib/tpl/default/main.php b/lib/tpl/default/main.php
new file mode 100644
index 000000000..3e85c58f2
--- /dev/null
+++ b/lib/tpl/default/main.php
@@ -0,0 +1,138 @@
+<?php
+/**
+ * DokuWiki Default Template
+ *
+ * This is the template you need to change for the overall look
+ * of DokuWiki.
+ *
+ * You should leave the doctype at the very top - It should
+ * always be the very first line of a document.
+ *
+ * @link http://dokuwiki.org/templates
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+// must be run from within DokuWiki
+if (!defined('DOKU_INC')) die();
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang']?>"
+ lang="<?php echo $conf['lang']?>" dir="<?php echo $lang['direction']?>">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>
+ <?php tpl_pagetitle()?>
+ [<?php echo strip_tags($conf['title'])?>]
+ </title>
+
+ <?php tpl_metaheaders()?>
+ <?php echo tpl_favicon(array('favicon', 'mobile')) ?>
+
+ <?php /*old includehook*/ @include(dirname(__FILE__).'/meta.html')?>
+</head>
+
+<body>
+<?php /*old includehook*/ @include(dirname(__FILE__).'/topheader.html')?>
+<div class="dokuwiki">
+ <?php html_msgarea()?>
+
+ <div class="stylehead">
+
+ <div class="header">
+ <div class="pagename">
+ [[<?php tpl_link(wl($ID,'do=backlink'),tpl_pagetitle($ID,true),'title="'.$lang['btn_backlink'].'"')?>]]
+ </div>
+ <div class="logo">
+ <?php tpl_link(wl(),$conf['title'],'name="dokuwiki__top" id="dokuwiki__top" accesskey="h" title="[H]"')?>
+ </div>
+
+ <div class="clearer"></div>
+ </div>
+
+ <?php /*old includehook*/ @include(dirname(__FILE__).'/header.html')?>
+
+ <div class="bar" id="bar__top">
+ <div class="bar-left" id="bar__topleft">
+ <?php tpl_button('edit')?>
+ <?php tpl_button('history')?>
+ </div>
+
+ <div class="bar-right" id="bar__topright">
+ <?php tpl_button('recent')?>
+ <?php tpl_searchform()?>&nbsp;
+ </div>
+
+ <div class="clearer"></div>
+ </div>
+
+ <?php if($conf['breadcrumbs']){?>
+ <div class="breadcrumbs">
+ <?php tpl_breadcrumbs()?>
+ <?php //tpl_youarehere() //(some people prefer this)?>
+ </div>
+ <?php }?>
+
+ <?php if($conf['youarehere']){?>
+ <div class="breadcrumbs">
+ <?php tpl_youarehere() ?>
+ </div>
+ <?php }?>
+
+ </div>
+ <?php tpl_flush()?>
+
+ <?php /*old includehook*/ @include(dirname(__FILE__).'/pageheader.html')?>
+
+ <div class="page">
+ <!-- wikipage start -->
+ <?php tpl_content()?>
+ <!-- wikipage stop -->
+ </div>
+
+ <div class="clearer"></div>
+
+ <?php tpl_flush()?>
+
+ <div class="stylefoot">
+
+ <div class="meta">
+ <div class="user">
+ <?php tpl_userinfo()?>
+ </div>
+ <div class="doc">
+ <?php tpl_pageinfo()?>
+ </div>
+ </div>
+
+ <?php /*old includehook*/ @include(dirname(__FILE__).'/pagefooter.html')?>
+
+ <div class="bar" id="bar__bottom">
+ <div class="bar-left" id="bar__bottomleft">
+ <?php tpl_button('edit')?>
+ <?php tpl_button('history')?>
+ <?php tpl_button('revert')?>
+ </div>
+ <div class="bar-right" id="bar__bottomright">
+ <?php tpl_button('subscribe')?>
+ <?php tpl_button('media')?>
+ <?php tpl_button('admin')?>
+ <?php tpl_button('profile')?>
+ <?php tpl_button('login')?>
+ <?php tpl_button('index')?>
+ <?php tpl_button('top')?>&nbsp;
+ </div>
+ <div class="clearer"></div>
+ </div>
+
+ </div>
+
+ <?php tpl_license(false);?>
+
+</div>
+<?php /*old includehook*/ @include(dirname(__FILE__).'/footer.html')?>
+
+<div class="no"><?php /* provide DokuWiki housekeeping, required in all templates */ tpl_indexerWebBug()?></div>
+</body>
+</html>
diff --git a/lib/tpl/default/media.css b/lib/tpl/default/media.css
new file mode 100644
index 000000000..37369fe2f
--- /dev/null
+++ b/lib/tpl/default/media.css
@@ -0,0 +1,213 @@
+/**
+ * The CSS in here controls the appearance of the media manager
+ */
+
+#media__manager {
+ height: 100%;
+ overflow: hidden;
+}
+
+#media__left {
+ width: 30%;
+ border-right: solid 1px __border__;
+
+ height: 100%;
+ overflow: auto;
+ position: absolute;
+ left: 0;
+}
+
+#media__right {
+ width: 69.7%;
+
+ height: 100%;
+ overflow: auto;
+ position: absolute;
+ right: 0;
+}
+
+#media__manager h1 {
+ margin: 0;
+ padding: 0;
+ margin-bottom: 0.5em;
+}
+
+#media__manager a.select {
+ cursor: pointer;
+}
+
+/* --- Tree formatting --- */
+
+#media__tree img {
+ float: left;
+ padding: 0.5em 0.3em 0 0;
+}
+
+#media__tree ul {
+ list-style-type: none;
+ list-style-image: none;
+ margin-left: 1.5em;
+}
+
+#media__tree li {
+ clear: left;
+ list-style-type: none;
+ list-style-image: none;
+}
+*+html #media__tree li,
+* html #media__tree li {
+ border: 1px solid __background__;
+}/* I don't understand this, but this fixes a style bug in IE;
+it's dirty, so any "real" fixes are welcome */
+
+/* --- options --- */
+
+#media__opts {
+ padding-left: 1em;
+ margin-bottom: 0.5em;
+}
+
+#media__opts input {
+ float: left;
+ display: block;
+ margin-top: 4px;
+ position: absolute;
+}
+*+html #media__opts input,
+* html #media__opts input {
+ position: static;
+}
+
+#media__opts label {
+ display: block;
+ float: left;
+ margin-left: 20px;
+ margin-bottom: 4px;
+}
+*+html #media__opts label,
+* html #media__opts label {
+ margin-left: 10px;
+}
+
+#media__opts br {
+ clear: left;
+}
+
+/* --- file list --- */
+
+#media__content img.load {
+ margin: 1em auto;
+}
+
+#media__content #scroll__here {
+ border: 1px dashed __border__;
+}
+
+#media__content .odd {
+ background-color: __background_other__;
+ padding: 0.4em;
+}
+
+#media__content .even {
+ padding: 0.4em;
+}
+
+#media__content a.mediafile {
+ margin-right: 1.5em;
+ font-weight: bold;
+}
+
+#media__content div.detail {
+ padding: 0.3em 0 0.3em 2em;
+}
+
+#media__content div.detail div.thumb {
+ float: left;
+ width: 130px;
+ text-align: center;
+ margin-right: 0.4em;
+}
+
+
+#media__content img.btn {
+ vertical-align: text-bottom;
+}
+
+#media__content div.example {
+ color: __text_neu__;
+ margin-left: 1em;
+}
+
+/* --- upload form --- */
+
+#media__content div.upload {
+ font-size: 90%;
+ padding: 0 0.5em 0.5em 0.5em;
+}
+
+#media__content #mediamanager__uploader {
+ display: block;
+ border-bottom: solid 1px __border__;
+ padding: 0 0.5em 1em 0.5em;
+}
+
+#media__content form#dw__upload {
+ border-bottom: 0;
+}
+
+#media__content form#dw__upload fieldset {
+ padding: 0;
+ margin: 0;
+ border: none;
+ width: auto;
+}
+#media__content form#dw__upload p {
+ text-align: left;
+ padding: 0.25em 0;
+ margin: 0;
+ line-height: 1.0em;
+}
+#media__content form#dw__upload label.check {
+ float: none;
+ width: auto;
+ margin-left: 11.5em;
+}
+
+/* --- meta edit form --- */
+
+#media__content form.meta {
+ display: block;
+ padding: 0 0 1em 0;
+}
+
+#media__content form.meta label {
+ display: block;
+ width: 25%;
+ float: left;
+ font-weight: bold;
+ margin-left: 1em;
+ clear: left;
+}
+
+#media__content form.meta .edit {
+ font: 100% "Lucida Grande", Verdana, Lucida, Helvetica, Arial, sans-serif;
+ float: left;
+ width: 70%;
+ padding-right: 0;
+ padding-left: 0.2em;
+ margin: 2px;
+}
+
+#media__content form.meta textarea.edit {
+ height: 8em;
+}
+
+#media__content form.meta div.metafield {
+ clear: left;
+}
+
+#media__content form.meta div.buttons {
+ clear: left;
+ margin-left: 20%;
+ padding-left: 1em;
+}
diff --git a/lib/tpl/default/mediamanager.php b/lib/tpl/default/mediamanager.php
new file mode 100644
index 000000000..7b7fe8675
--- /dev/null
+++ b/lib/tpl/default/mediamanager.php
@@ -0,0 +1,44 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<?php
+/**
+ * DokuWiki Default Template
+ *
+ * This is the template for the media manager popup
+ *
+ * You should leave the doctype at the very top - It should
+ * always be the very first line of a document.
+ *
+ * @link http://dokuwiki.org/templates
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+?>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang']?>" lang="<?php echo $conf['lang']?>" dir="ltr">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>
+ <?php echo hsc($lang['mediaselect'])?>
+ [<?php echo strip_tags($conf['title'])?>]
+ </title>
+ <?php tpl_metaheaders()?>
+ <link rel="shortcut icon" href="<?php echo DOKU_TPL?>images/favicon.ico" />
+</head>
+
+<body>
+<div id="media__manager" class="dokuwiki">
+ <div id="media__left">
+ <?php html_msgarea()?>
+ <h1><?php echo hsc($lang['mediaselect'])?></h1>
+
+ <?php /* keep the id! additional elements are inserted via JS here */?>
+ <div id="media__opts"></div>
+
+ <?php tpl_mediaTree() ?>
+ </div>
+
+ <div id="media__right">
+ <?php tpl_mediaContent() ?>
+ </div>
+</div>
+</body>
+</html>
diff --git a/lib/tpl/default/print.css b/lib/tpl/default/print.css
new file mode 100644
index 000000000..45b60aad2
--- /dev/null
+++ b/lib/tpl/default/print.css
@@ -0,0 +1,228 @@
+
+body {
+ font: 10pt "Lucida Grande", Verdana, Lucida, Helvetica, Arial, sans-serif;
+ background-color: White;
+ color: Black;
+}
+
+table {
+ font-size: 100%;
+ padding: 0;
+ margin: 0;
+}
+
+tr,td,th { padding: 0; margin: 0; }
+
+img { border: 0; }
+
+a {
+ color: #000000;
+ text-decoration: none;
+ background: none !important;
+}
+
+a.interwiki {
+ padding-left: 0px !important;
+}
+
+
+div.meta {
+ clear: both;
+ margin-top: 1em;
+ font-size: 70%;
+ text-align: right;
+}
+
+div.breadcrumbs {
+ display: none;
+}
+
+
+/* --------------------- Text formating -------------------------------- */
+
+/* external link */
+a.urlextern:after {
+ content: " [" attr(href) "]";
+ font-size: 90%;
+}
+
+/* interwiki link */
+a.interwiki:after {
+ content: " [" attr(href) "]";
+ font-size: 90%;
+}
+
+/* email link */
+a.mail:after {
+ content: " [" attr(href) "]";
+ font-size: 90%;
+}
+
+/* existing wikilink */
+a.wikilink1 { text-decoration: underline; }
+
+/* the document */
+div.page {
+ text-align: justify;
+}
+
+/* general headline setup */
+h1, h2, h3, h4, h5 {
+ color: Black;
+ background-color: transparent;
+ font-family: "Lucida Grande", Verdana, Lucida, Helvetica, Arial, sans-serif;
+ font-size: 100%;
+ font-weight: normal;
+ margin-left: 0;
+ margin-right: 0;
+ margin-top: 0;
+ margin-bottom: 1em;
+ padding-left: 0;
+ padding-right: 0;
+ padding-top: 0.5em;
+ padding-bottom: 0;
+ border-bottom: 1px solid #000000;
+ clear: left;
+}
+
+/* special headlines */
+h1 { font-size: 160%; font-weight: bold; }
+h2 { font-size: 150%; }
+h3 { font-size: 140%; border-bottom: none; }
+h4 { font-size: 120%; border-bottom: none; }
+h5 { font-size: 100%; border-bottom: none; }
+
+/* embedded images */
+img.media {
+ margin: 3px;
+}
+
+/* the styles for media images are already in
+ lib/styles/all.css, these are additional styles */
+img.medialeft {
+ margin: 0 1.5em 0 0;
+}
+img.mediaright {
+ margin: 0 0 0 1.5em;
+}
+img.mediacenter {
+}
+
+/* unordered lists */
+ul {
+ line-height: 1.5em;
+ list-style-type: square;
+ margin: 0 0 1em 3.5em;
+ padding: 0;
+}
+
+/* ordered lists */
+ol {
+ line-height: 1.5em;
+ margin: 0 0 1em 3.5em;
+ padding: 0;
+ font-weight: normal;
+}
+
+div.dokuwiki li ul {
+ margin-bottom: 0;
+}
+div.dokuwiki li ol {
+ margin-bottom: 0;
+}
+
+div.dokuwiki ol { list-style-type: decimal; }
+div.dokuwiki ol ol { list-style-type: upper-roman; }
+div.dokuwiki ol ol ol { list-style-type: lower-alpha; }
+div.dokuwiki ol ol ol ol { list-style-type: lower-greek; }
+
+/* the list items overriding the ol definition */
+span.li {
+ font-weight: normal;
+}
+
+pre {
+ font-family: monospace;
+}
+
+/* code blocks by indention */
+pre.pre {
+ font-size: 8pt;
+ padding: 0.5em;
+ border: 1px dashed #000000;
+ color: Black;
+ overflow: visible;
+}
+
+/* code blocks by code tag */
+pre.code {
+ font-size: 8pt;
+ padding: 0.5em;
+ border: 1px dashed #000000;
+ color: Black;
+ overflow: visible;
+}
+
+/* inline code words */
+code {
+ font-size: 120%;
+}
+
+/* code blocks by file tag */
+pre.file {
+ font-size: 8pt;
+ padding: 0.5em;
+ border: 1px dotted #000000;
+ color: Black;
+ overflow: visible;
+}
+
+/* footnotes */
+div.footnotes {
+ clear: both;
+ border-top: 1px solid #000000;
+ padding-left: 1em;
+ margin-top: 1em;
+}
+
+div.fn {
+ font-size: 90%;
+}
+
+a.fn_top {
+ vertical-align: super;
+ font-size: 80%;
+}
+
+a.fn_bot {
+ vertical-align: super;
+ font-size: 80%;
+ font-weight: bold;
+}
+
+acronym {
+ border: 0;
+}
+
+/* ---------- inline tables ------------------- */
+
+table.inline {
+ font-size: 80%;
+ background-color: #ffffff;
+ border-spacing: 0px;
+ border-collapse: collapse;
+}
+
+table.inline th {
+ padding: 3px;
+ border: 1px solid #000000;
+ border-bottom: 2px solid #000000;
+}
+
+table.inline td {
+ padding: 3px;
+ border: 1px solid #000000;
+}
+
+.toc, .footerinc, .header, .bar, .user { display: none; }
+
diff --git a/lib/tpl/default/rtl.css b/lib/tpl/default/rtl.css
new file mode 100644
index 000000000..82c85839b
--- /dev/null
+++ b/lib/tpl/default/rtl.css
@@ -0,0 +1,154 @@
+/**
+ * Layout and design corrections for right-to-left languages
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ */
+
+.bar-left {
+ float: right;
+ text-align: right;
+}
+
+.bar-right {
+ float: left;
+ text-align: left;
+}
+
+.pagename {
+ float: right;
+ text-align: right;
+}
+
+.logo {
+ float: left;
+ text-align: left;
+}
+
+label {
+ text-align: left;
+}
+
+label.simple {
+ text-align: right;
+}
+
+div.meta div.user {
+ float: right;
+}
+
+div.meta div.doc {
+ text-align: left;
+}
+
+/* ------------------ Design corrections --------------------------------- */
+
+div.dokuwiki ul,
+div.dokuwiki ol {
+ margin: 0.5em 3.5em 0.5em 0;
+}
+div.dokuwiki li ul,
+div.dokuwiki li ol {
+ margin: 0.5em 1.5em 0.5em 0;
+}
+
+div.dokuwiki a.urlextern,
+div.dokuwiki a.interwiki,
+div.dokuwiki a.windows,
+div.dokuwiki a.mail {
+ /* should work but doesn't - so we just disable icons here*/
+ /*
+ background-position: right 1px;
+ padding-right: 16px;
+ */
+ background-image: none !important;
+ padding: 0px 0px 0px 0px;
+}
+
+div.dokuwiki div.secedit input.button {
+ float: left;
+}
+
+/* headlines */
+div.dokuwiki h1, div.dokuwiki h2, div.dokuwiki h3, div.dokuwiki h4, div.dokuwiki h5 {
+ clear: right;
+}
+
+/* special headlines */
+div.dokuwiki h1 { margin-left: 0px; margin-right: 0px; }
+div.dokuwiki h2 { margin-left: 0px; margin-right: 20px; }
+div.dokuwiki h3 { margin-left: 0px; margin-right: 40px; }
+div.dokuwiki h4 { margin-left: 0px; margin-right: 60px; }
+div.dokuwiki h5 { margin-left: 0px; margin-right: 80px; }
+
+/* indent different sections */
+div.dokuwiki div.level1 { margin-left: 0px; margin-right: 3px; }
+div.dokuwiki div.level2 { margin-left: 0px; margin-right: 23px; }
+div.dokuwiki div.level3 { margin-left: 0px; margin-right: 43px; }
+div.dokuwiki div.level4 { margin-left: 0px; margin-right: 63px; }
+div.dokuwiki div.level5 { margin-left: 0px; margin-right: 83px; }
+
+/* TOC control */
+div.dokuwiki div.toc {
+ float: left;
+}
+
+div.dokuwiki div.tocheader {
+ text-align: right;
+}
+
+div.dokuwiki #toc__inside {
+ text-align: right;
+}
+
+div.dokuwiki ul.toc {
+ padding: 0;
+ padding-right: 1em;
+}
+
+div.dokuwiki ul.toc li {
+ background-position: right 0.6em;
+ padding-right: 0.4em;
+ direction: rtl;
+}
+
+div.dokuwiki ul.toc li.clear {
+ padding-right: 0.4em;
+}
+
+div.dokuwiki .code {
+ direction: ltr;
+ text-align: left;
+}
+div.dokuwiki blockquote {
+ border-left: 0;
+ padding-left: 0;
+ border-right: 2px solid __border__;
+ padding-right: 3px;
+}
+
+/* Admin corrections */
+#admin__version {
+ clear: right;
+ float: left;
+}
+
+.dokuwiki ul.admin_tasks {
+ float: right;
+}
+
+.dokuwiki ul.admin_tasks li {
+ padding-left: 0px;
+ padding-right: 35px;
+ background: transparent none no-repeat scroll right 0;
+ text-align: right;
+}
+
+/* Search corrections */
+div.dokuwiki ul.search_quickhits li {
+ float: right;
+}
+
+div#qsearch__out {
+ text-align: right;
+}
diff --git a/lib/tpl/default/style.ini b/lib/tpl/default/style.ini
new file mode 100644
index 000000000..7d27381c9
--- /dev/null
+++ b/lib/tpl/default/style.ini
@@ -0,0 +1,72 @@
+; Please see http://www.php.net/manual/en/function.parse-ini-file.php
+; for limitations of the ini format used here
+
+; Define the stylesheets your template uses here. The second value
+; defines for which output media the style should be loaded. Currently
+; print, screen and rtl are supported. rtl styles are loaded additionally
+; to screen styles if a right-to-left language is selected (eg. hebrew)
+[stylesheets]
+layout.css = screen
+design.css = screen
+style.css = screen
+
+media.css = screen
+_mediaoptions.css = screen
+_admin.css = screen
+_linkwiz.css = screen
+_subscription.css = screen
+_mediamanager.css = screen
+_tabs.css = screen
+_fileuploader.css = screen
+
+rtl.css = rtl
+print.css = print
+
+; This section is used to configure some placeholder values used in
+; the stylesheets. Changing this file is the simplest method to
+; give your wiki a new look.
+[replacements]
+
+;--------------------------------------------------------------------------
+;------ guaranteed dokuwiki color placeholders that every plugin can use
+; main text and background colors
+__text__ = "#000"
+__background__ = "#fff"
+; alternative text and background colors
+__text_alt__ = "#638c9c"
+__background_alt__ = "#dee7ec"
+; neutral text and background colors
+__text_neu__ = "#666"
+__background_neu__ = "#f5f5f5"
+; border color
+__border__ = "#8cacbb"
+;--------------------------------------------------------------------------
+
+; other text and background colors
+__text_other__ = "#ccc"
+__background_other__ = "#f7f9fa"
+
+; these are used for links
+__extern__ = "#436976"
+__existing__ = "#090"
+__missing__ = "#f30"
+
+; highlighting search snippets
+__highlight__ = "#ff9"
+
+
+;--------------------------------------------------------------------------
+;------ for keeping old templates and plugins compatible to the old pattern
+; (to be deleted at the next or after next release)
+__white__ = "#fff"
+__lightgray__ = "#f5f5f5"
+__mediumgray__ = "#ccc"
+__darkgray__ = "#666"
+__black__ = "#000"
+
+; these are the shades of blue
+__lighter__ = "#f7f9fa"
+__light__ = "#eef3f8"
+__medium__ = "#dee7ec"
+__dark__ = "#8cacbb"
+__darker__ = "#638c9c"
diff --git a/lib/tpl/index.php b/lib/tpl/index.php
new file mode 100644
index 000000000..0273e5678
--- /dev/null
+++ b/lib/tpl/index.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * This file reads the style.ini of the used template and displays the
+ * replacements defined in it. Color replacements will be displayed
+ * visually. This should help with adjusting and using the styles
+ * specified in the style.ini
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+if(!defined('NOSESSION')) define('NOSESSION',1);
+require_once(DOKU_INC.'inc/init.php');
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Template Replacements</title>
+ <style type="text/css">
+ body {
+ background-color: #fff;
+ color: #000;
+ }
+ caption {
+ font-weight: bold;
+ }
+ td {
+ margin: 0;
+ padding: 0.5em 2em;
+ font-family: monospace;
+ font-size: 120%;
+ border: 1px solid #fff;
+ }
+ tr:hover td {
+ border: 1px solid #ccc;
+ }
+ .color {
+ padding: 0.25em 1em;
+ border: 1px #000 solid;
+ }
+ </style>
+</head>
+<body>
+<?php
+$ini = @parse_ini_file($conf['template'].'/style.ini',true);
+if ($ini) {
+ echo '<table>';
+ echo "<caption>".htmlspecialchars($conf['template'])."'s style.ini</caption>";
+ foreach($ini['replacements'] as $key => $val){
+ echo '<tr>';
+ echo '<td>'.htmlspecialchars($key).'</td>';
+ echo '<td>'.htmlspecialchars($val).'</td>';
+ echo '<td>';
+ if(preg_match('/^#[0-f]{3,6}$/i',$val)){
+ echo '<div class="color" style="background-color:'.$val.';">&nbsp;</div>';
+ }
+ echo '</td>';
+ echo '</tr>';
+ }
+ echo '</table>';
+} else {
+ echo "<p>Non-existent template: <strong>".htmlspecialchars($conf['template'])."</strong></p>";
+}
+?>
+</body>
+</html>