diff --git a/LICENSE.txt b/LICENSE.md similarity index 100% rename from LICENSE.txt rename to LICENSE.md diff --git a/README.md b/README.md index 2d1c80a4..f9b9b2ca 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,47 @@ # h5ai +**a modern HTTP web server index for Apache httpd, lighttpd, nginx and Cherokee** -Please don't use files from the `src` folder for installation. -They need to be preprocessed to work correctly. You'll find a preprocessed -package on the [project page](http://larsjung.de/h5ai/). +The preferred way to report a bug or make a feature request is to +create [a new issue](http://github.com/lrsjng/h5ai/issues/new) on GitHub! -* to report a bug or make a feature request please create [a new issue](http://github.com/lrsjng/h5ai/issues/new) on GitHub -* website with download, docs and demo: -* sources: -h5ai is provided under the terms of the [MIT License](http://github.com/lrsjng/h5ai/blob/master/LICENSE.txt). +## Install + +(**note:** please don't use files from the `src` folder for installation, +they need to be preprocessed to work correctly) + +You'll find a preprocessed package, as well as detailed installation +instructions on the [project page](http://larsjung.de/h5ai/). + + +## Build + +(there are repositories of the latest [releases](http://release.larsjung.de/h5ai/) and [dev builds](http://release.larsjung.de/h5ai/dev/)) + +If you want to build **h5ai** yourself you need to install the build tool [fQuery](http://larsjung.de/fquery/) first: + + > npm install -g fquery + +This will install fQuery and its command line tool `makejs`. Run `makejs --help` to see if everything +worked fine. + +To clone and build the project run the following commands. +You'll find a new directory `build` including a fresh zipball. + + > git clone git://github.com/lrsjng/h5ai.git + > cd h5ai + > makejs release + + +## License + +**h5ai** is provided under the terms of the [MIT License](http://github.com/lrsjng/h5ai/blob/develop/LICENSE.md). + It profits from these great projects: -[AmplifyJS](http://amplifyjs.com) (MIT/GPL), [Faenza icon set](http://tiheum.deviantart.com/art/Faenza-Icons-173323228) (GPL), -[HTML5 ★ Boilerplate](http://html5boilerplate.com), -[jQuery](http://jquery.com) (MIT/GPL), +[HTML5 ★ Boilerplate](http://html5boilerplate.com) (MIT), +[jQuery](http://jquery.com) (MIT), +[jQuery.filedrop](http://www.github.com/weixiyen/jquery-filedrop) (MIT), [jQuery.fracs](http://larsjung.de/fracs/) (MIT), [jQuery.mousewheel](http://github.com/brandonaaron/jquery-mousewheel) (MIT), [jQuery.qrcode](http://larsjung.de/qrcode/) (MIT), @@ -22,26 +50,41 @@ It profits from these great projects: [Modernizr](http://www.modernizr.com) (MIT/BSD), [modulejs](http://larsjung.de/modulejs/) (MIT), [Moment.js](http://momentjs.com) (MIT), +[spin.js](http://fgnass.github.com/spin.js/) (MIT), [SyntaxHighlighter](http://alexgorbatchev.com/SyntaxHighlighter/) (MIT/GPL), [Underscore.js](http://underscorejs.org) (MIT) -## Build - -A prebuilt package can be found on the [project page](http://larsjung.de/h5ai/). If you want to build -h5ai yourself you need to install [fQuery](http://larsjung.de/fquery/) first: - - > npm install -g fquery - -To build the project run the following command inside the project's root directory - - > makejs - -Run `makejs -t` to list all possible targets. - - - ## Changelog +(**h5ai** uses [semantic versioning](http://semver.org/)) + +### v0.22 - *2012-??-??* + +* general changes h5ai directory layout and configuration +* splits configuration file (`config.json`) into files `options.json`, `types.json` and `langs.json` +* localization now in separate files +* adds auto-refresh +* adds drag'n'drop upload (PHP, experimental) +* adds file deletion (PHP, experimental) +* cleans and improves PHP code +* PHP no longer respects htaccess restrictions (so be careful) +* PHP ignore patterns might include paths now +* improves separation between aai and php mode +* improves performance in aai mode +* adds optional binary prefixes for file sizes +* improves filter: autofocus on keypress, clear on `ESC` +* download packages now packaged relative to current folder +* download package name changable +* splits type `js` into `js` and `json` +* prevents some errors with files > 2GB on 32bit OS +* adds max subfolder size in tree view +* adds ctrl-click file selection +* adds Piwik analytics extension +* temp download packages are now stored in the `cache`-folder and deleted as soon as possible +* updates translations +* adds `he` translation by [Tomer Cohen](https://github.com/tomer) +* updates 3rd party libs + ### v0.21 - *2012-08-06* diff --git a/makefile.js b/makefile.js index d10cc627..cc43d53d 100644 --- a/makefile.js +++ b/makefile.js @@ -3,10 +3,8 @@ var path = require('path'), - child_process = require('child_process'); - -var version = '0.21', + pkg = require('./package.json'), root = path.resolve(__dirname), src = path.join(root, 'src'), @@ -34,14 +32,18 @@ var version = '0.21', ] }, - mapper = function (blob) { - - return blob.source.replace(src, build).replace(/\.less$/, '.css'); + handlebarsEnv = { + pkg: pkg }, - mapperRoot = function (blob) { + mapSrc = function (blob) { - return blob.source.replace(root, build + '/_h5ai'); + return blob.source.replace(src, build).replace(/\.less$/, '.css').replace(/\.jade$/, ''); + }, + + mapRoot = function (blob) { + + return blob.source.replace(root, path.join(build, '_h5ai')); }; @@ -49,137 +51,119 @@ module.exports = function (make) { var Event = make.Event, $ = make.fQuery, - moment = make.moment, - stamp, replacements; + moment = make.moment; + make.version('>=0.8.1'); make.defaults('build'); make.before(function () { - stamp = moment(); - - replacements = { - version: version, - stamp: stamp.format('YYYY-MM-DD HH:mm:ss') - }; - - Event.info({ method: 'before', message: version + ' ' + replacements.stamp }); + handlebarsEnv.stamp = moment().format('YYYY-MM-DD HH:mm:ss'); }); - make.target('inc', [], 'increase build number, if any') - .sync(function () { + make.target('check-version', [], 'add git info to dev builds').async(function (done, fail) { - var re = /-(\d+)$/; - var match = version.match(re); + if (!/-dev$/.test(pkg.version)) { + done(); + return; + } - if (match) { - var number = parseInt(match[1], 10) + 1; - var newVersion = version.replace(re, '-' + number); + $.git(root, function (err, result) { - $('makefile.js').replace([[version, newVersion]]).write($.OVERWRITE, 'makefile.js'); - - version = newVersion; - replacements.version = version; - Event.ok({ method: 'inc', message: 'version is now ' + version }); - } - }); - - - make.target('clean', [], 'delete build folder') - .sync(function () { - - $.rmfr($.I_AM_SURE, build); - }); - - - make.target('lint', [], 'lint all JavaScript files with JSHint') - .sync(function () { - - $(src + '/_h5ai/js: **/*.js, ! *.min.js, ! inc/lib/**') - .jshint(jshint); - }); - - - make.target('build', [], 'build all updated files') - .sync(function () { - - $(src + ': _h5ai/js/*.js') - .modified(mapper, $(src + ': _h5ai/js/**')) - .includify() - .uglifyjs() - .write($.OVERWRITE, mapper); - - $(src + ': _h5ai/css/*.less') - .modified(mapper, $(src + ': _h5ai/css/**')) - .less() - .cssmin() - .write($.OVERWRITE, mapper); - - $(src + ': **, ! _h5ai/js/**, ! _h5ai/css/**') - .modified(mapper) - .mustache(replacements) - .write($.OVERWRITE, mapper); - - $(root + ': README*, LICENSE*') - .modified(mapperRoot) - .write($.OVERWRITE, mapperRoot); - }); - - - make.target('build-uncompressed', [], 'build all updated files without compression') - .sync(function () { - - $(src + ': _h5ai/js/*.js') - .modified(mapper, $(src + ': _h5ai/js/**')) - .includify() - // .uglifyjs() - .write($.OVERWRITE, mapper); - - $(src + ': _h5ai/css/*.less') - .modified(mapper, $(src + ': _h5ai/css/**')) - .less() - // .cssmin() - .write($.OVERWRITE, mapper); - - $(src + ': **, ! _h5ai/js/**, ! _h5ai/css/**') - .modified(mapper) - .mustache(replacements) - .write($.OVERWRITE, mapper); - - $(root + ': README*, LICENSE*') - .modified(mapperRoot) - .write($.OVERWRITE, mapperRoot); - }); - - - make.target('release', ['inc', 'clean', 'build'], 'create a zipball') - .async(function (done, fail) { - - var target = path.join(build, 'h5ai-' + version + '.zip'), - cmd = 'zip', - args = ['-ro', target, '_h5ai'], - options = { cwd: build }, - proc = child_process.spawn(cmd, args, options); - - Event.info({ method: 'exec', message: cmd + ' ' + args.join(' ') }); - - // proc.stdout.on('data', function (data) { - // process.stdout.write(data); - // }); - proc.stderr.on('data', function (data) { - process.stderr.write(data); - }); - proc.on('exit', function (code) { - if (code) { - Event.error({ method: 'exec', message: cmd + ' exit code ' + code }); - fail(); - } else { - Event.ok({ method: 'exec', message: 'created zipball ' + target }); - done(); - } + pkg.version += '-' + result.revListOriginMasterHead.length + '-' + result.revParseHead.slice(0, 7); + Event.info({ + method: 'check-version', + message: 'version set to ' + pkg.version }); + done(); }); + }); + + + make.target('clean', [], 'delete build folder').sync(function () { + + $.rmfr($.I_AM_SURE, build); + }); + + + make.target('lint', [], 'lint all JavaScript files with JSHint').sync(function () { + + $(src + '/_h5ai/client/js: **/*.js, ! lib/**') + .jshint(jshint); + }); + + + make.target('build', ['check-version'], 'build all updated files').sync(function () { + + $(src + ': _h5ai/client/js/*.js') + .modified(mapSrc, $(src + ': _h5ai/client/js/**')) + .includify() + .uglifyjs() + .write($.OVERWRITE, mapSrc); + + $(src + ': _h5ai/client/css/*.less') + .modified(mapSrc, $(src + ': _h5ai/client/css/**')) + .less() + .cssmin() + .write($.OVERWRITE, mapSrc); + + $(src + ': **/*.jade') + .modified(mapSrc) + .handlebars(handlebarsEnv) + .jade() + .write($.OVERWRITE, mapSrc); + + $(src + ': **, ! _h5ai/client/js/**, ! _h5ai/client/css/**, ! **/*.jade') + .modified(mapSrc) + .handlebars(handlebarsEnv) + .write($.OVERWRITE, mapSrc); + + $(root + ': README*, LICENSE*') + .modified(mapRoot) + .write($.OVERWRITE, mapRoot); + }); + + + make.target('build-uncompressed', ['check-version'], 'build all updated files without compression').sync(function () { + + $(src + ': _h5ai/client/js/*.js') + .modified(mapSrc, $(src + ': _h5ai/client/js/**')) + .includify() + // .uglifyjs() + .write($.OVERWRITE, mapSrc); + + $(src + ': _h5ai/client/css/*.less') + .modified(mapSrc, $(src + ': _h5ai/client/css/**')) + .less() + // .cssmin() + .write($.OVERWRITE, mapSrc); + + $(src + ': **/*.jade') + .modified(mapSrc) + .handlebars(handlebarsEnv) + .jade() + .write($.OVERWRITE, mapSrc); + + $(src + ': **, ! _h5ai/client/js/**, ! _h5ai/client/css/**, ! **/*.jade') + .modified(mapSrc) + .handlebars(handlebarsEnv) + .write($.OVERWRITE, mapSrc); + + $(root + ': README*, LICENSE*') + .modified(mapRoot) + .write($.OVERWRITE, mapRoot); + }); + + + make.target('release', ['clean', 'build'], 'create a zipball').async(function (done, fail) { + + $(build + ': **').shzip({ + target: path.join(build, pkg.name + '-' + pkg.version + '.zip'), + dir: build, + callback: done + }); + }); }; diff --git a/package.json b/package.json new file mode 100644 index 00000000..c1cd3570 --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "h5ai", + "version": "0.22-dev", + "description": "a modern HTTP web server index", + "url": "http://larsjung.de/h5ai/", + "author": "Lars Jung", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/lrsjng/h5ai.git" + } +} diff --git a/src/_h5ai/.htaccess b/src/_h5ai/.htaccess index 6751cfa3..9540a5a2 100644 --- a/src/_h5ai/.htaccess +++ b/src/_h5ai/.htaccess @@ -1,6 +1,8 @@ Options -Indexes +DirectoryIndex index.html + Header set Cache-Control "public" ExpiresActive on @@ -11,7 +13,7 @@ Options -Indexes # cache.manifest needs re-requests in FF 3.6 (thx Remy ~Introducing HTML5) ExpiresByType text/cache-manifest "access plus 0 seconds" - # your document html + # your document html ExpiresByType text/html "access plus 0 seconds" # data diff --git a/src/_h5ai/apache/h5ai-footer.html b/src/_h5ai/apache/h5ai-footer.html deleted file mode 100644 index 72b45348..00000000 --- a/src/_h5ai/apache/h5ai-footer.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/_h5ai/apache/h5ai-header.html b/src/_h5ai/apache/h5ai-header.html deleted file mode 100644 index 6d37b825..00000000 --- a/src/_h5ai/apache/h5ai-header.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - Directory index · styled with h5ai - - - - - - - - - -
- -
-
-
-
-
- - h5ai {{version}} - ⚡ JavaScript is disabled! ⚡ - ⚡ Some features disabled! Works best in modern browsers. ⚡ - - - -
-
- diff --git a/src/_h5ai/css/inc/bottombar.less b/src/_h5ai/client/css/inc/bottombar.less similarity index 88% rename from src/_h5ai/css/inc/bottombar.less rename to src/_h5ai/client/css/inc/bottombar.less index d902d81c..74c3ef69 100644 --- a/src/_h5ai/css/inc/bottombar.less +++ b/src/_h5ai/client/css/inc/bottombar.less @@ -3,6 +3,7 @@ position: fixed; z-index: 5; width: 100%; + height: 18px; left: 0; bottom: 0; padding: 6px 0 8px 0; @@ -24,18 +25,19 @@ } } .left { + position: absolute; + left: 0; display: block; padding: 0 8px; - float: left } .center { display: block; - margin: 0 100px; } .right { + position: absolute; + right: 0; display: block; padding: 0 8px; - float: right } .noJsMsg { color: #c33; @@ -57,6 +59,10 @@ .sep { display: inline-block; padding: 0 6px; + + &:before { + content: '·' + } } &.default { } diff --git a/src/_h5ai/css/inc/content.less b/src/_h5ai/client/css/inc/content.less similarity index 91% rename from src/_h5ai/css/inc/content.less rename to src/_h5ai/client/css/inc/content.less index 3c17fbfe..6511f851 100644 --- a/src/_h5ai/css/inc/content.less +++ b/src/_h5ai/client/css/inc/content.less @@ -5,8 +5,8 @@ font-size: 16px; } - #content-header, #content-footer { + color: #333; a, a:active, a:visited { color: #2080FF; @@ -14,12 +14,11 @@ cursor: pointer; &:hover { - color: #68A9FF; + color: #555; } } } - #content-header { padding-bottom: 12px; margin-bottom: 32px; diff --git a/src/_h5ai/client/css/inc/context-menu.less b/src/_h5ai/client/css/inc/context-menu.less new file mode 100644 index 00000000..6014e527 --- /dev/null +++ b/src/_h5ai/client/css/inc/context-menu.less @@ -0,0 +1,32 @@ + +#extended .context-menu { + + display: block; + position: absolute; + right: 0; + top: 0; + background-color: rgb(241,241,241); + border: 1px solid rgb(210,210,210); + color: #999; + z-index: 10; + font-size: 0.9em; + + ul { + margin: 0; + padding: 0; + list-style: none; + text-align: left; + + li { + padding: 8px 12px 10px 12px; + white-space: nowrap; + border-top: 1px solid rgb(231,231,231); + .transition(all 0.2s ease-in-out); + + &:hover { + color: #e80; + background-color: rgba(255,255,255,0.8); + } + } + } +} diff --git a/src/_h5ai/client/css/inc/delete.less b/src/_h5ai/client/css/inc/delete.less new file mode 100644 index 00000000..6008c9d4 --- /dev/null +++ b/src/_h5ai/client/css/inc/delete.less @@ -0,0 +1,30 @@ + +#delete { + display: none; + .topbar-right; + .transition(all 0.2s ease-in-out); + + &.failed { + background-color: rgba(255,0,0,0.5); + } +} + +#delete-auth { + display: none; + position: fixed; + z-index: 5; + left: 0; + top: 0; + .vert-gradient(rgb(241,241,241), rgb(228,228,228)); + border: 1px solid rgb(210,210,210); + + input { + display: block; + margin: 4px 6px; + border: 1px solid rgb(210,210,210); + font-family: Ubuntu, sans-serif; + color: #555; + background-color: rgba(255,255,255,1); + width: 100px; + } +} diff --git a/src/_h5ai/css/inc/download.less b/src/_h5ai/client/css/inc/download.less similarity index 100% rename from src/_h5ai/css/inc/download.less rename to src/_h5ai/client/css/inc/download.less diff --git a/src/_h5ai/client/css/inc/dropbox.less b/src/_h5ai/client/css/inc/dropbox.less new file mode 100644 index 00000000..785dc2b6 --- /dev/null +++ b/src/_h5ai/client/css/inc/dropbox.less @@ -0,0 +1,89 @@ + +#content { + border: 1px dashed #fff; + .border-radius(8px); + .transition(border-color 0.2s ease-in-out); + + &.hint { + border-color: #ddd; + } + &.match { + border-color: #999; + } +} + + +#uploads { + width: 450px; + margin: 12px auto; + padding: 0; + list-style: none; + + .upload { + color: #555; + font-size: 0.9em; + + .name { + display: inline-block; + white-space: nowrap; + overflow: hidden; + + &:before { + display: inline-block; + content: '•'; + color: #55c; + width: 1em; + text-align: center; + padding-right: 1em; + } + } + + .size { + display: none; + float: right; + white-space: nowrap; + + &:after { + content: ' bytes' + } + } + + .error { + float: right; + white-space: nowrap; + color: #c55; + } + + .finished { + float: right; + white-space: nowrap; + color: #008200; + } + + .progress { + display: inline-block; + margin: 4px 8px; + + width: 84px; + height: 8px; + background-color: #ddd; + overflow: hidden; + float: right; + + .bar { + width: 0%; + height: 100%; + background-color: #999; + } + } + + &.finished .name:before { + content: '✔'; + color: #008200; + } + &.error .name:before { + content: '✖'; + color: #c55; + } + } +} diff --git a/src/_h5ai/client/css/inc/extended-details.less b/src/_h5ai/client/css/inc/extended-details.less new file mode 100644 index 00000000..7c30e340 --- /dev/null +++ b/src/_h5ai/client/css/inc/extended-details.less @@ -0,0 +1,46 @@ + +#extended.view-details { + + li { + + &.header { + display: list-item; + } + + &.entry { + + a, a:active, a:visited { + border-bottom: 1px solid #e8e8e8; + } + + // needs to be here, to not conflict with header fields + .icon, .label, .date, .size { + padding: 6px; + } + } + + .icon.small { + display: inline-block; + position: absolute; + left: 0; + top: -2px; + width: 16px; + } + + .label { + margin: 0 270px 0 24px; + } + + .date { + position: absolute; + right: 100px; + top: 0; + } + + .size { + position: absolute; + right: 0; + top: 0; + } + } +} diff --git a/src/_h5ai/client/css/inc/extended-grid.less b/src/_h5ai/client/css/inc/extended-grid.less new file mode 100644 index 00000000..1d69c83c --- /dev/null +++ b/src/_h5ai/client/css/inc/extended-grid.less @@ -0,0 +1,42 @@ + +#extended.view-grid { + + li { + + &.entry { + float: left; + + a, a:active, a:visited { + float: left; + margin: 2px; + padding: 8px; + width: 164px; + height: 24px; + border: 2px solid rgba(0,0,0,0); + .border-radius(5px); + + &:hover, &.hover { + border-color: #e8e8e8; + } + } + } + + .icon.small { + display: inline-block; + position: relative; + left: 0; + top: -2px; + width: 16px; + } + + .label { + display: inline-block; + padding-left: 6px; + max-width: 140px; + } + + .date, .size { + display: none; + } + } +} diff --git a/src/_h5ai/client/css/inc/extended-icons.less b/src/_h5ai/client/css/inc/extended-icons.less new file mode 100644 index 00000000..006bef97 --- /dev/null +++ b/src/_h5ai/client/css/inc/extended-icons.less @@ -0,0 +1,47 @@ + +#extended.view-icons { + + li { + text-align: center; + + &.entry { + float: left; + + a, a:active, a:visited { + float: left; + margin: 8px; + padding: 8px; + width: 100px; + height: 120px; + border: 2px solid rgba(0,0,0,0); + .border-radius(5px); + + &:hover, &.hover { + border-color: #e8e8e8; + } + } + } + + .icon.big { + display: block; + height: 48px; + margin-bottom: 6px; + } + + .label { + text-align: center; + word-wrap: break-word; + white-space: normal; + } + + .date, .size { + display: none; + } + } + + .empty, .no-match { + margin: 0 120px; + padding: 16px; + height: 120px; + } +} diff --git a/src/_h5ai/client/css/inc/extended-list.less b/src/_h5ai/client/css/inc/extended-list.less new file mode 100644 index 00000000..f32e3e86 --- /dev/null +++ b/src/_h5ai/client/css/inc/extended-list.less @@ -0,0 +1,39 @@ + +#extended.view-list { + + li { + + &.entry { + + a, a:active, a:visited { + height: 56px; + border-bottom: 1px solid #e8e8e8; + } + } + + .icon, .label, .date, .size { + padding: 6px; + } + + .icon.big { + display: inline-block; + position: absolute; + left: 0; + top: -2px; + width: 100px; + } + + .label { + margin: 0 270px 0 106px; + } + + .date { + margin: 0 0 0 106px; + } + + .date, .size { + position: relative; + top: -6px; + } + } +} diff --git a/src/_h5ai/client/css/inc/extended.less b/src/_h5ai/client/css/inc/extended.less new file mode 100644 index 00000000..8ec706e2 --- /dev/null +++ b/src/_h5ai/client/css/inc/extended.less @@ -0,0 +1,168 @@ + +#selection-rect { + display: none; + position: absolute; + left: 0; + top: 0; + z-index: 2; + border: 1px dashed rgba(240,100,0,0.5); + background-color: rgba(240,100,0,0.2); +} + +#extended { + display: none; + + a, a:active, a:visited { + color: #333; + cursor: pointer; + text-decoration: none; + } + + ul { + margin: 0; + padding: 0; + list-style: none; + } + + li { + position: relative; + white-space: nowrap; + + &.header { + display: none; + font-size: 13px; + + a, a:active, a:visited { + padding: 6px 6px 18px 6px; + opacity: 0.4; + .transition(all 0.2s ease-in-out); + + img { + display: none; + position: relative; + top: -2px; + width: 12px; + height: 12px; + padding: 0 8px; + } + &:hover { + color: #555; + opacity: 0.9; + } + &.ascending img.ascending { + display: inline; + } + &.descending img.descending { + display: inline; + } + } + } + + &.entry { + + a, a:active, a:visited { + display: block; + overflow: hidden; + + &:hover, &.hover { + color: #e80; + background-color: #f6f6f6; + border-color: #e8e8e8; + } + } + + &.selected:not(.selecting), &.selecting:not(.selected) { + + a, a:active, a:visited { + border-color: rgba(240,100,0,0.2); + background-color: rgba(240,100,0,0.2); + + &:hover, &.hover { + border-color: rgba(240,100,0,0.2); + background-color: rgba(240,100,0,0.2); + } + } + } + } + + &.error { + + a, a:active, a:visited { + color: #aaa; + + &:hover, &.hover { + color: #e80; + } + } + + .label .hint { + padding: 0 6px; + font-size: 0.9em; + color: #c55; + } + } + + &.folder-parent { + + .date, .size { + display: none; + } + } + + .icon { + display: none; + text-align: center; + + img { + + &.thumb { + .box-shadow(0 0 0 1px #ddd); + } + } + + &.small { + + img { + max-width: 16px; + max-height: 16px; + } + } + + &.big { + + img { + max-width: 100px; + max-height: 48px; + } + } + } + + .label { + display: block; + overflow: hidden; + text-align: left; + } + + .date { + text-align: right; + width: 160px; + } + + .size { + text-align: right; + width: 80px; + } + } + + .empty, .no-match { + margin: 50px 0; + text-align: center; + color: #ddd; + font-size: 5em; + font-weight: bold; + } + + .no-match { + display: none; + } +} diff --git a/src/_h5ai/css/inc/apache-autoindex-table.less b/src/_h5ai/client/css/inc/fallback-table.less similarity index 95% rename from src/_h5ai/css/inc/apache-autoindex-table.less rename to src/_h5ai/client/css/inc/fallback-table.less index 65fad4cf..c2180336 100644 --- a/src/_h5ai/css/inc/apache-autoindex-table.less +++ b/src/_h5ai/client/css/inc/fallback-table.less @@ -1,7 +1,7 @@ #data-apache-autoindex, #data-php-no-js-fallback { max-width: 960px; - margin: 0 auto; + margin: 0 auto 80px auto; table { display: block; @@ -57,6 +57,8 @@ td:nth-child(1), th:nth-child(1) { text-align: center; width: 16px; + color: #ccc; + font-size: 0.9em; img { width: 16px; diff --git a/src/_h5ai/css/inc/filter.less b/src/_h5ai/client/css/inc/filter.less similarity index 100% rename from src/_h5ai/css/inc/filter.less rename to src/_h5ai/client/css/inc/filter.less diff --git a/src/_h5ai/client/css/inc/general.less b/src/_h5ai/client/css/inc/general.less new file mode 100644 index 00000000..4546397d --- /dev/null +++ b/src/_h5ai/client/css/inc/general.less @@ -0,0 +1,24 @@ + +html { overflow-y: auto; } +::-moz-selection { background: #68A9FF; color: #fff; text-shadow: none; } +::selection { background: #68A9FF; color: #fff; text-shadow: none; } + +body { + font-family: Ubuntu, sans-serif; + font-size: 13px; + color: #555; + background-color: #fff; + margin: 30px; +} + +html.js .hideOnJs, html.no-js .hideOnNoJs { + display: none; +} +html.oldie { + .oldBrowser { + display: inline !important; + } + #tree { + display: none !important; + } +} diff --git a/src/_h5ai/css/inc/h5ai-info.less b/src/_h5ai/client/css/inc/h5ai-info.less similarity index 94% rename from src/_h5ai/css/inc/h5ai-info.less rename to src/_h5ai/client/css/inc/h5ai-info.less index c1ad76ed..1a7cb7a1 100644 --- a/src/_h5ai/css/inc/h5ai-info.less +++ b/src/_h5ai/client/css/inc/h5ai-info.less @@ -9,8 +9,6 @@ body#h5ai-info { .build-version { display: block; - // font-size: 0.9em; - // color: #aaa; } .build-stamp { display: block; @@ -66,7 +64,7 @@ body#h5ai-info { margin: 4px 0 12px 12px; font-size: 0.7em; color: #aaa; - width: 300px; + width: 310px; line-height: 1.2em; } } diff --git a/src/_h5ai/css/inc/l10n.less b/src/_h5ai/client/css/inc/l10n.less similarity index 65% rename from src/_h5ai/css/inc/l10n.less rename to src/_h5ai/client/css/inc/l10n.less index 730e1e67..4ece6ed8 100644 --- a/src/_h5ai/css/inc/l10n.less +++ b/src/_h5ai/client/css/inc/l10n.less @@ -33,21 +33,21 @@ padding: 0; list-style: none; text-align: left; + } - li { - padding: 8px 24px 10px 24px; - white-space: nowrap; - border-top: 1px solid rgb(231,231,231); - .transition(all 0.2s ease-in-out); + li { + padding: 8px 24px 10px 24px; + white-space: nowrap; + border-top: 1px solid rgb(231,231,231); + .transition(all 0.2s ease-in-out); - &.current { - color: #333; - background-color: rgba(255,255,255,0.8); - } - &:hover { - color: #e80; - background-color: rgba(255,255,255,0.8); - } + &.current { + color: #333; + background-color: rgba(255,255,255,0.8); + } + &:hover { + color: #e80; + background-color: rgba(255,255,255,0.8); } } } diff --git a/src/_h5ai/css/inc/preview-img.less b/src/_h5ai/client/css/inc/preview-img.less similarity index 69% rename from src/_h5ai/css/inc/preview-img.less rename to src/_h5ai/client/css/inc/preview-img.less index 7e6f9540..f11e9708 100644 --- a/src/_h5ai/css/inc/preview-img.less +++ b/src/_h5ai/client/css/inc/preview-img.less @@ -9,6 +9,7 @@ z-index: 100; background-color: rgba(0,0,0,0.5); + .transition(background-color 0.3s ease-in-out); text-align: center; } @@ -18,11 +19,22 @@ } +// @check-white: rgba(255,255,255,0.5); +// @check-black: rgba(0,0,0,0.2); +@check-white: #f8f8f8; +@check-black: #e8e8e8; #pv-img-image { max-width: 100%; max-height: 100%; border: 2px solid #fff; .border-radius(4px); + + background-color: @check-white; + background-image: + -webkit-linear-gradient(45deg, @check-black 25%, transparent 25%, transparent 75%, @check-black 75%, @check-black), + -webkit-linear-gradient(45deg, @check-black 25%, transparent 25%, transparent 75%, @check-black 75%, @check-black); + background-size: 60px 60px; + background-position: 0 0, 30px 30px } #pv-img-overlay.fullscreen { @@ -108,15 +120,15 @@ } } -#pv-img-topbar { - position: fixed; - z-index: 5; - width: 100%; - left: 0; - top: 0; - .vert-gradient(rgb(37,37,37), rgb(24,24,24)); - border-bottom: 1px solid rgb(27,27,27); -} +// #pv-img-topbar { +// position: fixed; +// z-index: 5; +// width: 100%; +// left: 0; +// top: 0; +// .vert-gradient(rgb(37,37,37), rgb(24,24,24)); +// border-bottom: 1px solid rgb(27,27,27); +// } #pv-img-bottombar { position: fixed; diff --git a/src/_h5ai/css/inc/preview-txt.less b/src/_h5ai/client/css/inc/preview-txt.less similarity index 86% rename from src/_h5ai/css/inc/preview-txt.less rename to src/_h5ai/client/css/inc/preview-txt.less index ddcbcbf3..413327a3 100644 --- a/src/_h5ai/css/inc/preview-txt.less +++ b/src/_h5ai/client/css/inc/preview-txt.less @@ -26,12 +26,17 @@ } #pv-txt-text { + word-break: break-all; + .syntaxhighlighter { overflow: visible !important; .gutter .line { border-right: none !important; } + // .code .line, table td.code .container textarea { + // white-space: normal !important; + // } } &.markdown { @@ -133,15 +138,15 @@ } } -#pv-txt-topbar { - position: fixed; - z-index: 5; - width: 100%; - left: 0; - top: 0; - .vert-gradient(rgb(37,37,37), rgb(24,24,24)); - border-bottom: 1px solid rgb(27,27,27); -} +// #pv-txt-topbar { +// position: fixed; +// z-index: 5; +// width: 100%; +// left: 0; +// top: 0; +// .vert-gradient(rgb(37,37,37), rgb(24,24,24)); +// border-bottom: 1px solid rgb(27,27,27); +// } #pv-txt-bottombar { position: fixed; diff --git a/src/_h5ai/css/inc/context.less b/src/_h5ai/client/css/inc/qrcode.less similarity index 71% rename from src/_h5ai/css/inc/context.less rename to src/_h5ai/client/css/inc/qrcode.less index 62db2474..8fa52c13 100644 --- a/src/_h5ai/css/inc/context.less +++ b/src/_h5ai/client/css/inc/qrcode.less @@ -1,22 +1,16 @@ -#context { - position: fixed; - z-index: 1; +#qrcode { display: none; + position: fixed; right: 16px; bottom: 50px; + z-index: 1; background-color: #fff; border: 2px solid #ddd; padding: 8px; - span { + canvas { display: block; } - - .qrcode { - canvas { - display: block; - } - } } diff --git a/src/_h5ai/css/inc/responsive.less b/src/_h5ai/client/css/inc/responsive.less similarity index 99% rename from src/_h5ai/css/inc/responsive.less rename to src/_h5ai/client/css/inc/responsive.less index 90fcb19f..54c45c15 100644 --- a/src/_h5ai/css/inc/responsive.less +++ b/src/_h5ai/client/css/inc/responsive.less @@ -20,7 +20,7 @@ .current { display: block; } -} +} #extended.view-details { .header .label, .entry .label { margin-right: 110px; diff --git a/src/_h5ai/css/inc/topbar.less b/src/_h5ai/client/css/inc/topbar.less similarity index 98% rename from src/_h5ai/css/inc/topbar.less rename to src/_h5ai/client/css/inc/topbar.less index 9b5577a7..048f0959 100644 --- a/src/_h5ai/css/inc/topbar.less +++ b/src/_h5ai/client/css/inc/topbar.less @@ -3,6 +3,7 @@ position: fixed; z-index: 5; width: 100%; + min-height: 30px; left: 0; top: 0; .vert-gradient(rgb(241,241,241), rgb(228,228,228)); diff --git a/src/_h5ai/client/css/inc/tree.less b/src/_h5ai/client/css/inc/tree.less new file mode 100644 index 00000000..75d0a7d8 --- /dev/null +++ b/src/_h5ai/client/css/inc/tree.less @@ -0,0 +1,119 @@ + +#tree { + display: none; + position: fixed; + left: 0; + top: 31px; + height: 100%; + z-index: 3; + overflow: auto; + padding: 8px; + background-color: rgb(241,241,241); + border-right: 2px solid rgb(221,221,221); + + .sp-scrollbar { + margin: 8px 8px 8px 0; + width: 6px; + background-color: rgb(210,210,210); + .border-radius(3px); + cursor: pointer; + + .sp-thumb { + background-color: rgb(180,180,180); + .border-radius(3px); + } + &.active .sp-thumb { + background-color: rgb(150,150,150); + } + } + + .indicator { + position: relative; + top: 2px; + display: inline-block; + width: 16px; + height: 22px; + float: left; + opacity: 0.7; + cursor: pointer; + + img { + width: 12px; + height: 12px; + .transition(all 0.2s ease-in-out); + } + &.open { + img { + .transform(rotate(90deg)); + } + } + &.unknown { + opacity: 0.3; + } + &.none { + opacity: 0; + cursor: inherit; + } + } + a, a:active, a.visited { + display: block; + height: 1.231em; + line-height: 1.231em; + margin-left: 14px; + padding: 4px 6px; + color: #555; + border: 1px solid rgba(0,0,0,0); + .border-radius(5px); + text-decoration: none; + opacity: 0.7; + + &:hover, &.hover { + color: #e80; + background-color: rgba(255,255,255,0.5); + opacity: 1; + } + } + .icon { + position: relative; + top: -2px; + margin-right: 6px; + + img { + width: 16px; + height: 16px; + } + } + .hint { + margin-left: 6px; + font-size: 0.9em; + color: #ccc; + } + .content { + list-style: none; + margin: 0; + padding: 0 0 0 24px; + } + .summary { + margin: 0 0 0 24px; + color: #999; + font-style: italic; + } + .current { + > a, > a:active, > a:visited { + background-color: rgba(255,255,255,0.5); + border-color: rgb(221,221,221); + opacity: 1; + } + } + .error { + > a, > a:active, > a:visited { + color: #999; + &:hover, &.hover { + color: #e80; + } + } + .hint { + color: #c55; + } + } +} diff --git a/src/_h5ai/client/css/lib/h5bp-main-footer.less b/src/_h5ai/client/css/lib/h5bp-main-footer.less new file mode 100644 index 00000000..9dc81d19 --- /dev/null +++ b/src/_h5ai/client/css/lib/h5bp-main-footer.less @@ -0,0 +1,188 @@ + +/* ========================================================================== + Helper classes + ========================================================================== */ + +/* + * Image replacement + */ + +.ir { + background-color: transparent; + border: 0; + overflow: hidden; + /* IE 6/7 fallback */ + *text-indent: -9999px; +} + +.ir:before { + content: ""; + display: block; + width: 0; + height: 100%; +} + +/* + * Hide from both screenreaders and browsers: h5bp.com/u + */ + +.hidden { + display: none !important; + visibility: hidden; +} + +/* + * Hide only visually, but have it available for screenreaders: h5bp.com/v + */ + +.visuallyhidden { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +/* + * Extends the .visuallyhidden class to allow the element to be focusable + * when navigated to via the keyboard: h5bp.com/p + */ + +.visuallyhidden.focusable:active, +.visuallyhidden.focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; +} + +/* + * Hide visually and from screenreaders, but maintain layout + */ + +.invisible { + visibility: hidden; +} + +/* + * Clearfix: contain floats + * + * For modern browsers + * 1. The space content is one way to avoid an Opera bug when the + * `contenteditable` attribute is included anywhere else in the document. + * Otherwise it causes space to appear at the top and bottom of elements + * that receive the `clearfix` class. + * 2. The use of `table` rather than `block` is only necessary if using + * `:before` to contain the top-margins of child elements. + */ + +.clearfix:before, +.clearfix:after { + content: " "; /* 1 */ + display: table; /* 2 */ +} + +.clearfix:after { + clear: both; +} + +/* + * For IE 6/7 only + * Include this rule to trigger hasLayout and contain floats. + */ + +.clearfix { + *zoom: 1; +} + +/* ========================================================================== + EXAMPLE Media Queries for Responsive Design. + Theses examples override the primary ('mobile first') styles. + Modify as content requires. + ========================================================================== */ + +@media only screen and (min-width: 35em) { + /* Style adjustments for viewports that meet the condition */ +} + +@media only screen and (-webkit-min-device-pixel-ratio: 1.5), + only screen and (min-resolution: 144dpi) { + /* Style adjustments for high resolution devices */ +} + +/* ========================================================================== + Print styles. + Inlined to avoid required HTTP connection: h5bp.com/r + ========================================================================== */ + +@media print { + * { + background: transparent !important; + color: #000 !important; /* Black prints faster: h5bp.com/s */ + box-shadow:none !important; + text-shadow: none !important; + } + + a, + a:visited { + text-decoration: underline; + } + + a[href]:after { + content: " (" attr(href) ")"; + } + + abbr[title]:after { + content: " (" attr(title) ")"; + } + + /* + * Don't show links for images, or javascript/internal links + */ + + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + + thead { + display: table-header-group; /* h5bp.com/t */ + } + + tr, + img { + page-break-inside: avoid; + } + + img { + max-width: 100% !important; + } + + @page { + margin: 0.5cm; + } + + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + + h2, + h3 { + page-break-after: avoid; + } +} diff --git a/src/_h5ai/client/css/lib/h5bp-main-header.less b/src/_h5ai/client/css/lib/h5bp-main-header.less new file mode 100644 index 00000000..724098df --- /dev/null +++ b/src/_h5ai/client/css/lib/h5bp-main-header.less @@ -0,0 +1,94 @@ +/* + * HTML5 Boilerplate + * + * What follows is the result of much research on cross-browser styling. + * Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal, + * Kroc Camen, and the H5BP dev community and team. + */ + +/* ========================================================================== + Base styles: opinionated defaults + ========================================================================== */ + +html, +button, +input, +select, +textarea { + color: #222; +} + +body { + font-size: 1em; + line-height: 1.4; +} + +/* + * Remove text-shadow in selection highlight: h5bp.com/i + * These selection declarations have to be separate. + * Customize the background color to match your design. + */ + +::-moz-selection { + background: #b3d4fc; + text-shadow: none; +} + +::selection { + background: #b3d4fc; + text-shadow: none; +} + +/* + * A better looking default horizontal rule + */ + +hr { + display: block; + height: 1px; + border: 0; + border-top: 1px solid #ccc; + margin: 1em 0; + padding: 0; +} + +/* + * Remove the gap between images and the bottom of their containers: h5bp.com/i/440 + */ + +img { + vertical-align: middle; +} + +/* + * Remove default fieldset styles. + */ + +fieldset { + border: 0; + margin: 0; + padding: 0; +} + +/* + * Allow only vertical resizing of textareas. + */ + +textarea { + resize: vertical; +} + +/* ========================================================================== + Chrome Frame prompt + ========================================================================== */ + +.chromeframe { + margin: 0.2em 0; + background: #ccc; + color: #000; + padding: 0.2em 0; +} + +/* ========================================================================== + Author's custom styles + ========================================================================== */ diff --git a/src/_h5ai/client/css/lib/h5bp-normalize.less b/src/_h5ai/client/css/lib/h5bp-normalize.less new file mode 100644 index 00000000..d4210aac --- /dev/null +++ b/src/_h5ai/client/css/lib/h5bp-normalize.less @@ -0,0 +1,504 @@ +/*! normalize.css v1.0.1 | MIT License | git.io/normalize */ + +/* ========================================================================== + HTML5 display definitions + ========================================================================== */ + +/* + * Corrects `block` display not defined in IE 6/7/8/9 and Firefox 3. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section, +summary { + display: block; +} + +/* + * Corrects `inline-block` display not defined in IE 6/7/8/9 and Firefox 3. + */ + +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +/* + * Prevents modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/* + * Addresses styling for `hidden` attribute not present in IE 7/8/9, Firefox 3, + * and Safari 4. + * Known issue: no IE 6 support. + */ + +[hidden] { + display: none; +} + +/* ========================================================================== + Base + ========================================================================== */ + +/* + * 1. Corrects text resizing oddly in IE 6/7 when body `font-size` is set using + * `em` units. + * 2. Prevents iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-size: 100%; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ + -ms-text-size-adjust: 100%; /* 2 */ +} + +/* + * Addresses `font-family` inconsistency between `textarea` and other form + * elements. + */ + +html, +button, +input, +select, +textarea { + font-family: sans-serif; +} + +/* + * Addresses margins handled incorrectly in IE 6/7. + */ + +body { + margin: 0; +} + +/* ========================================================================== + Links + ========================================================================== */ + +/* + * Addresses `outline` inconsistency between Chrome and other browsers. + */ + +a:focus { + outline: thin dotted; +} + +/* + * Improves readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* ========================================================================== + Typography + ========================================================================== */ + +/* + * Addresses font sizes and margins set differently in IE 6/7. + * Addresses font sizes within `section` and `article` in Firefox 4+, Safari 5, + * and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +h2 { + font-size: 1.5em; + margin: 0.83em 0; +} + +h3 { + font-size: 1.17em; + margin: 1em 0; +} + +h4 { + font-size: 1em; + margin: 1.33em 0; +} + +h5 { + font-size: 0.83em; + margin: 1.67em 0; +} + +h6 { + font-size: 0.75em; + margin: 2.33em 0; +} + +/* + * Addresses styling not present in IE 7/8/9, Safari 5, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/* + * Addresses style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +blockquote { + margin: 1em 40px; +} + +/* + * Addresses styling not present in Safari 5 and Chrome. + */ + +dfn { + font-style: italic; +} + +/* + * Addresses styling not present in IE 6/7/8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/* + * Addresses margins set differently in IE 6/7. + */ + +p, +pre { + margin: 1em 0; +} + +/* + * Corrects font family set oddly in IE 6, Safari 4/5, and Chrome. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + _font-family: 'courier new', monospace; + font-size: 1em; +} + +/* + * Improves readability of pre-formatted text in all browsers. + */ + +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} + +/* + * Addresses CSS quotes not supported in IE 6/7. + */ + +q { + quotes: none; +} + +/* + * Addresses `quotes` property not supported in Safari 4. + */ + +q:before, +q:after { + content: ''; + content: none; +} + +/* + * Addresses inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/* + * Prevents `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* ========================================================================== + Lists + ========================================================================== */ + +/* + * Addresses margins set differently in IE 6/7. + */ + +dl, +menu, +ol, +ul { + margin: 1em 0; +} + +dd { + margin: 0 0 0 40px; +} + +/* + * Addresses paddings set differently in IE 6/7. + */ + +menu, +ol, +ul { + padding: 0 0 0 40px; +} + +/* + * Corrects list images handled incorrectly in IE 7. + */ + +nav ul, +nav ol { + list-style: none; + list-style-image: none; +} + +/* ========================================================================== + Embedded content + ========================================================================== */ + +/* + * 1. Removes border when inside `a` element in IE 6/7/8/9 and Firefox 3. + * 2. Improves image quality when scaled in IE 7. + */ + +img { + border: 0; /* 1 */ + -ms-interpolation-mode: bicubic; /* 2 */ +} + +/* + * Corrects overflow displayed oddly in IE 9. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* ========================================================================== + Figures + ========================================================================== */ + +/* + * Addresses margin not present in IE 6/7/8/9, Safari 5, and Opera 11. + */ + +figure { + margin: 0; +} + +/* ========================================================================== + Forms + ========================================================================== */ + +/* + * Corrects margin displayed oddly in IE 6/7. + */ + +form { + margin: 0; +} + +/* + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/* + * 1. Corrects color not being inherited in IE 6/7/8/9. + * 2. Corrects text not wrapping in Firefox 3. + * 3. Corrects alignment displayed oddly in IE 6/7. + */ + +legend { + border: 0; /* 1 */ + padding: 0; + white-space: normal; /* 2 */ + *margin-left: -7px; /* 3 */ +} + +/* + * 1. Corrects font size not being inherited in all browsers. + * 2. Addresses margins set differently in IE 6/7, Firefox 3+, Safari 5, + * and Chrome. + * 3. Improves appearance and consistency in all browsers. + */ + +button, +input, +select, +textarea { + font-size: 100%; /* 1 */ + margin: 0; /* 2 */ + vertical-align: baseline; /* 3 */ + *vertical-align: middle; /* 3 */ +} + +/* + * Addresses Firefox 3+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +button, +input { + line-height: normal; +} + +/* + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Corrects inability to style clickable `input` types in iOS. + * 3. Improves usability and consistency of cursor style between image-type + * `input` and others. + * 4. Removes inner spacing in IE 7 without affecting normal text inputs. + * Known issue: inner spacing remains in IE 6. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ + *overflow: visible; /* 4 */ +} + +/* + * Re-set default cursor for disabled elements. + */ + +button[disabled], +input[disabled] { + cursor: default; +} + +/* + * 1. Addresses box sizing set to content-box in IE 8/9. + * 2. Removes excess padding in IE 8/9. + * 3. Removes excess padding in IE 7. + * Known issue: excess padding remains in IE 6. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ + *height: 13px; /* 3 */ + *width: 13px; /* 3 */ +} + +/* + * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome. + * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/* + * Removes inner padding and search cancel button in Safari 5 and Chrome + * on OS X. + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* + * Removes inner padding and border in Firefox 3+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/* + * 1. Removes default vertical scrollbar in IE 6/7/8/9. + * 2. Improves readability and alignment in all browsers. + */ + +textarea { + overflow: auto; /* 1 */ + vertical-align: top; /* 2 */ +} + +/* ========================================================================== + Tables + ========================================================================== */ + +/* + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/src/_h5ai/css/lib/mixins.less b/src/_h5ai/client/css/lib/mixins.less similarity index 100% rename from src/_h5ai/css/lib/mixins.less rename to src/_h5ai/client/css/lib/mixins.less diff --git a/src/_h5ai/css/lib/sh/shCore.less b/src/_h5ai/client/css/lib/sh/shCore.less similarity index 100% rename from src/_h5ai/css/lib/sh/shCore.less rename to src/_h5ai/client/css/lib/sh/shCore.less diff --git a/src/_h5ai/css/lib/sh/shThemeDefault.less b/src/_h5ai/client/css/lib/sh/shThemeDefault.less similarity index 100% rename from src/_h5ai/css/lib/sh/shThemeDefault.less rename to src/_h5ai/client/css/lib/sh/shThemeDefault.less diff --git a/src/_h5ai/client/css/styles.less b/src/_h5ai/client/css/styles.less new file mode 100644 index 00000000..631aba7d --- /dev/null +++ b/src/_h5ai/client/css/styles.less @@ -0,0 +1,35 @@ + +@import "lib/h5bp-normalize"; +@import "lib/h5bp-main-header"; + +@import "lib/mixins"; +@import "lib/sh/shCore"; +@import "lib/sh/shThemeDefault"; + +@import "inc/general"; +@import "inc/topbar"; +@import "inc/bottombar"; +@import "inc/download"; +@import "inc/delete"; +@import "inc/filter"; +@import "inc/l10n"; +@import "inc/tree"; +@import "inc/qrcode"; +@import "inc/preview-img"; +@import "inc/preview-txt"; + +@import "inc/content"; +@import "inc/extended"; +@import "inc/extended-details"; +@import "inc/extended-icons"; +@import "inc/extended-list"; +@import "inc/extended-grid"; +// @import "inc/context-menu"; +@import "inc/dropbox"; +@import "inc/fallback-table"; + +@import "inc/responsive"; + +@import "inc/h5ai-info"; + +@import "lib/h5bp-main-footer"; diff --git a/src/_h5ai/icons/16x16/archive.png b/src/_h5ai/client/icons/16x16/archive.png similarity index 100% rename from src/_h5ai/icons/16x16/archive.png rename to src/_h5ai/client/icons/16x16/archive.png diff --git a/src/_h5ai/icons/16x16/audio.png b/src/_h5ai/client/icons/16x16/audio.png similarity index 100% rename from src/_h5ai/icons/16x16/audio.png rename to src/_h5ai/client/icons/16x16/audio.png diff --git a/src/_h5ai/icons/16x16/authors.png b/src/_h5ai/client/icons/16x16/authors.png similarity index 100% rename from src/_h5ai/icons/16x16/authors.png rename to src/_h5ai/client/icons/16x16/authors.png diff --git a/src/_h5ai/icons/16x16/bin.png b/src/_h5ai/client/icons/16x16/bin.png similarity index 100% rename from src/_h5ai/icons/16x16/bin.png rename to src/_h5ai/client/icons/16x16/bin.png diff --git a/src/_h5ai/icons/16x16/blank.png b/src/_h5ai/client/icons/16x16/blank.png similarity index 100% rename from src/_h5ai/icons/16x16/blank.png rename to src/_h5ai/client/icons/16x16/blank.png diff --git a/src/_h5ai/icons/16x16/bmp.png b/src/_h5ai/client/icons/16x16/bmp.png similarity index 100% rename from src/_h5ai/icons/16x16/bmp.png rename to src/_h5ai/client/icons/16x16/bmp.png diff --git a/src/_h5ai/icons/16x16/c.png b/src/_h5ai/client/icons/16x16/c.png similarity index 100% rename from src/_h5ai/icons/16x16/c.png rename to src/_h5ai/client/icons/16x16/c.png diff --git a/src/_h5ai/icons/16x16/calc.png b/src/_h5ai/client/icons/16x16/calc.png similarity index 100% rename from src/_h5ai/icons/16x16/calc.png rename to src/_h5ai/client/icons/16x16/calc.png diff --git a/src/_h5ai/icons/16x16/cd.png b/src/_h5ai/client/icons/16x16/cd.png similarity index 100% rename from src/_h5ai/icons/16x16/cd.png rename to src/_h5ai/client/icons/16x16/cd.png diff --git a/src/_h5ai/icons/16x16/copying.png b/src/_h5ai/client/icons/16x16/copying.png similarity index 100% rename from src/_h5ai/icons/16x16/copying.png rename to src/_h5ai/client/icons/16x16/copying.png diff --git a/src/_h5ai/icons/16x16/cpp.png b/src/_h5ai/client/icons/16x16/cpp.png similarity index 100% rename from src/_h5ai/icons/16x16/cpp.png rename to src/_h5ai/client/icons/16x16/cpp.png diff --git a/src/_h5ai/icons/16x16/css.png b/src/_h5ai/client/icons/16x16/css.png similarity index 100% rename from src/_h5ai/icons/16x16/css.png rename to src/_h5ai/client/icons/16x16/css.png diff --git a/src/_h5ai/icons/16x16/deb.png b/src/_h5ai/client/icons/16x16/deb.png similarity index 100% rename from src/_h5ai/icons/16x16/deb.png rename to src/_h5ai/client/icons/16x16/deb.png diff --git a/src/_h5ai/icons/16x16/default.png b/src/_h5ai/client/icons/16x16/default.png similarity index 100% rename from src/_h5ai/icons/16x16/default.png rename to src/_h5ai/client/icons/16x16/default.png diff --git a/src/_h5ai/icons/16x16/source.png b/src/_h5ai/client/icons/16x16/diff.png similarity index 100% rename from src/_h5ai/icons/16x16/source.png rename to src/_h5ai/client/icons/16x16/diff.png diff --git a/src/_h5ai/icons/16x16/doc.png b/src/_h5ai/client/icons/16x16/doc.png similarity index 100% rename from src/_h5ai/icons/16x16/doc.png rename to src/_h5ai/client/icons/16x16/doc.png diff --git a/src/_h5ai/icons/16x16/draw.png b/src/_h5ai/client/icons/16x16/draw.png similarity index 100% rename from src/_h5ai/icons/16x16/draw.png rename to src/_h5ai/client/icons/16x16/draw.png diff --git a/src/_h5ai/icons/16x16/eps.png b/src/_h5ai/client/icons/16x16/eps.png similarity index 100% rename from src/_h5ai/icons/16x16/eps.png rename to src/_h5ai/client/icons/16x16/eps.png diff --git a/src/_h5ai/icons/16x16/exe.png b/src/_h5ai/client/icons/16x16/exe.png similarity index 100% rename from src/_h5ai/icons/16x16/exe.png rename to src/_h5ai/client/icons/16x16/exe.png diff --git a/src/_h5ai/icons/16x16/folder-home.png b/src/_h5ai/client/icons/16x16/folder-home.png similarity index 100% rename from src/_h5ai/icons/16x16/folder-home.png rename to src/_h5ai/client/icons/16x16/folder-home.png diff --git a/src/_h5ai/icons/16x16/folder-open.png b/src/_h5ai/client/icons/16x16/folder-open.png similarity index 100% rename from src/_h5ai/icons/16x16/folder-open.png rename to src/_h5ai/client/icons/16x16/folder-open.png diff --git a/src/_h5ai/icons/16x16/folder-page.png b/src/_h5ai/client/icons/16x16/folder-page.png similarity index 100% rename from src/_h5ai/icons/16x16/folder-page.png rename to src/_h5ai/client/icons/16x16/folder-page.png diff --git a/src/_h5ai/icons/16x16/folder-parent.png b/src/_h5ai/client/icons/16x16/folder-parent-old.png similarity index 100% rename from src/_h5ai/icons/16x16/folder-parent.png rename to src/_h5ai/client/icons/16x16/folder-parent-old.png diff --git a/src/_h5ai/client/icons/16x16/folder-parent.png b/src/_h5ai/client/icons/16x16/folder-parent.png new file mode 100644 index 00000000..3c964f19 Binary files /dev/null and b/src/_h5ai/client/icons/16x16/folder-parent.png differ diff --git a/src/_h5ai/icons/16x16/folder.png b/src/_h5ai/client/icons/16x16/folder.png similarity index 100% rename from src/_h5ai/icons/16x16/folder.png rename to src/_h5ai/client/icons/16x16/folder.png diff --git a/src/_h5ai/icons/16x16/gif.png b/src/_h5ai/client/icons/16x16/gif.png similarity index 100% rename from src/_h5ai/icons/16x16/gif.png rename to src/_h5ai/client/icons/16x16/gif.png diff --git a/src/_h5ai/icons/16x16/gzip.png b/src/_h5ai/client/icons/16x16/gzip.png similarity index 100% rename from src/_h5ai/icons/16x16/gzip.png rename to src/_h5ai/client/icons/16x16/gzip.png diff --git a/src/_h5ai/icons/16x16/h.png b/src/_h5ai/client/icons/16x16/h.png similarity index 100% rename from src/_h5ai/icons/16x16/h.png rename to src/_h5ai/client/icons/16x16/h.png diff --git a/src/_h5ai/icons/16x16/hpp.png b/src/_h5ai/client/icons/16x16/hpp.png similarity index 100% rename from src/_h5ai/icons/16x16/hpp.png rename to src/_h5ai/client/icons/16x16/hpp.png diff --git a/src/_h5ai/icons/16x16/html.png b/src/_h5ai/client/icons/16x16/html.png similarity index 100% rename from src/_h5ai/icons/16x16/html.png rename to src/_h5ai/client/icons/16x16/html.png diff --git a/src/_h5ai/icons/16x16/ico.png b/src/_h5ai/client/icons/16x16/ico.png similarity index 100% rename from src/_h5ai/icons/16x16/ico.png rename to src/_h5ai/client/icons/16x16/ico.png diff --git a/src/_h5ai/icons/16x16/image.png b/src/_h5ai/client/icons/16x16/image.png similarity index 100% rename from src/_h5ai/icons/16x16/image.png rename to src/_h5ai/client/icons/16x16/image.png diff --git a/src/_h5ai/icons/16x16/install.png b/src/_h5ai/client/icons/16x16/install.png similarity index 100% rename from src/_h5ai/icons/16x16/install.png rename to src/_h5ai/client/icons/16x16/install.png diff --git a/src/_h5ai/icons/16x16/java.png b/src/_h5ai/client/icons/16x16/java.png similarity index 100% rename from src/_h5ai/icons/16x16/java.png rename to src/_h5ai/client/icons/16x16/java.png diff --git a/src/_h5ai/icons/16x16/jpg.png b/src/_h5ai/client/icons/16x16/jpg.png similarity index 100% rename from src/_h5ai/icons/16x16/jpg.png rename to src/_h5ai/client/icons/16x16/jpg.png diff --git a/src/_h5ai/icons/16x16/js.png b/src/_h5ai/client/icons/16x16/js.png similarity index 100% rename from src/_h5ai/icons/16x16/js.png rename to src/_h5ai/client/icons/16x16/js.png diff --git a/src/_h5ai/client/icons/16x16/json.png b/src/_h5ai/client/icons/16x16/json.png new file mode 100644 index 00000000..af1a475e Binary files /dev/null and b/src/_h5ai/client/icons/16x16/json.png differ diff --git a/src/_h5ai/icons/16x16/log.png b/src/_h5ai/client/icons/16x16/log.png similarity index 100% rename from src/_h5ai/icons/16x16/log.png rename to src/_h5ai/client/icons/16x16/log.png diff --git a/src/_h5ai/icons/16x16/makefile.png b/src/_h5ai/client/icons/16x16/makefile.png similarity index 100% rename from src/_h5ai/icons/16x16/makefile.png rename to src/_h5ai/client/icons/16x16/makefile.png diff --git a/src/_h5ai/icons/16x16/markdown.png b/src/_h5ai/client/icons/16x16/markdown.png similarity index 100% rename from src/_h5ai/icons/16x16/markdown.png rename to src/_h5ai/client/icons/16x16/markdown.png diff --git a/src/_h5ai/icons/16x16/package.png b/src/_h5ai/client/icons/16x16/package.png similarity index 100% rename from src/_h5ai/icons/16x16/package.png rename to src/_h5ai/client/icons/16x16/package.png diff --git a/src/_h5ai/icons/16x16/pdf.png b/src/_h5ai/client/icons/16x16/pdf.png similarity index 100% rename from src/_h5ai/icons/16x16/pdf.png rename to src/_h5ai/client/icons/16x16/pdf.png diff --git a/src/_h5ai/icons/16x16/php.png b/src/_h5ai/client/icons/16x16/php.png similarity index 100% rename from src/_h5ai/icons/16x16/php.png rename to src/_h5ai/client/icons/16x16/php.png diff --git a/src/_h5ai/icons/16x16/playlist.png b/src/_h5ai/client/icons/16x16/playlist.png similarity index 100% rename from src/_h5ai/icons/16x16/playlist.png rename to src/_h5ai/client/icons/16x16/playlist.png diff --git a/src/_h5ai/icons/16x16/png.png b/src/_h5ai/client/icons/16x16/png.png similarity index 100% rename from src/_h5ai/icons/16x16/png.png rename to src/_h5ai/client/icons/16x16/png.png diff --git a/src/_h5ai/icons/16x16/pres.png b/src/_h5ai/client/icons/16x16/pres.png similarity index 100% rename from src/_h5ai/icons/16x16/pres.png rename to src/_h5ai/client/icons/16x16/pres.png diff --git a/src/_h5ai/icons/16x16/ps.png b/src/_h5ai/client/icons/16x16/ps.png similarity index 100% rename from src/_h5ai/icons/16x16/ps.png rename to src/_h5ai/client/icons/16x16/ps.png diff --git a/src/_h5ai/icons/16x16/psd.png b/src/_h5ai/client/icons/16x16/psd.png similarity index 100% rename from src/_h5ai/icons/16x16/psd.png rename to src/_h5ai/client/icons/16x16/psd.png diff --git a/src/_h5ai/icons/16x16/py.png b/src/_h5ai/client/icons/16x16/py.png similarity index 100% rename from src/_h5ai/icons/16x16/py.png rename to src/_h5ai/client/icons/16x16/py.png diff --git a/src/_h5ai/icons/16x16/rar.png b/src/_h5ai/client/icons/16x16/rar.png similarity index 100% rename from src/_h5ai/icons/16x16/rar.png rename to src/_h5ai/client/icons/16x16/rar.png diff --git a/src/_h5ai/icons/16x16/rb.png b/src/_h5ai/client/icons/16x16/rb.png similarity index 100% rename from src/_h5ai/icons/16x16/rb.png rename to src/_h5ai/client/icons/16x16/rb.png diff --git a/src/_h5ai/icons/16x16/readme.png b/src/_h5ai/client/icons/16x16/readme.png similarity index 100% rename from src/_h5ai/icons/16x16/readme.png rename to src/_h5ai/client/icons/16x16/readme.png diff --git a/src/_h5ai/icons/16x16/rpm.png b/src/_h5ai/client/icons/16x16/rpm.png similarity index 100% rename from src/_h5ai/icons/16x16/rpm.png rename to src/_h5ai/client/icons/16x16/rpm.png diff --git a/src/_h5ai/icons/16x16/rss.png b/src/_h5ai/client/icons/16x16/rss.png similarity index 100% rename from src/_h5ai/icons/16x16/rss.png rename to src/_h5ai/client/icons/16x16/rss.png diff --git a/src/_h5ai/icons/16x16/rtf.png b/src/_h5ai/client/icons/16x16/rtf.png similarity index 100% rename from src/_h5ai/icons/16x16/rtf.png rename to src/_h5ai/client/icons/16x16/rtf.png diff --git a/src/_h5ai/icons/16x16/script.png b/src/_h5ai/client/icons/16x16/script.png similarity index 100% rename from src/_h5ai/icons/16x16/script.png rename to src/_h5ai/client/icons/16x16/script.png diff --git a/src/_h5ai/client/icons/16x16/source.png b/src/_h5ai/client/icons/16x16/source.png new file mode 100644 index 00000000..5bef9207 Binary files /dev/null and b/src/_h5ai/client/icons/16x16/source.png differ diff --git a/src/_h5ai/icons/16x16/sql.png b/src/_h5ai/client/icons/16x16/sql.png similarity index 100% rename from src/_h5ai/icons/16x16/sql.png rename to src/_h5ai/client/icons/16x16/sql.png diff --git a/src/_h5ai/icons/16x16/tar.png b/src/_h5ai/client/icons/16x16/tar.png similarity index 100% rename from src/_h5ai/icons/16x16/tar.png rename to src/_h5ai/client/icons/16x16/tar.png diff --git a/src/_h5ai/icons/16x16/tex.png b/src/_h5ai/client/icons/16x16/tex.png similarity index 100% rename from src/_h5ai/icons/16x16/tex.png rename to src/_h5ai/client/icons/16x16/tex.png diff --git a/src/_h5ai/icons/16x16/text.png b/src/_h5ai/client/icons/16x16/text.png similarity index 100% rename from src/_h5ai/icons/16x16/text.png rename to src/_h5ai/client/icons/16x16/text.png diff --git a/src/_h5ai/icons/16x16/tiff.png b/src/_h5ai/client/icons/16x16/tiff.png similarity index 100% rename from src/_h5ai/icons/16x16/tiff.png rename to src/_h5ai/client/icons/16x16/tiff.png diff --git a/src/_h5ai/icons/16x16/unknown.png b/src/_h5ai/client/icons/16x16/unknown.png similarity index 100% rename from src/_h5ai/icons/16x16/unknown.png rename to src/_h5ai/client/icons/16x16/unknown.png diff --git a/src/_h5ai/icons/16x16/vcal.png b/src/_h5ai/client/icons/16x16/vcal.png similarity index 100% rename from src/_h5ai/icons/16x16/vcal.png rename to src/_h5ai/client/icons/16x16/vcal.png diff --git a/src/_h5ai/icons/16x16/video.png b/src/_h5ai/client/icons/16x16/video.png similarity index 100% rename from src/_h5ai/icons/16x16/video.png rename to src/_h5ai/client/icons/16x16/video.png diff --git a/src/_h5ai/icons/16x16/xml.png b/src/_h5ai/client/icons/16x16/xml.png similarity index 100% rename from src/_h5ai/icons/16x16/xml.png rename to src/_h5ai/client/icons/16x16/xml.png diff --git a/src/_h5ai/icons/16x16/zip.png b/src/_h5ai/client/icons/16x16/zip.png similarity index 100% rename from src/_h5ai/icons/16x16/zip.png rename to src/_h5ai/client/icons/16x16/zip.png diff --git a/src/_h5ai/icons/48x48/archive.png b/src/_h5ai/client/icons/48x48/archive.png similarity index 100% rename from src/_h5ai/icons/48x48/archive.png rename to src/_h5ai/client/icons/48x48/archive.png diff --git a/src/_h5ai/icons/48x48/audio.png b/src/_h5ai/client/icons/48x48/audio.png similarity index 100% rename from src/_h5ai/icons/48x48/audio.png rename to src/_h5ai/client/icons/48x48/audio.png diff --git a/src/_h5ai/icons/48x48/authors.png b/src/_h5ai/client/icons/48x48/authors.png similarity index 100% rename from src/_h5ai/icons/48x48/authors.png rename to src/_h5ai/client/icons/48x48/authors.png diff --git a/src/_h5ai/icons/48x48/bin.png b/src/_h5ai/client/icons/48x48/bin.png similarity index 100% rename from src/_h5ai/icons/48x48/bin.png rename to src/_h5ai/client/icons/48x48/bin.png diff --git a/src/_h5ai/icons/48x48/blank.png b/src/_h5ai/client/icons/48x48/blank.png similarity index 100% rename from src/_h5ai/icons/48x48/blank.png rename to src/_h5ai/client/icons/48x48/blank.png diff --git a/src/_h5ai/icons/48x48/bmp.png b/src/_h5ai/client/icons/48x48/bmp.png similarity index 100% rename from src/_h5ai/icons/48x48/bmp.png rename to src/_h5ai/client/icons/48x48/bmp.png diff --git a/src/_h5ai/icons/48x48/c.png b/src/_h5ai/client/icons/48x48/c.png similarity index 100% rename from src/_h5ai/icons/48x48/c.png rename to src/_h5ai/client/icons/48x48/c.png diff --git a/src/_h5ai/icons/48x48/calc.png b/src/_h5ai/client/icons/48x48/calc.png similarity index 100% rename from src/_h5ai/icons/48x48/calc.png rename to src/_h5ai/client/icons/48x48/calc.png diff --git a/src/_h5ai/icons/48x48/cd.png b/src/_h5ai/client/icons/48x48/cd.png similarity index 100% rename from src/_h5ai/icons/48x48/cd.png rename to src/_h5ai/client/icons/48x48/cd.png diff --git a/src/_h5ai/icons/48x48/copying.png b/src/_h5ai/client/icons/48x48/copying.png similarity index 100% rename from src/_h5ai/icons/48x48/copying.png rename to src/_h5ai/client/icons/48x48/copying.png diff --git a/src/_h5ai/icons/48x48/cpp.png b/src/_h5ai/client/icons/48x48/cpp.png similarity index 100% rename from src/_h5ai/icons/48x48/cpp.png rename to src/_h5ai/client/icons/48x48/cpp.png diff --git a/src/_h5ai/icons/48x48/css.png b/src/_h5ai/client/icons/48x48/css.png similarity index 100% rename from src/_h5ai/icons/48x48/css.png rename to src/_h5ai/client/icons/48x48/css.png diff --git a/src/_h5ai/icons/48x48/deb.png b/src/_h5ai/client/icons/48x48/deb.png similarity index 100% rename from src/_h5ai/icons/48x48/deb.png rename to src/_h5ai/client/icons/48x48/deb.png diff --git a/src/_h5ai/icons/48x48/default.png b/src/_h5ai/client/icons/48x48/default.png similarity index 100% rename from src/_h5ai/icons/48x48/default.png rename to src/_h5ai/client/icons/48x48/default.png diff --git a/src/_h5ai/icons/48x48/source.png b/src/_h5ai/client/icons/48x48/diff.png similarity index 100% rename from src/_h5ai/icons/48x48/source.png rename to src/_h5ai/client/icons/48x48/diff.png diff --git a/src/_h5ai/icons/48x48/doc.png b/src/_h5ai/client/icons/48x48/doc.png similarity index 100% rename from src/_h5ai/icons/48x48/doc.png rename to src/_h5ai/client/icons/48x48/doc.png diff --git a/src/_h5ai/icons/48x48/draw.png b/src/_h5ai/client/icons/48x48/draw.png similarity index 100% rename from src/_h5ai/icons/48x48/draw.png rename to src/_h5ai/client/icons/48x48/draw.png diff --git a/src/_h5ai/icons/48x48/eps.png b/src/_h5ai/client/icons/48x48/eps.png similarity index 100% rename from src/_h5ai/icons/48x48/eps.png rename to src/_h5ai/client/icons/48x48/eps.png diff --git a/src/_h5ai/icons/48x48/exe.png b/src/_h5ai/client/icons/48x48/exe.png similarity index 100% rename from src/_h5ai/icons/48x48/exe.png rename to src/_h5ai/client/icons/48x48/exe.png diff --git a/src/_h5ai/icons/48x48/folder-home.png b/src/_h5ai/client/icons/48x48/folder-home.png similarity index 100% rename from src/_h5ai/icons/48x48/folder-home.png rename to src/_h5ai/client/icons/48x48/folder-home.png diff --git a/src/_h5ai/icons/48x48/folder-open.png b/src/_h5ai/client/icons/48x48/folder-open.png similarity index 100% rename from src/_h5ai/icons/48x48/folder-open.png rename to src/_h5ai/client/icons/48x48/folder-open.png diff --git a/src/_h5ai/icons/48x48/folder-page.png b/src/_h5ai/client/icons/48x48/folder-page.png similarity index 100% rename from src/_h5ai/icons/48x48/folder-page.png rename to src/_h5ai/client/icons/48x48/folder-page.png diff --git a/src/_h5ai/icons/48x48/folder-parent.png b/src/_h5ai/client/icons/48x48/folder-parent.png similarity index 100% rename from src/_h5ai/icons/48x48/folder-parent.png rename to src/_h5ai/client/icons/48x48/folder-parent.png diff --git a/src/_h5ai/icons/48x48/folder.png b/src/_h5ai/client/icons/48x48/folder.png similarity index 100% rename from src/_h5ai/icons/48x48/folder.png rename to src/_h5ai/client/icons/48x48/folder.png diff --git a/src/_h5ai/icons/48x48/gif.png b/src/_h5ai/client/icons/48x48/gif.png similarity index 100% rename from src/_h5ai/icons/48x48/gif.png rename to src/_h5ai/client/icons/48x48/gif.png diff --git a/src/_h5ai/icons/48x48/gzip.png b/src/_h5ai/client/icons/48x48/gzip.png similarity index 100% rename from src/_h5ai/icons/48x48/gzip.png rename to src/_h5ai/client/icons/48x48/gzip.png diff --git a/src/_h5ai/icons/48x48/h.png b/src/_h5ai/client/icons/48x48/h.png similarity index 100% rename from src/_h5ai/icons/48x48/h.png rename to src/_h5ai/client/icons/48x48/h.png diff --git a/src/_h5ai/icons/48x48/hpp.png b/src/_h5ai/client/icons/48x48/hpp.png similarity index 100% rename from src/_h5ai/icons/48x48/hpp.png rename to src/_h5ai/client/icons/48x48/hpp.png diff --git a/src/_h5ai/icons/48x48/html.png b/src/_h5ai/client/icons/48x48/html.png similarity index 100% rename from src/_h5ai/icons/48x48/html.png rename to src/_h5ai/client/icons/48x48/html.png diff --git a/src/_h5ai/icons/48x48/ico.png b/src/_h5ai/client/icons/48x48/ico.png similarity index 100% rename from src/_h5ai/icons/48x48/ico.png rename to src/_h5ai/client/icons/48x48/ico.png diff --git a/src/_h5ai/icons/48x48/image.png b/src/_h5ai/client/icons/48x48/image.png similarity index 100% rename from src/_h5ai/icons/48x48/image.png rename to src/_h5ai/client/icons/48x48/image.png diff --git a/src/_h5ai/icons/48x48/install.png b/src/_h5ai/client/icons/48x48/install.png similarity index 100% rename from src/_h5ai/icons/48x48/install.png rename to src/_h5ai/client/icons/48x48/install.png diff --git a/src/_h5ai/icons/48x48/java.png b/src/_h5ai/client/icons/48x48/java.png similarity index 100% rename from src/_h5ai/icons/48x48/java.png rename to src/_h5ai/client/icons/48x48/java.png diff --git a/src/_h5ai/icons/48x48/jpg.png b/src/_h5ai/client/icons/48x48/jpg.png similarity index 100% rename from src/_h5ai/icons/48x48/jpg.png rename to src/_h5ai/client/icons/48x48/jpg.png diff --git a/src/_h5ai/icons/48x48/js.png b/src/_h5ai/client/icons/48x48/js.png similarity index 100% rename from src/_h5ai/icons/48x48/js.png rename to src/_h5ai/client/icons/48x48/js.png diff --git a/src/_h5ai/client/icons/48x48/json.png b/src/_h5ai/client/icons/48x48/json.png new file mode 100644 index 00000000..dbe9da65 Binary files /dev/null and b/src/_h5ai/client/icons/48x48/json.png differ diff --git a/src/_h5ai/icons/48x48/log.png b/src/_h5ai/client/icons/48x48/log.png similarity index 100% rename from src/_h5ai/icons/48x48/log.png rename to src/_h5ai/client/icons/48x48/log.png diff --git a/src/_h5ai/icons/48x48/makefile.png b/src/_h5ai/client/icons/48x48/makefile.png similarity index 100% rename from src/_h5ai/icons/48x48/makefile.png rename to src/_h5ai/client/icons/48x48/makefile.png diff --git a/src/_h5ai/icons/48x48/markdown.png b/src/_h5ai/client/icons/48x48/markdown.png similarity index 100% rename from src/_h5ai/icons/48x48/markdown.png rename to src/_h5ai/client/icons/48x48/markdown.png diff --git a/src/_h5ai/icons/48x48/package.png b/src/_h5ai/client/icons/48x48/package.png similarity index 100% rename from src/_h5ai/icons/48x48/package.png rename to src/_h5ai/client/icons/48x48/package.png diff --git a/src/_h5ai/icons/48x48/pdf.png b/src/_h5ai/client/icons/48x48/pdf.png similarity index 100% rename from src/_h5ai/icons/48x48/pdf.png rename to src/_h5ai/client/icons/48x48/pdf.png diff --git a/src/_h5ai/icons/48x48/php.png b/src/_h5ai/client/icons/48x48/php.png similarity index 100% rename from src/_h5ai/icons/48x48/php.png rename to src/_h5ai/client/icons/48x48/php.png diff --git a/src/_h5ai/icons/48x48/playlist.png b/src/_h5ai/client/icons/48x48/playlist.png similarity index 100% rename from src/_h5ai/icons/48x48/playlist.png rename to src/_h5ai/client/icons/48x48/playlist.png diff --git a/src/_h5ai/icons/48x48/png.png b/src/_h5ai/client/icons/48x48/png.png similarity index 100% rename from src/_h5ai/icons/48x48/png.png rename to src/_h5ai/client/icons/48x48/png.png diff --git a/src/_h5ai/icons/48x48/pres.png b/src/_h5ai/client/icons/48x48/pres.png similarity index 100% rename from src/_h5ai/icons/48x48/pres.png rename to src/_h5ai/client/icons/48x48/pres.png diff --git a/src/_h5ai/icons/48x48/ps.png b/src/_h5ai/client/icons/48x48/ps.png similarity index 100% rename from src/_h5ai/icons/48x48/ps.png rename to src/_h5ai/client/icons/48x48/ps.png diff --git a/src/_h5ai/icons/48x48/psd.png b/src/_h5ai/client/icons/48x48/psd.png similarity index 100% rename from src/_h5ai/icons/48x48/psd.png rename to src/_h5ai/client/icons/48x48/psd.png diff --git a/src/_h5ai/icons/48x48/py.png b/src/_h5ai/client/icons/48x48/py.png similarity index 100% rename from src/_h5ai/icons/48x48/py.png rename to src/_h5ai/client/icons/48x48/py.png diff --git a/src/_h5ai/icons/48x48/rar.png b/src/_h5ai/client/icons/48x48/rar.png similarity index 100% rename from src/_h5ai/icons/48x48/rar.png rename to src/_h5ai/client/icons/48x48/rar.png diff --git a/src/_h5ai/icons/48x48/rb.png b/src/_h5ai/client/icons/48x48/rb.png similarity index 100% rename from src/_h5ai/icons/48x48/rb.png rename to src/_h5ai/client/icons/48x48/rb.png diff --git a/src/_h5ai/icons/48x48/readme.png b/src/_h5ai/client/icons/48x48/readme.png similarity index 100% rename from src/_h5ai/icons/48x48/readme.png rename to src/_h5ai/client/icons/48x48/readme.png diff --git a/src/_h5ai/icons/48x48/rpm.png b/src/_h5ai/client/icons/48x48/rpm.png similarity index 100% rename from src/_h5ai/icons/48x48/rpm.png rename to src/_h5ai/client/icons/48x48/rpm.png diff --git a/src/_h5ai/icons/48x48/rss.png b/src/_h5ai/client/icons/48x48/rss.png similarity index 100% rename from src/_h5ai/icons/48x48/rss.png rename to src/_h5ai/client/icons/48x48/rss.png diff --git a/src/_h5ai/icons/48x48/rtf.png b/src/_h5ai/client/icons/48x48/rtf.png similarity index 100% rename from src/_h5ai/icons/48x48/rtf.png rename to src/_h5ai/client/icons/48x48/rtf.png diff --git a/src/_h5ai/icons/48x48/script.png b/src/_h5ai/client/icons/48x48/script.png similarity index 100% rename from src/_h5ai/icons/48x48/script.png rename to src/_h5ai/client/icons/48x48/script.png diff --git a/src/_h5ai/client/icons/48x48/source.png b/src/_h5ai/client/icons/48x48/source.png new file mode 100644 index 00000000..c7bf4344 Binary files /dev/null and b/src/_h5ai/client/icons/48x48/source.png differ diff --git a/src/_h5ai/icons/48x48/sql.png b/src/_h5ai/client/icons/48x48/sql.png similarity index 100% rename from src/_h5ai/icons/48x48/sql.png rename to src/_h5ai/client/icons/48x48/sql.png diff --git a/src/_h5ai/icons/48x48/tar.png b/src/_h5ai/client/icons/48x48/tar.png similarity index 100% rename from src/_h5ai/icons/48x48/tar.png rename to src/_h5ai/client/icons/48x48/tar.png diff --git a/src/_h5ai/icons/48x48/tex.png b/src/_h5ai/client/icons/48x48/tex.png similarity index 100% rename from src/_h5ai/icons/48x48/tex.png rename to src/_h5ai/client/icons/48x48/tex.png diff --git a/src/_h5ai/icons/48x48/text.png b/src/_h5ai/client/icons/48x48/text.png similarity index 100% rename from src/_h5ai/icons/48x48/text.png rename to src/_h5ai/client/icons/48x48/text.png diff --git a/src/_h5ai/icons/48x48/tiff.png b/src/_h5ai/client/icons/48x48/tiff.png similarity index 100% rename from src/_h5ai/icons/48x48/tiff.png rename to src/_h5ai/client/icons/48x48/tiff.png diff --git a/src/_h5ai/icons/48x48/unknown.png b/src/_h5ai/client/icons/48x48/unknown.png similarity index 100% rename from src/_h5ai/icons/48x48/unknown.png rename to src/_h5ai/client/icons/48x48/unknown.png diff --git a/src/_h5ai/icons/48x48/vcal.png b/src/_h5ai/client/icons/48x48/vcal.png similarity index 100% rename from src/_h5ai/icons/48x48/vcal.png rename to src/_h5ai/client/icons/48x48/vcal.png diff --git a/src/_h5ai/icons/48x48/video.png b/src/_h5ai/client/icons/48x48/video.png similarity index 100% rename from src/_h5ai/icons/48x48/video.png rename to src/_h5ai/client/icons/48x48/video.png diff --git a/src/_h5ai/icons/48x48/xml.png b/src/_h5ai/client/icons/48x48/xml.png similarity index 100% rename from src/_h5ai/icons/48x48/xml.png rename to src/_h5ai/client/icons/48x48/xml.png diff --git a/src/_h5ai/icons/48x48/zip.png b/src/_h5ai/client/icons/48x48/zip.png similarity index 100% rename from src/_h5ai/icons/48x48/zip.png rename to src/_h5ai/client/icons/48x48/zip.png diff --git a/src/_h5ai/client/images/app-16x16.ico b/src/_h5ai/client/images/app-16x16.ico new file mode 100644 index 00000000..d8d95d09 Binary files /dev/null and b/src/_h5ai/client/images/app-16x16.ico differ diff --git a/src/_h5ai/images/h5ai-48x48.png b/src/_h5ai/client/images/app-48x48.png similarity index 100% rename from src/_h5ai/images/h5ai-48x48.png rename to src/_h5ai/client/images/app-48x48.png diff --git a/src/_h5ai/images/ascending.png b/src/_h5ai/client/images/ascending.png similarity index 100% rename from src/_h5ai/images/ascending.png rename to src/_h5ai/client/images/ascending.png diff --git a/src/_h5ai/images/blank.png b/src/_h5ai/client/images/blank.png similarity index 100% rename from src/_h5ai/images/blank.png rename to src/_h5ai/client/images/blank.png diff --git a/src/_h5ai/images/crumb.png b/src/_h5ai/client/images/crumb.png similarity index 100% rename from src/_h5ai/images/crumb.png rename to src/_h5ai/client/images/crumb.png diff --git a/src/_h5ai/client/images/delete.png b/src/_h5ai/client/images/delete.png new file mode 100644 index 00000000..9d8afaef Binary files /dev/null and b/src/_h5ai/client/images/delete.png differ diff --git a/src/_h5ai/images/descending.png b/src/_h5ai/client/images/descending.png similarity index 100% rename from src/_h5ai/images/descending.png rename to src/_h5ai/client/images/descending.png diff --git a/src/_h5ai/images/download.png b/src/_h5ai/client/images/download.png similarity index 100% rename from src/_h5ai/images/download.png rename to src/_h5ai/client/images/download.png diff --git a/src/_h5ai/images/filter.png b/src/_h5ai/client/images/filter.png similarity index 100% rename from src/_h5ai/images/filter.png rename to src/_h5ai/client/images/filter.png diff --git a/src/_h5ai/images/home.png b/src/_h5ai/client/images/home.png similarity index 100% rename from src/_h5ai/images/home.png rename to src/_h5ai/client/images/home.png diff --git a/src/_h5ai/images/loading.gif b/src/_h5ai/client/images/loading.gif similarity index 100% rename from src/_h5ai/images/loading.gif rename to src/_h5ai/client/images/loading.gif diff --git a/src/_h5ai/images/loading.png b/src/_h5ai/client/images/loading.png similarity index 100% rename from src/_h5ai/images/loading.png rename to src/_h5ai/client/images/loading.png diff --git a/src/_h5ai/images/page.png b/src/_h5ai/client/images/page.png similarity index 100% rename from src/_h5ai/images/page.png rename to src/_h5ai/client/images/page.png diff --git a/src/_h5ai/images/preview/close.png b/src/_h5ai/client/images/preview/close.png similarity index 100% rename from src/_h5ai/images/preview/close.png rename to src/_h5ai/client/images/preview/close.png diff --git a/src/_h5ai/images/preview/crumb.png b/src/_h5ai/client/images/preview/crumb.png similarity index 100% rename from src/_h5ai/images/preview/crumb.png rename to src/_h5ai/client/images/preview/crumb.png diff --git a/src/_h5ai/images/preview/fullscreen.png b/src/_h5ai/client/images/preview/fullscreen.png similarity index 100% rename from src/_h5ai/images/preview/fullscreen.png rename to src/_h5ai/client/images/preview/fullscreen.png diff --git a/src/_h5ai/images/preview/home.png b/src/_h5ai/client/images/preview/home.png similarity index 100% rename from src/_h5ai/images/preview/home.png rename to src/_h5ai/client/images/preview/home.png diff --git a/src/_h5ai/images/preview/next.png b/src/_h5ai/client/images/preview/next.png similarity index 100% rename from src/_h5ai/images/preview/next.png rename to src/_h5ai/client/images/preview/next.png diff --git a/src/_h5ai/images/preview/no-fullscreen.png b/src/_h5ai/client/images/preview/no-fullscreen.png similarity index 100% rename from src/_h5ai/images/preview/no-fullscreen.png rename to src/_h5ai/client/images/preview/no-fullscreen.png diff --git a/src/_h5ai/images/preview/play.png b/src/_h5ai/client/images/preview/play.png similarity index 100% rename from src/_h5ai/images/preview/play.png rename to src/_h5ai/client/images/preview/play.png diff --git a/src/_h5ai/images/preview/prev.png b/src/_h5ai/client/images/preview/prev.png similarity index 100% rename from src/_h5ai/images/preview/prev.png rename to src/_h5ai/client/images/preview/prev.png diff --git a/src/_h5ai/images/preview/raw.png b/src/_h5ai/client/images/preview/raw.png similarity index 100% rename from src/_h5ai/images/preview/raw.png rename to src/_h5ai/client/images/preview/raw.png diff --git a/src/_h5ai/images/tree.png b/src/_h5ai/client/images/tree.png similarity index 100% rename from src/_h5ai/images/tree.png rename to src/_h5ai/client/images/tree.png diff --git a/src/_h5ai/images/view-details.png b/src/_h5ai/client/images/view-details.png similarity index 100% rename from src/_h5ai/images/view-details.png rename to src/_h5ai/client/images/view-details.png diff --git a/src/_h5ai/images/view-icons.png b/src/_h5ai/client/images/view-grid.png similarity index 100% rename from src/_h5ai/images/view-icons.png rename to src/_h5ai/client/images/view-grid.png diff --git a/src/_h5ai/client/images/view-icons.png b/src/_h5ai/client/images/view-icons.png new file mode 100644 index 00000000..a9cb1fe6 Binary files /dev/null and b/src/_h5ai/client/images/view-icons.png differ diff --git a/src/_h5ai/images/view-list.png b/src/_h5ai/client/images/view-list.png similarity index 100% rename from src/_h5ai/images/view-list.png rename to src/_h5ai/client/images/view-list.png diff --git a/src/_h5ai/client/js/inc/core/entry.js b/src/_h5ai/client/js/inc/core/entry.js new file mode 100644 index 00000000..53431840 --- /dev/null +++ b/src/_h5ai/client/js/inc/core/entry.js @@ -0,0 +1,48 @@ + +modulejs.define('core/entry', ['_', '$', 'core/format', 'model/entry'], function (_, $, format, Entry) { + + var parseGenericJson = function (absHref, $container) { + + return JSON.parse($.trim($container.text()) || '{}').entries; + }, + + parseApacheTable = function (absHref, $table) { + + return _.compact(_.map($table.find('td').closest('tr'), function (tr) { + + var $tds = $(tr).find('td'), + $a = $tds.eq(1).find('a'); + + return $a.text() === 'Parent Directory' ? null : { + absHref: absHref + $a.attr('href'), + time: format.parseDate($tds.eq(2).text(), ['YYYY-MM-DD HH:mm', 'DD-MMM-YYYY HH:mm']), + size: format.parseSize($tds.eq(3).text()) + }; + })); + }, + + parse = function (absHref, $html) { + + var $generic = $html.find('#data-generic-json'), + $apache = $html.find('#data-apache-autoindex table'), + json = []; + + if ($generic.length) { + json = parseGenericJson(absHref, $generic); + } else if ($apache.length) { + json = parseApacheTable(absHref, $apache); + } + + return _.map(json, function (entry) { + + return Entry.get(entry.absHref, entry.time, entry.size, entry.status, entry.content); + }); + }, + + entry = Entry.get(); + + parse(entry.absHref, $('body')); + entry.status = '=h5ai='; + + return entry; +}); diff --git a/src/_h5ai/client/js/inc/core/event.js b/src/_h5ai/client/js/inc/core/event.js new file mode 100644 index 00000000..14fd0d61 --- /dev/null +++ b/src/_h5ai/client/js/inc/core/event.js @@ -0,0 +1,42 @@ + +modulejs.define('core/event', ['_'], function (_) { + + var subscriptions = {}, + + sub = function (topic, callback) { + + if (_.isString(topic) && _.isFunction(callback)) { + + if (!subscriptions[topic]) { + subscriptions[topic] = []; + } + subscriptions[topic].push(callback); + } + }, + + unsub = function (topic, callback) { + + if (_.isString(topic) && _.isFunction(callback) && subscriptions[topic]) { + + subscriptions[topic] = _.without(subscriptions[topic], callback); + } + }, + + pub = function (topic, data) { + + // console.log('EVENT PUB', topic, data); + if (_.isString(topic) && subscriptions[topic]) { + + _.each(subscriptions[topic], function (callback) { + + callback(data); + }); + } + }; + + return { + sub: sub, + unsub: unsub, + pub: pub + }; +}); diff --git a/src/_h5ai/js/inc/core/format.js b/src/_h5ai/client/js/inc/core/format.js similarity index 67% rename from src/_h5ai/js/inc/core/format.js rename to src/_h5ai/client/js/inc/core/format.js index f59245f5..edebc71d 100644 --- a/src/_h5ai/js/inc/core/format.js +++ b/src/_h5ai/client/js/inc/core/format.js @@ -2,13 +2,23 @@ modulejs.define('core/format', ['_', 'moment'], function (_, moment) { var reParseSize = /^\s*([\.\d]+)\s*([kmgt]?)b?\s*$/i, - treshhold = 1000.0, - kilo = 1000.0, - sizeUnits = ['B', 'KB', 'MB', 'GB', 'TB'], + decimalMetric = { + t: 1000.0, + k: 1000.0, + u: ['B', 'KB', 'MB', 'GB', 'TB'] + }, + binaryMetric = { + t: 1024.0, + k: 1024.0, + u: ['B', 'KiB', 'MiB', 'GiB', 'TiB'] + }, + defaultMetric = decimalMetric, + defaultDateFormat = 'YYYY-MM-DD HH:mm', parseSize = function (str) { var match = reParseSize.exec(str), + kilo = decimalMetric.k, val, unit; if (!match) { @@ -29,24 +39,35 @@ modulejs.define('core/format', ['_', 'moment'], function (_, moment) { return val; }, - formatSize = function (size) { + setDefaultMetric = function (metric) { + + if (!metric) { + defaultMetric = decimalMetric; + } else if (metric === true) { + defaultMetric = binaryMetric; + } else { + defaultMetric = metric; + } + }, + + formatSize = function (size, metric) { + + metric = metric || defaultMetric; if (!_.isNumber(size) || size < 0) { return ''; } var i = 0, - maxI = sizeUnits.length - 1; + maxI = metric.u.length - 1; - while (size >= treshhold && i < maxI) { - size /= kilo; + while (size >= metric.t && i < maxI) { + size /= metric.k; i += 1; } - return (i <= 1 ? Math.round(size) : size.toFixed(1)).toString() + ' ' + sizeUnits[i]; + return (i <= 1 ? Math.round(size) : size.toFixed(1)).toString() + ' ' + metric.u[i]; }, - defaultDateFormat = 'YYYY-MM-DD HH:mm', - setDefaultDateFormat = function (dateFormat) { defaultDateFormat = dateFormat; @@ -72,6 +93,7 @@ modulejs.define('core/format', ['_', 'moment'], function (_, moment) { return { parseSize: parseSize, + setDefaultMetric: setDefaultMetric, formatSize: formatSize, setDefaultDateFormat: setDefaultDateFormat, parseDate: parseDate, diff --git a/src/_h5ai/client/js/inc/core/langs.js b/src/_h5ai/client/js/inc/core/langs.js new file mode 100644 index 00000000..9a7f1555 --- /dev/null +++ b/src/_h5ai/client/js/inc/core/langs.js @@ -0,0 +1,5 @@ + +modulejs.define('core/langs', ['config', '_'], function (config, _) { + + return _.extend({}, config.langs); +}); diff --git a/src/_h5ai/client/js/inc/core/location.js b/src/_h5ai/client/js/inc/core/location.js new file mode 100644 index 00000000..0ebcb24e --- /dev/null +++ b/src/_h5ai/client/js/inc/core/location.js @@ -0,0 +1,52 @@ + +modulejs.define('core/location', ['$', 'core/event'], function ($, event) { + + var doc = document, + + forceEncoding = function (href) { + + return href + .replace(/\/+/g, '/') + .replace(/ /g, '%20') + .replace(/'/g, '%27') + .replace(/\[/g, '%5B') + .replace(/\]/g, '%5D') + .replace(/\(/g, '%28') + .replace(/\)/g, '%29') + .replace(/\+/g, '%2B') + .replace(/\=/g, '%3D'); + }, + + absHref = (function () { + + var rePrePathname = /.*:\/\/[^\/]*/, + rePostPathname = /[^\/]*$/, + + uriToPathname = function (uri) { + + return uri.replace(rePrePathname, '').replace(rePostPathname, ''); + }, + + testpathname = '/a b', + a = doc.createElement('a'), + isDecoded, location; + + a.href = testpathname; + isDecoded = uriToPathname(a.href) === testpathname; + + a.href = doc.location.href; + location = uriToPathname(a.href); + + if (isDecoded) { + location = encodeURIComponent(location).replace(/%2F/ig, '/'); + } + + return forceEncoding(location); + }()); + + return { + domain: doc.domain, + absHref: absHref, + forceEncoding: forceEncoding + }; +}); diff --git a/src/_h5ai/client/js/inc/core/refresh.js b/src/_h5ai/client/js/inc/core/refresh.js new file mode 100644 index 00000000..23d60b84 --- /dev/null +++ b/src/_h5ai/client/js/inc/core/refresh.js @@ -0,0 +1,37 @@ + +modulejs.define('core/refresh', ['_', 'core/server', 'model/entry'], function (_, server, Entry) { + + var parseJson = function (entry, json) { + + var found = {}; + + _.each(json.entries, function (jsonEntry) { + + var e = Entry.get(jsonEntry.absHref, jsonEntry.time, jsonEntry.size, jsonEntry.status, jsonEntry.content); + found[e.absHref] = true; + }); + + _.each(entry.content, function (e) { + if (!found[e.absHref]) { + Entry.remove(e.absHref); + } + }); + }, + + refresh = function (callback) { + + var entry = Entry.get(); + + server.request({action: 'get', entries: true, entriesHref: entry.absHref, entriesWhat: 1}, function (json) { + + if (json) { + parseJson(entry, json); + } + if (_.isFunction(callback)) { + callback(entry); + } + }); + }; + + return refresh; +}); diff --git a/src/_h5ai/client/js/inc/core/resource.js b/src/_h5ai/client/js/inc/core/resource.js new file mode 100644 index 00000000..1be1a4cc --- /dev/null +++ b/src/_h5ai/client/js/inc/core/resource.js @@ -0,0 +1,17 @@ + +modulejs.define('core/resource', ['core/settings'], function (settings) { + + var image = function (id, noPngExt) { + + return settings.h5aiAbsHref + 'client/images/' + id + (noPngExt ? '' : '.png'); + }, + icon = function (id, big) { + + return settings.h5aiAbsHref + 'client/icons/' + (big ? '48x48' : '16x16') + '/' + id + '.png'; + }; + + return { + image: image, + icon: icon + }; +}); diff --git a/src/_h5ai/client/js/inc/core/server.js b/src/_h5ai/client/js/inc/core/server.js new file mode 100644 index 00000000..7870d219 --- /dev/null +++ b/src/_h5ai/client/js/inc/core/server.js @@ -0,0 +1,150 @@ + +modulejs.define('core/server', ['$', '_', 'config'], function ($, _, config) { + + var server = _.extend({}, config.server, { + + request: function (data, callback) { + + if (server.api) { + $.ajax({ + url: '.', + data: data, + type: 'POST', + dataType: 'json', + success: function (json) { + + callback(json); + }, + error: function () { + + callback(); + } + }); + } else if (server.backend === 'aai') { + return modulejs.require('core/server-request-mock-aai')(data, callback); + } else { + callback(); + } + } + }); + + return server; +}); + + + +modulejs.define('core/server-request-mock-aai', ['$', '_', 'core/settings', 'core/format'], function ($, _, allsettings, format) { + + var loadText = function (href) { + + var deferred = $.Deferred(); + + $.ajax(href, {dataType: 'text'}).always(function (content) { + + content = content.replace ? content : null; + deferred.resolve(content); + }); + + return deferred; + }, + + loadJson = function (href) { + + var deferred = $.Deferred(); + + loadText(href).always(function (content) { + + var json = content.replace ? JSON.parse(content.replace(/\/\*[\s\S]*?\*\/|\/\/.*?(\n|$)/g, '')) : {}; + deferred.resolve(json); + }); + + return deferred; + }, + + parse = function (absHref, html) { + + html = '
' + html.replace(/^[\s\S]*|<\/body>[\s\S]*$/g, '') + '
'; + var $table = $(html).find('#data-apache-autoindex table'); + + return _.compact(_.map($table.find('td').closest('tr'), function (tr) { + + var $tds = $(tr).find('td'), + $a = $tds.eq(1).find('a'); + + return $a.text() === 'Parent Directory' ? null : { + absHref: absHref + $a.attr('href'), + time: format.parseDate($tds.eq(2).text(), ['YYYY-MM-DD HH:mm', 'DD-MMM-YYYY HH:mm']), + size: format.parseSize($tds.eq(3).text()) + }; + })); + }; + + return function (data, callback) { + + if (data.action === 'get' && data.l10n === true) { + + var isoCodes = data.l10nCodes.split(':'); + var isoCode = data.l10nCodes.split(':')[0]; + loadJson(allsettings.h5aiAbsHref + 'conf/l10n/' + isoCode + '.json').done(function (json) { + + var result = {code: 0, l10n: {}}; + + if (json) { + result.l10n[isoCode] = json; + } + callback(result); + }); + + } else if (data.action === 'get' && data.custom === true) { + + $.when( + loadText('_h5ai.header.html'), + loadText('_h5ai.footer.html') + ).done(function (header, footer) { + + callback({ + code: 0, + custom: { + header: header, + footer: footer + } + }); + }); + + } else if (data.action === 'get' && data.entries === true) { + + var absHref = data.entriesHref, + what = data.entriesWhat, + magicSequence = '=h5ai=', + reContentType = /^text\/html;h5ai=/; + + $.ajax({ + url: absHref, + type: what === 0 ? 'HEAD' : 'GET', + complete: function (xhr) { + + var entries = [], + status = xhr.status; + + if (status === 200 && reContentType.test(xhr.getResponseHeader('Content-Type'))) { + status = magicSequence; + } + + if (status === magicSequence && what > 0) { + entries = parse(absHref, xhr.responseText); + } + entries.push({absHref: absHref, status: status, content: what > 0}); + + callback({ + code: 0, + entries: entries + }); + } + }); + + } else { + + callback(); + } + }; +}); diff --git a/src/_h5ai/client/js/inc/core/settings.js b/src/_h5ai/client/js/inc/core/settings.js new file mode 100644 index 00000000..6afde834 --- /dev/null +++ b/src/_h5ai/client/js/inc/core/settings.js @@ -0,0 +1,16 @@ + +modulejs.define('core/settings', ['config', '_', '$'], function (config, _, $) { + + var settings = _.extend({ + h5aiAbsHref: '/_h5ai/' + }, config.options), + + filename = 'client/js/scripts.js', + src = $('script[src$="' + filename + '"]').attr('src'), + appHref = src.substr(0, src.length - filename.length); + + settings.h5aiAbsHref = src.substr(0, src.length - filename.length).replace(/\/*$/, '/'); + settings.rootAbsHref = /^(.*\/)[^\/]+\/?$/.exec(settings.h5aiAbsHref)[1]; + + return settings; +}); diff --git a/src/_h5ai/client/js/inc/core/store.js b/src/_h5ai/client/js/inc/core/store.js new file mode 100644 index 00000000..c7c2a7c3 --- /dev/null +++ b/src/_h5ai/client/js/inc/core/store.js @@ -0,0 +1,29 @@ + +modulejs.define('core/store', ['_'], function (_) { + + var store = window.localStorage, + + put = function (key, value) { + + if (store && _.isString(key)) { + store[key] = JSON.stringify({data: value}); + } + }, + + get = function (key) { + + if (store && _.isString(key)) { + var json = store[key], + obj = {}; + + try { obj = JSON.parse(json); } catch (e) {} + + return obj.data; + } + }; + + return { + put: put, + get: get + }; +}); diff --git a/src/_h5ai/js/inc/core/types.js b/src/_h5ai/client/js/inc/core/types.js similarity index 100% rename from src/_h5ai/js/inc/core/types.js rename to src/_h5ai/client/js/inc/core/types.js diff --git a/src/_h5ai/client/js/inc/ext/autorefresh.js b/src/_h5ai/client/js/inc/ext/autorefresh.js new file mode 100644 index 00000000..7faff453 --- /dev/null +++ b/src/_h5ai/client/js/inc/ext/autorefresh.js @@ -0,0 +1,30 @@ + +modulejs.define('ext/autorefresh', ['_', '$', 'core/settings', 'core/event', 'core/refresh'], function (_, $, allsettings, event, refresh) { + + var settings = _.extend({ + enabled: false, + interval: 5000 + }, allsettings.autorefresh), + + heartbeat = function () { + + refresh(); + setTimeout(heartbeat, settings.interval); + }, + + init = function () { + + if (!settings.enabled) { + return; + } + + settings.interval = Math.max(1000, settings.interval); + + event.sub('ready', function () { + + setTimeout(heartbeat, settings.interval); + }); + }; + + init(); +}); diff --git a/src/_h5ai/js/inc/ext/crumb.js b/src/_h5ai/client/js/inc/ext/crumb.js similarity index 62% rename from src/_h5ai/js/inc/ext/crumb.js rename to src/_h5ai/client/js/inc/ext/crumb.js index 07d8ebcb..da128980 100644 --- a/src/_h5ai/js/inc/ext/crumb.js +++ b/src/_h5ai/client/js/inc/ext/crumb.js @@ -1,25 +1,23 @@ -modulejs.define('ext/crumb', ['_', '$', 'core/settings', 'core/resource', 'core/entry'], function (_, $, allsettings, resource, entry) { +modulejs.define('ext/crumb', ['_', '$', 'core/settings', 'core/resource', 'core/event', 'core/entry'], function (_, $, allsettings, resource, event, entry) { - var defaults = { + var settings = _.extend({ enabled: false - }, - - settings = _.extend({}, defaults, allsettings.crumb), + }, allsettings.crumb), template = '
  • ' + '' + - '>' + - '' + + '>' + + '' + '' + '
  • ', - pageHintTemplate = 'has index page', - statusHintTemplate = '', + pageHintTemplate = 'has index page', + statusHintTemplate = '', // updates the crumb for this single entry - update = function (entry) { + update = function (entry, force) { - if (entry.$crumb && entry.$crumb.data('status') === entry.status) { + if (!force && entry.$crumb && entry.$crumb.data('status') === entry.status) { return entry.$crumb; } @@ -39,6 +37,11 @@ modulejs.define('ext/crumb', ['_', '$', 'core/settings', 'core/resource', 'core/ $a.find('img').attr('src', resource.image('home')); } + if (entry.isRoot()) { + $html.addClass('root'); + $a.find('img').attr('src', resource.image('home')); + } + if (entry.isCurrentFolder()) { $html.addClass('current'); } @@ -59,6 +62,13 @@ modulejs.define('ext/crumb', ['_', '$', 'core/settings', 'core/resource', 'core/ return $html; }, + onContentChanged = function (entry) { + + if (entry.$crumb) { + update(entry, true); + } + }, + // creates the complete crumb from entry down to the root init = function (entry) { @@ -72,12 +82,11 @@ modulejs.define('ext/crumb', ['_', '$', 'core/settings', 'core/resource', 'core/ _.each(crumb, function (e) { $ul.append(update(e)); - - e.fetchStatus(function (e) { - - update(e); - }); }); + + // event.sub('entry.created', onContentChanged); + // event.sub('entry.removed', onContentChanged); + event.sub('entry.changed', onContentChanged); }; init(entry); diff --git a/src/_h5ai/client/js/inc/ext/custom.js b/src/_h5ai/client/js/inc/ext/custom.js new file mode 100644 index 00000000..5da2495b --- /dev/null +++ b/src/_h5ai/client/js/inc/ext/custom.js @@ -0,0 +1,30 @@ + +modulejs.define('ext/custom', ['_', '$', 'core/settings', 'core/server'], function (_, $, allsettings, server) { + + var settings = _.extend({ + enabled: false, + header: '_h5ai.header.html', + footer: '_h5ai.footer.html' + }, allsettings.custom), + + init = function () { + + if (!settings.enabled) { + return; + } + + server.request({action: 'get', custom: true}, function (response) { + + if (response) { + if (response.custom.header) { + $('
    ' + response.custom.header + '
    ').prependTo('#content'); + } + if (response.custom.footer) { + $('').appendTo('#content'); + } + } + }); + }; + + init(); +}); diff --git a/src/_h5ai/client/js/inc/ext/delete.js b/src/_h5ai/client/js/inc/ext/delete.js new file mode 100644 index 00000000..7c99f4de --- /dev/null +++ b/src/_h5ai/client/js/inc/ext/delete.js @@ -0,0 +1,77 @@ + +modulejs.define('ext/delete', ['_', '$', 'core/settings', 'core/event', 'core/resource', 'core/refresh', 'core/server'], function (_, $, allsettings, event, resource, refresh, server) { + + var settings = _.extend({ + enabled: false + }, allsettings['delete']), + + deleteBtnTemplate = '
  • ' + + '' + + 'delete' + + '' + + '' + + '
  • ', + + selectedHrefsStr = '', + $delete, $img, + + failed = function () { + + $delete.addClass('failed'); + setTimeout(function () { + $delete.removeClass('failed'); + }, 1000); + }, + + handleResponse = function (json) { + + $delete.removeClass('current'); + $img.attr('src', resource.image('delete')); + + if (!json || json.code) { + failed(); + } + refresh(); + }, + + requestDeletion = function (hrefsStr) { + + $delete.addClass('current'); + $img.attr('src', resource.image('loading.gif', true)); + server.request({action: 'delete', hrefs: hrefsStr}, handleResponse); + }, + + onSelection = function (entries) { + + selectedHrefsStr = ''; + if (entries.length) { + selectedHrefsStr = _.map(entries, function (entry) { + + return entry.absHref; + }).join(':'); + $delete.appendTo('#navbar').show(); + } else { + $delete.hide(); + } + }, + + init = function () { + + if (!settings.enabled || !server.api) { + return; + } + + $delete = $(deleteBtnTemplate) + .find('a').on('click', function (event) { + + event.preventDefault(); + requestDeletion(selectedHrefsStr); + }).end() + .appendTo('#navbar'); + $img = $delete.find('img'); + + event.sub('selection', onSelection); + }; + + init(); +}); diff --git a/src/_h5ai/js/inc/ext/download.js b/src/_h5ai/client/js/inc/ext/download.js similarity index 50% rename from src/_h5ai/js/inc/ext/download.js rename to src/_h5ai/client/js/inc/ext/download.js index 719555f9..fbab9e5a 100644 --- a/src/_h5ai/js/inc/ext/download.js +++ b/src/_h5ai/client/js/inc/ext/download.js @@ -1,29 +1,24 @@ -modulejs.define('ext/download', ['_', '$', 'core/settings', 'core/resource', 'core/event', 'core/ajax'], function (_, $, allsettings, resource, event, ajax) { +modulejs.define('ext/download', ['_', '$', 'core/settings', 'core/resource', 'core/event', 'core/server', 'core/entry'], function (_, $, allsettings, resource, event, server, entry) { - var defaults = { + var settings = _.extend({ enabled: false, execution: 'php', - format: 'zip' - }, - - settings = _.extend({}, defaults, allsettings.download), + format: 'zip', + packageName: 'package' + }, allsettings.download), // formats = ['tar', 'zip'], downloadBtnTemplate = '
  • ' + '' + - 'download' + - 'download' + + 'download' + + '' + '' + '
  • ', - authTemplate = '
    ' + - '' + - '' + - '
    ', selectedHrefsStr = '', - $download, $img, $downloadAuth, $downloadUser, $downloadPassword, + $download, $img, failed = function () { @@ -38,24 +33,11 @@ modulejs.define('ext/download', ['_', '$', 'core/settings', 'core/resource', 'co $download.removeClass('current'); $img.attr('src', resource.image('download')); - if (json) { - if (json.code === 0) { - setTimeout(function () { // wait here so the img above can be updated in time + if (json && json.code === 0) { + setTimeout(function () { // wait here so the img above can be updated in time - window.location = resource.api() + '?action=getarchive&id=' + json.id + '&as=h5ai-selection.' + settings.format; - }, 200); - } else { - if (json.code === 401) { - $downloadAuth - .css({ - left: $download.offset().left, - top: $download.offset().top + $download.outerHeight() - }) - .show(); - $downloadUser.focus(); - } - failed(); - } + window.location = '?action=getArchive&id=' + json.id + '&as=' + (settings.packageName || entry.label) + '.' + settings.format; + }, 200); } else { failed(); } @@ -65,12 +47,12 @@ modulejs.define('ext/download', ['_', '$', 'core/settings', 'core/resource', 'co $download.addClass('current'); $img.attr('src', resource.image('loading.gif', true)); - ajax.getArchive({ + + server.request({ + action: 'createArchive', execution: settings.execution, format: settings.format, - hrefs: hrefsStr, - user: $downloadUser.val(), - password: $downloadPassword.val() + hrefs: hrefsStr }, handleResponse); }, @@ -85,13 +67,12 @@ modulejs.define('ext/download', ['_', '$', 'core/settings', 'core/resource', 'co $download.appendTo('#navbar').show(); } else { $download.hide(); - $downloadAuth.hide(); } }, init = function () { - if (!settings.enabled) { + if (!settings.enabled || !server.api) { return; } @@ -99,16 +80,11 @@ modulejs.define('ext/download', ['_', '$', 'core/settings', 'core/resource', 'co .find('a').on('click', function (event) { event.preventDefault(); - $downloadAuth.hide(); requestArchive(selectedHrefsStr); }).end() .appendTo('#navbar'); $img = $download.find('img'); - $downloadAuth = $(authTemplate).appendTo('body'); - $downloadUser = $downloadAuth.find('#download-auth-user'); - $downloadPassword = $downloadAuth.find('#download-auth-password'); - event.sub('selection', onSelection); }; diff --git a/src/_h5ai/client/js/inc/ext/dropbox.js b/src/_h5ai/client/js/inc/ext/dropbox.js new file mode 100644 index 00000000..e0d8caad --- /dev/null +++ b/src/_h5ai/client/js/inc/ext/dropbox.js @@ -0,0 +1,113 @@ + +modulejs.define('ext/dropbox', ['_', '$', 'core/settings', 'core/entry', 'core/refresh', 'core/server'], function (_, $, allsettings, entry, refresh, server) { + + var settings = _.extend({ + enabled: false, + maxfiles: 5, + maxfilesize: 20 + }, allsettings.dropbox), + + template = '
      ', + + uploadTemplate = '
    • ' + + '' + + '' + + '
      ' + + '
    • ', + + init = function () { + + if (!settings.enabled || !server.api) { + return; + } + + var $content = $('#content').append(template); + + var uploads = {}, + afterUpload = function (err, file) { + + if (file) { + uploads[file.name] + .addClass(err ? 'error' : 'finished') + .find('.progress').replaceWith(err ? '' + err + '' : 'okay'); + + setTimeout(function () { + uploads[file.name].slideUp(400, function () { + + uploads[file.name].remove(); + delete uploads[file.name]; + }); + }, 5000); + } + }; + + $content.filedrop({ + + paramname: 'userfile', + + maxfiles: settings.maxfiles, + maxfilesize: settings.maxfilesize, + url: server.api, + data: { + action: 'upload', + href: entry.absHref + }, + + docEnter: function () { + + $content.addClass('hint'); + }, + + docLeave: function () { + + $content.removeClass('hint'); + }, + + dragOver: function () { + + $content.addClass('match'); + }, + + dragLeave: function () { + + $content.removeClass('match'); + }, + + drop: function () { + + $content.removeClass('hint match'); + }, + + + beforeEach: function (file) { + + uploads[file.name] = $(uploadTemplate).appendTo('#uploads') + .find('.name').text(file.name).end() + .find('.size').text(file.size).end() + .find('.progress .bar').css('width', 0).end(); + }, + + progressUpdated: function (i, file, progress) { + + uploads[file.name].find('.progress .bar').css('width', '' + progress + '%'); + }, + + uploadFinished: function (i, file, response) { + + afterUpload(response.code && response.msg, file); + }, + + afterAll: function () { + + refresh(); + }, + + error: function (err, file) { + + afterUpload(err, file); + } + }); + }; + + init(); +}); diff --git a/src/_h5ai/js/inc/ext/filter.js b/src/_h5ai/client/js/inc/ext/filter.js similarity index 76% rename from src/_h5ai/js/inc/ext/filter.js rename to src/_h5ai/client/js/inc/ext/filter.js index ec75b5ce..3d2ce0f6 100644 --- a/src/_h5ai/js/inc/ext/filter.js +++ b/src/_h5ai/client/js/inc/ext/filter.js @@ -1,19 +1,17 @@ modulejs.define('ext/filter', ['_', '$', 'core/settings', 'core/resource'], function (_, $, allsettings, resource) { - var defaults = { + var settings = _.extend({ enabled: false - }, - - settings = _.extend({}, defaults, allsettings.filter), + }, allsettings.filter), template = '
    • ' + '' + - 'filter' + - '' + + 'filter' + + '' + '' + '
    • ', - noMatchTemplate = '
      no match
      ', + noMatchTemplate = '
      ', $filter, $input, $noMatch, @@ -47,17 +45,6 @@ modulejs.define('ext/filter', ['_', '$', 'core/settings', 'core/resource'], func $(noMatch).fadeOut(duration); }, - checkState = function (focus) { - - var val = $input.val(); - - if (val || focus) { - $filter.addClass('current'); - } else { - $filter.removeClass('current'); - } - }, - escapeRegExp = function (sequence) { return sequence.replace(/[\-\[\]{}()*+?.,\\$\^|#\s]/g, '\\$&'); @@ -75,8 +62,6 @@ modulejs.define('ext/filter', ['_', '$', 'core/settings', 'core/resource'], func return escapeRegExp(char); }).join('.*?'); - - // return escapeRegExp(part); }).join('|'); return new RegExp(sequence, 'i'); @@ -88,10 +73,11 @@ modulejs.define('ext/filter', ['_', '$', 'core/settings', 'core/resource'], func if (val) { filter(parseFilterSequence(val)); + $filter.addClass('current'); } else { filter(); + $filter.removeClass('current'); } - checkState($input.is(':focus')); }, init = function () { @@ -100,7 +86,7 @@ modulejs.define('ext/filter', ['_', '$', 'core/settings', 'core/resource'], func return; } - $filter = $(template); + $filter = $(template).appendTo('#navbar'); $input = $filter.find('input'); $noMatch = $(noMatchTemplate).appendTo('#extended'); @@ -108,19 +94,26 @@ modulejs.define('ext/filter', ['_', '$', 'core/settings', 'core/resource'], func .on('click', function () { $input.focus(); - }) - .appendTo('#navbar'); + }); $input .on('focus', function () { - checkState(true); + $filter.addClass('current'); }) - .on('blur', function () { + .on('blur keyup', update); - checkState(false); + $(document) + .on('keydown', function (event) { + + if (event.which === 27) { + $input.attr('value','').blur(); + } }) - .on('keyup', update); + .on('keypress', function (event) { + + $input.focus(); + }); }; init(); diff --git a/src/_h5ai/client/js/inc/ext/folderstatus.js b/src/_h5ai/client/js/inc/ext/folderstatus.js new file mode 100644 index 00000000..929f7e79 --- /dev/null +++ b/src/_h5ai/client/js/inc/ext/folderstatus.js @@ -0,0 +1,30 @@ + +modulejs.define('ext/folderstatus', ['_', '$', 'core/settings', 'core/event', 'core/entry'], function (_, $, allsettings, event, entry) { + + var settings = _.extend({ + enabled: false, + maxChecks: 16, + delay: 2000 + }, allsettings.folderstatus), + + init = function () { + + if (!settings.enabled) { + return; + } + + event.sub('ready', function () { + + var count = 0; + _.each(entry.content, function (e) { + + if (e.isFolder() && e.status === null && count <= settings.maxChecks) { + count += 1; + setTimeout(function () { e.fetchStatus(); }, settings.delay); + } + }); + }); + }; + + init(); +}); diff --git a/src/_h5ai/js/inc/ext/google-analytics.js b/src/_h5ai/client/js/inc/ext/google-analytics.js similarity index 86% rename from src/_h5ai/js/inc/ext/google-analytics.js rename to src/_h5ai/client/js/inc/ext/google-analytics.js index 60a82d33..7238d855 100644 --- a/src/_h5ai/js/inc/ext/google-analytics.js +++ b/src/_h5ai/client/js/inc/ext/google-analytics.js @@ -1,12 +1,10 @@ modulejs.define('ext/google-analytics', ['_', 'core/settings'], function (_, allsettings) { - var defaults = { + var settings = _.extend({ enabled: false, gaq: [] - }, - - settings = _.extend({}, defaults, allsettings['google-analytics']), + }, allsettings['google-analytics']), init = function () { diff --git a/src/_h5ai/client/js/inc/ext/l10n.js b/src/_h5ai/client/js/inc/ext/l10n.js new file mode 100644 index 00000000..66a8a3de --- /dev/null +++ b/src/_h5ai/client/js/inc/ext/l10n.js @@ -0,0 +1,168 @@ + +modulejs.define('ext/l10n', ['_', '$', 'core/settings', 'core/langs', 'core/format', 'core/store', 'core/event', 'core/server'], function (_, $, allsettings, langs, format, store, event, server) { + + var settings = _.extend({ + enabled: false, + lang: 'en', + useBrowserLang: true + }, allsettings.l10n), + + defaultTranslations = { + isoCode: 'en', + lang: 'english', + details: 'details', + list: "list", + grid: "grid", + icons: 'icons', + name: 'Name', + lastModified: 'Last modified', + size: 'Size', + parentDirectory: 'Parent Directory', + empty: 'empty', + folders: 'folders', + files: 'files', + download: 'download', + noMatch: 'no match', + dateFormat: 'YYYY-MM-DD HH:mm', + filter: 'filter', + 'delete': 'delete' + }, + + template = '' + + ' - ' + + '
        ' + + '', + langOptionTemplate = '
      • ', + + storekey = 'h5ai.language', + + loaded = { + en: _.extend({}, defaultTranslations) + }, + currentLang = loaded.en, + + update = function (lang) { + + if (lang) { + currentLang = lang; + } + + $.each(currentLang, function (key, value) { + $('.l10n-' + key).text(value); + }); + $('.langOption').removeClass('current'); + $('.langOption.' + currentLang.isoCode).addClass('current'); + + format.setDefaultDateFormat(currentLang.dateFormat); + + $('#extended .entry .date').each(function () { + + var $this = $(this); + + $this.text(format.formatDate($this.data('time'))); + }); + + $('#filter input').attr('placeholder', currentLang.filter); + }, + + loadLanguage = function (isoCode, callback) { + + if (loaded[isoCode]) { + + callback(loaded[isoCode]); + } else { + + server.request({action: 'get', l10n: true, l10nCodes: isoCode}, function (response) { + + var json = response.l10n && response.l10n[isoCode] ? response.l10n[isoCode] : {}; + loaded[isoCode] = _.extend({}, defaultTranslations, json, {isoCode: isoCode}); + callback(loaded[isoCode]); + }); + } + }, + + localize = function (langs, isoCode, useBrowserLang) { + + var storedIsoCode = store.get(storekey); + + if (langs[storedIsoCode]) { + isoCode = storedIsoCode; + } else if (useBrowserLang) { + var browserLang = navigator.language || navigator.browserLanguage; + if (browserLang) { + if (langs[browserLang]) { + isoCode = browserLang; + } else if (browserLang.length > 2 && langs[browserLang.substr(0, 2)]) { + isoCode = browserLang.substr(0, 2); + } + } + } + + if (!langs[isoCode]) { + isoCode = 'en'; + } + + loadLanguage(isoCode, update); + }, + + initLangSelector = function (langs) { + + var $langSelector = $(template).appendTo('#bottombar .right'), + $langOptions = $langSelector.find('.langOptions'), + $ul = $langOptions.find('ul'), + isoCodes = []; + + $.each(langs, function (isoCode) { + isoCodes.push(isoCode); + }); + isoCodes.sort(); + + $.each(isoCodes, function (idx, isoCode) { + $(langOptionTemplate) + .addClass(isoCode) + .text(isoCode + ' - ' + (_.isString(langs[isoCode]) ? langs[isoCode] : langs[isoCode].lang)) + .appendTo($ul) + .click(function () { + store.put(storekey, isoCode); + localize(langs, isoCode, false); + }); + }); + $langOptions + .append($ul) + .scrollpanel(); + + $langSelector.hover( + function () { + $langOptions + .css('top', '-' + $langOptions.outerHeight() + 'px') + .stop(true, true) + .fadeIn(); + + // needs to be updated twice for initial fade in rendering :/ + $langOptions.scrollpanel('update').scrollpanel('update'); + }, + function () { + $langOptions + .stop(true, true) + .fadeOut(); + } + ); + }, + + init = function () { + + if (!settings.enabled) { + event.sub('ready', function () { update(); }); + return; + } + + initLangSelector(langs); + + event.sub('ready', function () { + + localize(langs, settings.lang, settings.useBrowserLang); + }); + }; + + init(); +}); diff --git a/src/_h5ai/js/inc/ext/link-hover-states.js b/src/_h5ai/client/js/inc/ext/link-hover-states.js similarity index 88% rename from src/_h5ai/js/inc/ext/link-hover-states.js rename to src/_h5ai/client/js/inc/ext/link-hover-states.js index dc403b19..f3a84e0c 100644 --- a/src/_h5ai/js/inc/ext/link-hover-states.js +++ b/src/_h5ai/client/js/inc/ext/link-hover-states.js @@ -1,11 +1,9 @@ modulejs.define('ext/link-hover-states', ['_', '$', 'core/settings'], function (_, $, allsettings) { - var defaults = { + var settings = _.extend({ enabled: false - }, - - settings = _.extend({}, defaults, allsettings['link-hover-states']), + }, allsettings['link-hover-states']), selector = "a[href^='/']", diff --git a/src/_h5ai/client/js/inc/ext/mode.js b/src/_h5ai/client/js/inc/ext/mode.js new file mode 100644 index 00000000..e8350432 --- /dev/null +++ b/src/_h5ai/client/js/inc/ext/mode.js @@ -0,0 +1,33 @@ + +modulejs.define('ext/mode', ['_', '$', 'core/settings', 'core/server'], function (_, $, allsettings, server) { + + var settings = _.extend({ + enabled: false, + display: 0 + }, allsettings.mode), + + init = function () { + + if (!settings.enabled) { + return; + } + + var info = ''; + + if (server.backend) { + info += server.backend; + } + if (settings.display > 0 && server.name) { + info += (info ? ' on ' : '') + server.name; + } + if (settings.display > 1 && server.version) { + info += (info ? '-' : '') + server.version; + } + + if (info) { + $('#bottombar .left').append(' (' + info + ') '); + } + }; + + init(); +}); diff --git a/src/_h5ai/client/js/inc/ext/piwik-analytics.js b/src/_h5ai/client/js/inc/ext/piwik-analytics.js new file mode 100755 index 00000000..7bc05191 --- /dev/null +++ b/src/_h5ai/client/js/inc/ext/piwik-analytics.js @@ -0,0 +1,31 @@ + +modulejs.define('ext/piwik-analytics', ['_', '$', 'core/settings'], function (_, $, allsettings) { + + var settings = _.extend({ + enabled: false, + baseURL: 'not-set', + idSite: 0 + }, allsettings['piwik-analytics']), + + init = function () { + + if (!settings.enabled) { + return; + } + + // reference: http://piwik.org/docs/javascript-tracking/ + + var pkBaseURL = (("https:" === document.location.protocol) ? "https://" : "http://") + settings.baseURL + '/'; + + $(' - - -

        h5ai

        - version {{version}} - {{stamp}} -

        server supports

        -
          -
        • php version? -
          PHP version >= 5.2.1
          -
        • -
        • cache? -
          _h5ai/cache writable for the server
          -
        • -
        • image thumbs? -
          PHP GD extension with JPEG support available
          -
        • -
        • movie thumbs? -
          ffmpeg executable in a shell
          -
        • -
        • pdf thumbs? -
          convert executable in a shell
          -
        • -
        • temp directory? -
          temporary directory writable for the server
          -
        • -
        • php tar and zip? -
          PHP Phar extension available
          -
        • -
        • shell tar? -
          tar executable in a shell
          -
        • -
        • shell zip? -
          zip executable in a shell
          -
        • -
        • folder size? -
          du executable in a shell
          -
        • -
        -
        - - h5ai {{version}} - ⚡ JavaScript is disabled! ⚡ - ⚡ Some features disabled! Works best in modern browsers. ⚡ - - - -
        - - - - \ No newline at end of file diff --git a/src/_h5ai/index.html.jade b/src/_h5ai/index.html.jade new file mode 100644 index 00000000..8503be40 --- /dev/null +++ b/src/_h5ai/index.html.jade @@ -0,0 +1,76 @@ +doctype 5 +//if lt IE 9 + +//[if gt IE 8]>= 5.2.1 + li.test( data-id="cache" ) + span.test-label cache directory + span.test-result ? + div.test-info web server has write access + li.test( data-id="thumbs" ) + span.test-label image thumbs + span.test-result ? + div.test-info PHP GD extension with JPEG support available + li.test( data-id="ffmpeg" ) + span.test-label movie thumbs + span.test-result ? + div.test-info command 'ffmpeg' available + li.test( data-id="convert" ) + span.test-label pdf thumbs + span.test-result ? + div.test-info command 'convert' available + li.test( data-id="archive" ) + span.test-label php tar and zip + span.test-result ? + div.test-info PHP Phar extension available + li.test( data-id="tar" ) + span.test-label shell tar + span.test-result ? + div.test-info command 'tar' available + li.test( data-id="zip" ) + span.test-label shell zip + span.test-result ? + div.test-info command 'zip' available + li.test( data-id="du" ) + span.test-label folder size + span.test-result ? + div.test-info command 'du' available + + div#bottombar.clearfix + span.left + a#h5ai-reference( href="{{pkg.url}}", title="{{pkg.name}} · {{pkg.description}}" ) + | {{pkg.name}} {{pkg.version}} + span.hideOnJs.noJsMsg + | ⚡ JavaScript is disabled! ⚡ + span.oldBrowser + | ⚡ Some features disabled! Works best in + a( href="http://browsehappy.com" ) modern browsers + | . ⚡ + span.right + span.center diff --git a/src/_h5ai/js/inc/core/ajax.js b/src/_h5ai/js/inc/core/ajax.js deleted file mode 100644 index 1dec7865..00000000 --- a/src/_h5ai/js/inc/core/ajax.js +++ /dev/null @@ -1,157 +0,0 @@ - -modulejs.define('core/ajax', ['$', 'amplify', 'base64', 'core/resource'], function ($, amplify, base64, resource) { - - var reContentType = /^text\/html;h5ai=/, - - getStatus = function (href, withContent, callback) { - - $.ajax({ - url: href, - type: withContent ? 'GET' : 'HEAD', - complete: function (xhr) { - - var res = { - status: xhr.status, - content: xhr.responseText - }; - - if (xhr.status === 200 && reContentType.test(xhr.getResponseHeader('Content-Type'))) { - res.status = 'h5ai'; - } - - callback(res); - } - }); - }, - - getChecks = function (callback) { - - $.ajax({ - url: resource.api(), - data: { - action: 'getchecks' - }, - type: 'POST', - dataType: 'json', - success: function (json) { - - callback(json); - }, - error: function () { - - callback(); - } - }); - }, - - getArchive = function (data, callback) { - - $.ajax({ - url: resource.api(), - data: { - action: 'archive', - execution: data.execution, - format: data.format, - hrefs: data.hrefs - }, - type: 'POST', - dataType: 'json', - beforeSend: function (xhr) { - - if (data.user) { - xhr.setRequestHeader('Authorization', 'Basic ' + base64.encode(data.user + ':' + data.password)); - } - }, - success: function (json) { - - callback(json); - }, - error: function () { - - callback(); - } - }); - }, - - getThumbSrc = function (data, callback) { - - $.ajax({ - url: resource.api(), - data: { - action: 'getthumbsrc', - type: data.type, - href: data.href, - mode: data.mode, - width: data.width, - height: data.height - }, - type: 'POST', - dataType: 'json', - success: function (json) { - - if (json.code === 0) { - callback(json.absHref); - } - callback(); - }, - error: function () { - - callback(); - } - }); - }, - - getThumbSrcSmall = function (type, href, callback) { - - getThumbSrc( - { - type: type, - href: href, - mode: 'square', - width: 16, - height: 16 - }, - callback - ); - }, - - getThumbSrcBig = function (type, href, callback) { - - getThumbSrc( - { - type: type, - href: href, - mode: 'rational', - width: 100, - height: 48 - }, - callback - ); - }, - - getHtml = function (url, callback) { - - $.ajax({ - url: url, - dataType: 'html', - success: function (html) { - - callback(html); - }, - error: function () { - - callback(); - } - }); - }; - - - return { - getStatus: getStatus, - getChecks: getChecks, - getArchive: getArchive, - getThumbSrcSmall: getThumbSrcSmall, - getThumbSrcBig: getThumbSrcBig, - getHtml: getHtml - }; -}); diff --git a/src/_h5ai/js/inc/core/entry.js b/src/_h5ai/js/inc/core/entry.js deleted file mode 100644 index 289ab15c..00000000 --- a/src/_h5ai/js/inc/core/entry.js +++ /dev/null @@ -1,15 +0,0 @@ - -modulejs.define('core/entry', ['$', 'core/parser', 'model/entry'], function ($, parser, Entry) { - - var entry = Entry.get(); - - parser.parse(entry.absHref, $('body')); - $('#data-apache-autoindex').remove(); - - entry.status = 'h5ai'; - if (entry.parent) { - entry.parent.isParentFolder = true; - } - - return entry; -}); diff --git a/src/_h5ai/js/inc/core/event.js b/src/_h5ai/js/inc/core/event.js deleted file mode 100644 index 81ce4284..00000000 --- a/src/_h5ai/js/inc/core/event.js +++ /dev/null @@ -1,25 +0,0 @@ - -modulejs.define('core/event', ['amplify'], function (amplify) { - - var sub = function (topic, callback) { - - amplify.subscribe(topic, callback); - }, - - unsub = function (topic, callback) { - - amplify.unsubscribe(topic, callback); - }, - - pub = function (topic, data) { - - // console.log('EVENT PUB', topic, data); - amplify.publish(topic, data); - }; - - return { - sub: sub, - unsub: unsub, - pub: pub - }; -}); diff --git a/src/_h5ai/js/inc/core/langs.js b/src/_h5ai/js/inc/core/langs.js deleted file mode 100644 index 1c851f55..00000000 --- a/src/_h5ai/js/inc/core/langs.js +++ /dev/null @@ -1,34 +0,0 @@ - -modulejs.define('core/langs', ['config', '_'], function (config, _) { - - var defaults = { - lang: 'unknown', - details: 'details', - icons: 'icons', - name: 'Name', - lastModified: 'Last modified', - size: 'Size', - parentDirectory: 'Parent Directory', - empty: 'empty', - folders: 'folders', - files: 'files', - download: 'download', - noMatch: 'no match', - dateFormat: 'YYYY-MM-DD HH:mm', - filter: 'filter' - }, - - translations = {}, - - parse = function (langs) { - - _.each(langs, function (trans, lang) { - - translations[lang] = _.extend({}, defaults, trans); - }); - }; - - parse(_.extend({}, config.langs)); - - return translations; -}); diff --git a/src/_h5ai/js/inc/core/parser.js b/src/_h5ai/js/inc/core/parser.js deleted file mode 100644 index 9002ef30..00000000 --- a/src/_h5ai/js/inc/core/parser.js +++ /dev/null @@ -1,22 +0,0 @@ - -modulejs.define('core/parser', ['$'], function ($) { - - if ($('#data-apache-autoindex').length) { - return modulejs.require('parser/apache-autoindex'); - } - if ($('#data-generic-json').length) { - return modulejs.require('parser/generic-json'); - } - - return { - id: 'none', - mode: null, - server: { - name: null, - version: null - }, - parse: function () { - return []; - } - }; -}); diff --git a/src/_h5ai/js/inc/core/resource.js b/src/_h5ai/js/inc/core/resource.js deleted file mode 100644 index 17baed3c..00000000 --- a/src/_h5ai/js/inc/core/resource.js +++ /dev/null @@ -1,22 +0,0 @@ - -modulejs.define('core/resource', ['core/settings'], function (settings) { - - var api = function () { - - return settings.h5aiAbsHref + 'php/api.php'; - }, - image = function (id, noPngExt) { - - return settings.h5aiAbsHref + 'images/' + id + (noPngExt ? '' : '.png'); - }, - icon = function (id, big) { - - return settings.h5aiAbsHref + 'icons/' + (big ? '48x48' : '16x16') + '/' + id + '.png'; - }; - - return { - api: api, - image: image, - icon: icon - }; -}); diff --git a/src/_h5ai/js/inc/core/settings.js b/src/_h5ai/js/inc/core/settings.js deleted file mode 100644 index 5111291e..00000000 --- a/src/_h5ai/js/inc/core/settings.js +++ /dev/null @@ -1,12 +0,0 @@ - -modulejs.define('core/settings', ['config', '_'], function (config, _) { - - var defaults = { - rootAbsHref: '/', - h5aiAbsHref: '/_h5ai/', - server: 'unknown', - mode: 'unknown' - }; - - return _.extend({}, defaults, config.options); -}); diff --git a/src/_h5ai/js/inc/core/store.js b/src/_h5ai/js/inc/core/store.js deleted file mode 100644 index ca7f6715..00000000 --- a/src/_h5ai/js/inc/core/store.js +++ /dev/null @@ -1,18 +0,0 @@ - -modulejs.define('core/store', ['amplify'], function (amplify) { - - var put = function (key, value) { - - amplify.store(key, value); - }, - - get = function (key) { - - return amplify.store(key); - }; - - return { - put: put, - get: get - }; -}); diff --git a/src/_h5ai/js/inc/ext/custom.js b/src/_h5ai/js/inc/ext/custom.js deleted file mode 100644 index 95be1a5a..00000000 --- a/src/_h5ai/js/inc/ext/custom.js +++ /dev/null @@ -1,38 +0,0 @@ - -modulejs.define('ext/custom', ['_', '$', 'core/settings', 'core/ajax'], function (_, $, allsettings, ajax) { - - var defaults = { - enabled: false, - header: '_h5ai.header.html', - footer: '_h5ai.footer.html' - }, - - settings = _.extend({}, defaults, allsettings.custom), - - init = function () { - - if (!settings.enabled) { - return; - } - - if (_.isString(settings.header)) { - ajax.getHtml(settings.header, function (html) { - - if (html) { - $('
        ' + html + '
        ').prependTo('#content'); - } - }); - } - - if (_.isString(settings.footer)) { - ajax.getHtml(settings.footer, function (html) { - - if (html) { - $('').appendTo('#content'); - } - }); - } - }; - - init(); -}); diff --git a/src/_h5ai/js/inc/ext/folderstatus.js b/src/_h5ai/js/inc/ext/folderstatus.js deleted file mode 100644 index 4c110db4..00000000 --- a/src/_h5ai/js/inc/ext/folderstatus.js +++ /dev/null @@ -1,14 +0,0 @@ - -modulejs.define('ext/folderstatus', ['_', 'core/settings'], function (_, allsettings) { - - var defaults = { - enabled: false, - folders: {} - }, - - settings = _.extend({}, defaults, allsettings.folderstatus), - - folders = settings.enabled ? settings.folders : defaults.folders; - - return folders; -}); diff --git a/src/_h5ai/js/inc/ext/l10n.js b/src/_h5ai/js/inc/ext/l10n.js deleted file mode 100644 index c16e2b77..00000000 --- a/src/_h5ai/js/inc/ext/l10n.js +++ /dev/null @@ -1,124 +0,0 @@ - -modulejs.define('ext/l10n', ['_', '$', 'core/settings', 'core/langs', 'core/format', 'core/store', 'core/event'], function (_, $, allsettings, langs, format, store, event) { - - var defaults = { - enabled: true, - lang: 'en', - useBrowserLang: true - }, - - settings = _.extend({}, defaults, allsettings.l10n), - - template = '' + - 'en - english' + - '
          ' + - '', - langOptionTemplate = '
        • ', - - storekey = 'h5ai.language', - - currentLang = null, - - localize = function (langs, lang, useBrowserLang) { - - var storedLang = store.get(storekey); - - if (langs[storedLang]) { - lang = storedLang; - } else if (useBrowserLang) { - var browserLang = navigator.language || navigator.browserLanguage; - if (browserLang) { - if (langs[browserLang]) { - lang = browserLang; - } else if (browserLang.length > 2 && langs[browserLang.substr(0, 2)]) { - lang = browserLang.substr(0, 2); - } - } - } - - if (!langs[lang]) { - lang = 'en'; - } - - currentLang = langs[lang]; - if (currentLang) { - $.each(currentLang, function (key, value) { - $('.l10n-' + key).text(value); - }); - $('.lang').text(lang); - $('.langOption').removeClass('current'); - $('.langOption.' + lang).addClass('current'); - } - - format.setDefaultDateFormat(currentLang.dateFormat); - - $('#extended .entry .date').each(function () { - - var $this = $(this); - - $this.text(format.formatDate($this.data('time'))); - }); - - $('#filter input').attr('placeholder', currentLang.filter); - }, - - initLangSelector = function (langs) { - - var $langSelector = $(template).appendTo('#bottombar .right'), - $langOptions = $langSelector.find('.langOptions'), - $ul = $langOptions.find('ul'), - sortedLangsKeys = []; - - $.each(langs, function (lang) { - sortedLangsKeys.push(lang); - }); - sortedLangsKeys.sort(); - - $.each(sortedLangsKeys, function (idx, lang) { - $(langOptionTemplate) - .addClass(lang) - .text(lang + ' - ' + langs[lang].lang) - .appendTo($ul) - .click(function () { - store.put(storekey, lang); - localize(langs, lang, false); - }); - }); - $langOptions - .append($ul) - .scrollpanel(); - - $langSelector.hover( - function () { - $langOptions - .css('top', '-' + $langOptions.outerHeight() + 'px') - .stop(true, true) - .fadeIn(); - - // needs to be updated twice for initial fade in rendering :/ - $langOptions.scrollpanel('update').scrollpanel('update'); - }, - function () { - $langOptions - .stop(true, true) - .fadeOut(); - } - ); - }, - - init = function () { - - if (!settings.enabled) { - return; - } - - initLangSelector(langs); - - event.sub('ready', function () { - - localize(langs, settings.lang, settings.useBrowserLang); - }); - }; - - init(); -}); diff --git a/src/_h5ai/js/inc/ext/mode.js b/src/_h5ai/js/inc/ext/mode.js deleted file mode 100644 index 6b2cd6c1..00000000 --- a/src/_h5ai/js/inc/ext/mode.js +++ /dev/null @@ -1,35 +0,0 @@ - -modulejs.define('ext/mode', ['_', '$', 'core/settings', 'core/parser'], function (_, $, allsettings, parser) { - - var defaults = { - enabled: false, - display: 0 - }, - - settings = _.extend({}, defaults, allsettings.mode), - - init = function () { - - if (!settings.enabled) { - return; - } - - var info = ''; - - if (parser.mode) { - info += parser.mode; - } - if (settings.display > 0 && parser.server.name) { - info += (info ? ' on ' : '') + parser.server.name; - } - if (settings.display > 1 && parser.server.version) { - info += (info ? '-' : '') + parser.server.version; - } - - if (info) { - $('#h5ai-reference').append(' (' + info + ')'); - } - }; - - init(); -}); diff --git a/src/_h5ai/js/inc/ext/qrcode.js b/src/_h5ai/js/inc/ext/qrcode.js deleted file mode 100644 index cdd183b0..00000000 --- a/src/_h5ai/js/inc/ext/qrcode.js +++ /dev/null @@ -1,56 +0,0 @@ - -modulejs.define('ext/qrcode', ['_', '$', 'modernizr', 'core/settings', 'core/event'], function (_, $, modernizr, allsettings, event) { - - var defaults = { - enabled: false, - size: 150 - }, - - settings = _.extend({}, defaults, allsettings.qrcode), - - template = '
          ', - - $context, hideTimeoutId, - - update = function (entry) { - - $context.find('.qrcode').empty().qrcode({ - render: modernizr.canvas ? 'canvas' : 'div', - width: settings.size, - height: settings.size, - color: '#333', - text: 'http://' + document.domain + entry.absHref - }); - }, - - onMouseenter = function (entry) { - - if (!entry.isFolder()) { - update(entry); - clearTimeout(hideTimeoutId); - $context.stop(true, true).fadeIn(400); - } - }, - - onMouseleave = function (entry) { - - hideTimeoutId = setTimeout(function () { - - $context.stop(true, true).fadeOut(400); - }, 200); - }, - - init = function () { - - if (!settings.enabled) { - return; - } - - $context = $(template).appendTo('body'); - - event.sub('entry.mouseenter', onMouseenter); - event.sub('entry.mouseleave', onMouseleave); - }; - - init(); -}); diff --git a/src/_h5ai/js/inc/h5ai-info.js b/src/_h5ai/js/inc/h5ai-info.js deleted file mode 100644 index 606d57cd..00000000 --- a/src/_h5ai/js/inc/h5ai-info.js +++ /dev/null @@ -1,29 +0,0 @@ - -modulejs.define('h5ai-info', ['$', 'core/ajax'], function ($, ajax) { - - var setCheckResult = function (id, result) { - - var $ele = $(id).find('.test-result'); - - if (result) { - $ele.addClass('test-passed').text('yes'); - } else { - $ele.addClass('test-failed').text('no'); - } - }, - - init = function () { - - ajax.getChecks(function (json) { - - if (json) { - $('.test').each(function () { - - setCheckResult(this, json[$(this).data('id')]); - }); - } - }); - }; - - init(); -}); diff --git a/src/_h5ai/js/inc/main.js b/src/_h5ai/js/inc/main.js deleted file mode 100644 index feacef09..00000000 --- a/src/_h5ai/js/inc/main.js +++ /dev/null @@ -1,67 +0,0 @@ - -(function ($) { - 'use strict'; - - - // @include "core/ajax.js" - // @include "core/entry.js" - // @include "core/event.js" - // @include "core/format.js" - // @include "core/langs.js" - // @include "core/parser.js" - // @include "core/resource.js" - // @include "core/settings.js" - // @include "core/store.js" - // @include "core/types.js" - - // @include "model/entry.js" - - // @include "parser/apache-autoindex.js" - // @include "parser/generic-json.js" - - // @include "view/extended.js" - // @include "view/spacing.js" - // @include "view/viewmode.js" - - // @include "ext/crumb.js" - // @include "ext/custom.js" - // @include "ext/download.js" - // @include "ext/filter.js" - // @include "ext/folderstatus.js" - // @include "ext/google-analytics.js" - // @include "ext/l10n.js" - // @include "ext/link-hover-states.js" - // @include "ext/mode.js" - // @include "ext/preview-img.js" - // @include "ext/preview-txt.js" - // @include "ext/qrcode.js" - // @include "ext/select.js" - // @include "ext/sort.js" - // @include "ext/statusbar.js" - // @include "ext/thumbnails.js" - // @include "ext/title.js" - // @include "ext/tree.js" - - // @include "h5ai-info.js" - // @include "h5ai-main.js" - - - $(function () { - /*global H5AI_CONFIG, amplify, Base64, jQuery, Modernizr, moment, _ */ - - // Register predefined globals on doc ready, so the script order inside - // the document doesn't matter. `jQuery`, `moment` and `underscore` are - // itself functions, so they have to be wrapped to not be handled as - // constructors. - modulejs.define('config', H5AI_CONFIG); - modulejs.define('amplify', amplify); - modulejs.define('base64', Base64); - modulejs.define('$', function () { return jQuery; }); - modulejs.define('modernizr', Modernizr); - modulejs.define('moment', function () { return moment; }); - modulejs.define('_', function () { return _; }); - - modulejs.require($('body').attr('id')); - }); - -}(jQuery)); diff --git a/src/_h5ai/js/inc/model/entry.js b/src/_h5ai/js/inc/model/entry.js deleted file mode 100644 index 4e6539a4..00000000 --- a/src/_h5ai/js/inc/model/entry.js +++ /dev/null @@ -1,284 +0,0 @@ - -modulejs.define('model/entry', ['_', 'core/types', 'core/ajax'], function (_, types, ajax) { - - var doc = document, - domain = doc.domain, - - forceEncoding = function (href) { - - return href - .replace(/\/+/g, '/') - .replace(/'/g, '%27') - .replace(/\[/g, '%5B') - .replace(/\]/g, '%5D') - .replace(/\(/g, '%28') - .replace(/\)/g, '%29') - .replace(/\+/g, '%2B') - .replace(/\=/g, '%3D'); - }, - - - location = (function () { - - var rePrePathname = /.*:\/\/[^\/]*/, - rePostPathname = /[^\/]*$/, - - uriToPathname = function (uri) { - - return uri.replace(rePrePathname, '').replace(rePostPathname, ''); - }, - - testpathname = '/a b', - a = doc.createElement('a'), - isDecoded, location; - - a.href = testpathname; - isDecoded = uriToPathname(a.href) === testpathname; - - a.href = doc.location.href; - location = uriToPathname(a.href); - - if (isDecoded) { - location = encodeURIComponent(location).replace(/%2F/ig, '/'); - } - - return forceEncoding(location); - }()), - - folderstatus = (function () { - - try { return modulejs.require('ext/folderstatus'); } catch (e) {} - return {}; - }()), - - - - // utils - - reEndsWithSlash = /\/$/, - - - createLabel = function (sequence) { - - if (sequence.length > 1 && reEndsWithSlash.test(sequence)) { - sequence = sequence.slice(0, -1); - } - try { sequence = decodeURIComponent(sequence); } catch (e) {} - return sequence; - }, - - - reSplitPath = /^\/([^\/]+\/?)$/, - reSplitPath2 = /^(\/(?:.*\/)*?([^\/]+)\/)([^\/]+\/?)$/, - - splitPath = function (sequence) { - - var match; - - if (sequence === '/') { - return { parent: null, name: '/' }; - } - match = reSplitPath2.exec(sequence); - if (match) { - return { parent: match[1], name: match[3] }; - } - match = reSplitPath.exec(sequence); - if (match) { - return { parent: '/', name: match[1] }; - } - }, - - - ajaxRequest = function (self, parser, callback) { - - ajax.getStatus(self.absHref, parser, function (response) { - - self.status = response.status; - if (parser && response.status === 'h5ai') { - parser.parse(self.absHref, response.content); - } - callback(self); - }); - }, - - - - // Cache - - cache = {}, - - getEntry = function (absHref, time, size, status, isContentFetched) { - - absHref = forceEncoding(absHref || location); - - var self = cache[absHref] || new Entry(absHref); - - if (_.isNumber(time)) { - self.time = time; - } - if (_.isNumber(size)) { - self.size = size; - } - if (status) { - self.status = status; - } - if (isContentFetched) { - self.isContentFetched = true; - } - - return self; - }, - - fetchStatus = function (absHref, callback) { - - var self = getEntry(absHref); - - if (self.status || !self.isFolder()) { - callback(self); - } else if (folderstatus[absHref]) { - self.status = folderstatus[absHref]; - callback(self); - } else { - ajaxRequest(self, null, callback); - } - }, - - fetchContent = function (absHref, parser, callback) { - - var self = getEntry(absHref); - - if (self.isContentFetched) { - callback(self); - } else { - fetchStatus(absHref, function (self) { - - self.isContentFetched = true; - if (self.status === 'h5ai') { - ajaxRequest(self, parser, callback); - } else { - callback(self); - } - }); - } - }; - - - - // Entry - - var Entry = function (absHref) { - - var split = splitPath(absHref); - - cache[absHref] = this; - - this.absHref = absHref; - this.type = types.getType(absHref); - this.label = createLabel(absHref === '/' ? domain : split.name); - this.time = null; - this.size = null; - this.parent = null; - this.status = null; - this.content = {}; - - if (split.parent) { - this.parent = getEntry(split.parent); - this.parent.content[this.absHref] = this; - if (_.keys(this.parent.content).length > 1) { - this.parent.isContentFetched = true; - } - } - }; - - _.extend(Entry.prototype, { - - isFolder: function () { - - return reEndsWithSlash.test(this.absHref); - }, - - isCurrentFolder: function () { - - return this.absHref === location; - }, - - isDomain: function () { - - return this.absHref === '/'; - }, - - isEmpty: function () { - - return _.keys(this.content).length === 0; - }, - - fetchStatus: function (callback) { - - return fetchStatus(this.absHref, callback); - }, - - fetchContent: function (parser, callback) { - - return fetchContent(this.absHref, parser, callback); - }, - - getCrumb: function () { - - var entry = this, - crumb = [entry]; - - while (entry.parent) { - entry = entry.parent; - crumb.unshift(entry); - } - - return crumb; - }, - - getSubfolders: function () { - - return _.sortBy(_.filter(this.content, function (entry) { - - return entry.isFolder(); - }), function (entry) { - - return entry.label.toLowerCase(); - }); - }, - - getStats: function () { - - var folders = 0, - files = 0; - - _.each(this.content, function (entry) { - - if (entry.isFolder()) { - folders += 1; - } else { - files += 1; - } - }); - - var depth = 0, - entry = this; - - while (entry.parent) { - depth += 1; - entry = entry.parent; - } - - return { - folders: folders, - files: files, - depth: depth - }; - } - }); - - - - return { - get: getEntry - }; -}); diff --git a/src/_h5ai/js/inc/parser/apache-autoindex.js b/src/_h5ai/js/inc/parser/apache-autoindex.js deleted file mode 100644 index 5123aeed..00000000 --- a/src/_h5ai/js/inc/parser/apache-autoindex.js +++ /dev/null @@ -1,47 +0,0 @@ - -modulejs.define('parser/apache-autoindex', ['_', '$', 'core/settings', 'core/format', 'model/entry'], function (_, $, settings, format, Entry) { - - var parseTableRow = function (absHref, tr) { - - var $tds = $(tr).find('td'), - $a = $tds.eq(1).find('a'), - label = $a.text(), - time = format.parseDate($tds.eq(2).text(), 'DD-MMM-YYYY HH:mm'), - size = format.parseSize($tds.eq(3).text()); - - absHref = absHref + $a.attr('href'); - - return label === 'Parent Directory' ? null : Entry.get(absHref, time, size); - }, - - parseTable = function (absHref, table) { - - return _.compact(_.map($(table).find('td').closest('tr'), function (tr) { - - return parseTableRow(absHref, tr); - })); - }, - - parse = function (absHref, html) { - - var id = '#data-apache-autoindex', - $html = $(html), - $id = $html.filter(id); - - if (!$id.length) { - $id = $html.find(id); - } - - return parseTable(absHref, $id.find('table')); - }; - - return { - id: 'apache-autoindex', - mode: 'aai', - server: { - name: 'apache', - version: null - }, - parse: parse - }; -}); diff --git a/src/_h5ai/js/inc/parser/generic-json.js b/src/_h5ai/js/inc/parser/generic-json.js deleted file mode 100644 index eece589a..00000000 --- a/src/_h5ai/js/inc/parser/generic-json.js +++ /dev/null @@ -1,55 +0,0 @@ - -modulejs.define('parser/generic-json', ['_', '$', 'core/settings', 'model/entry'], function (_, $, settings, Entry) { - - var parser = { - id: 'generic-json', - mode: null, - server: { - name: null, - version: null - } - }, - - parseJson = function (absHref, json) { - - if (_.has(json, 'customHeader')) { - settings.custom.header = json.customHeader; - } - if (_.has(json, 'customFooter')) { - settings.custom.footer = json.customFooter; - } - if (_.has(json, 'mode')) { - parser.mode = json.mode; - } - if (_.has(json, 'server')) { - parser.server = json.server; - } - - return _.map(json.entries, function (jsonEntry) { - - return Entry.get(jsonEntry.absHref, jsonEntry.time, jsonEntry.size, jsonEntry.status, jsonEntry.content); - }); - }, - - parseJsonStr = function (absHref, jsonStr) { - - return parseJson(absHref, JSON.parse($.trim(jsonStr) || '{}')); - }, - - parse = function (absHref, html) { - - var id = '#data-generic-json', - $html = $(html), - $id = $html.filter(id); - - if (!$id.length) { - $id = $html.find(id); - } - - return parseJsonStr(absHref, $id.text()); - }; - - parser.parse = parse; - - return parser; -}); diff --git a/src/_h5ai/js/lib/amplify-1.1.0.min.js b/src/_h5ai/js/lib/amplify-1.1.0.min.js deleted file mode 100644 index 8398f85b..00000000 --- a/src/_h5ai/js/lib/amplify-1.1.0.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/*! - * AmplifyJS 1.1.0 - Core, Store, Request - * - * Copyright 2011 appendTo LLC. (http://appendto.com/team) - * Dual licensed under the MIT or GPL licenses. - * http://appendto.com/open-source-licenses - * - * http://amplifyjs.com - */ -(function(a,b){var c=[].slice,d={},e=a.amplify={publish:function(a){var b=c.call(arguments,1),e,f,g,h=0,i;if(!d[a])return!0;e=d[a].slice();for(g=e.length;h=0;j--)if(d[a][j].priority<=e){d[a].splice(j+1,0,k),i=!0;break}i||d[a].unshift(k)}return c},unsubscribe:function(a,b){if(!!d[a]){var c=d[a].length,e=0;for(;e> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - output = output + - this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + - this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); - - } - - return output; - }, - - // public method for decoding - decode : function (input) { - var output = ""; - var chr1, chr2, chr3; - var enc1, enc2, enc3, enc4; - var i = 0; - - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - while (i < input.length) { - - enc1 = this._keyStr.indexOf(input.charAt(i++)); - enc2 = this._keyStr.indexOf(input.charAt(i++)); - enc3 = this._keyStr.indexOf(input.charAt(i++)); - enc4 = this._keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output = output + String.fromCharCode(chr1); - - if (enc3 != 64) { - output = output + String.fromCharCode(chr2); - } - if (enc4 != 64) { - output = output + String.fromCharCode(chr3); - } - - } - - return Base64._utf8_decode(output); - }, - - // private method for UTF-8 encoding - _utf8_encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - - var c = string.charCodeAt(n); - - if (c < 128) { - utftext += String.fromCharCode(c); - } - else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } - else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // private method for UTF-8 decoding - _utf8_decode : function (utftext) { - var string = ""; - var i = 0; - var c = c1 = c2 = 0; - - while ( i < utftext.length ) { - - c = utftext.charCodeAt(i); - - if (c < 128) { - string += String.fromCharCode(c); - i++; - } - else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } - else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - - } - - return string; - } -} diff --git a/src/_h5ai/js/lib/jquery-1.7.2.min.js b/src/_h5ai/js/lib/jquery-1.7.2.min.js deleted file mode 100644 index 16ad06c5..00000000 --- a/src/_h5ai/js/lib/jquery-1.7.2.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v1.7.2 jquery.com | jquery.org/license */ -(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"":"")+""),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(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;g0){if(c!=="border")for(;e=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};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=m.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.7.2",length:0,size:function(){return this.length},toArray:function(){return F.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)?E.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(),A.add(a);return this},eq:function(a){a=+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(F.apply(this,arguments),"slice",F.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:E,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(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(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(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;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(w,"ms-").replace(v,x)},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(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
          a",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.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:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="
          "+""+"
          ",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="
          t
          ",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="
          ",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([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&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},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"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},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(p);for(c=0,d=this.length;c-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.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.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),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,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;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},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function( -a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&j.push({elem:this,matches:d.slice(e)});for(k=0;k0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.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]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),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]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.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!!m(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 bc[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=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&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=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null: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=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=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(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.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:[]}},o.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&&(o.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.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

          ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[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}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.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 m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
          ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0: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=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-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(S(c[0])||S(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);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).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 V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*",""],legend:[1,"
          ","
          "],thead:[1,"","
          "],tr:[2,"","
          "],td:[3,"","
          "],col:[2,"","
          "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
          ","
          "]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},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){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):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 -.clean(arguments);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.clean(arguments));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){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(;d1&&l0?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,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]===""&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"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=bu.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(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.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.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),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&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.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("
          ").append(c.replace(bM,"")).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||bN.test(this.nodeName)||bH.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(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(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?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},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:bY(bS),ajaxTransport:bY(bT),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?ca(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=cb(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.fireWith(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.Callbacks("once memory"),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=bG.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.add,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(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.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]!=="*"?", "+bW+"; 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=bZ(bT,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){if(s<2)w(-1,z);else throw 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)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.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(cd,l),b.url===j&&(e&&(k=k.replace(cd,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 ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,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,ce&&delete cg[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);try{m.text=h.responseText}catch(a){}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=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-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=cx.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&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/src/_h5ai/js/lib/jquery.fracs-0.11.min.js b/src/_h5ai/js/lib/jquery.fracs-0.11.min.js deleted file mode 100644 index 14b35972..00000000 --- a/src/_h5ai/js/lib/jquery.fracs-0.11.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery.fracs 0.11 - //larsjung.de/fracs - MIT License */ -(function(a,b,c){"use strict";var d=c(a),e=c(b),f=c.extend,g=c.isFunction,h=[].slice,i=Math.max,j=Math.min,k=Math.round,l=function(a,b){return typeof a===b},m=function(a,b){return a instanceof b},n=function(a){return a&&a.nodeType},o=function(a){return n(a)?a:m(a,c)?a[0]:undefined},p=function(a,b,d){return c.each(a,function(a,c){d=b.call(c,d,a,c)}),d},q=function(){var a={},b=1;return function(c){return c?(a[c]||(a[c]=b,b+=1),a[c]):0}}(),r=function(a,b,c){var d,e,f;if(a===b)return!0;if(!a||!b||a.constructor!==b.constructor)return!1;for(d=0,e=c.length;d=0&&g>=0?new s(b,d,f,g):null},envelope:function(a){if(!m(a,s))return this;var b=j(this.left,a.left),c=i(this.right,a.right),d=j(this.top,a.top),e=i(this.bottom,a.bottom),f=c-b,g=e-d;return new s(b,d,f,g)}}),f(s,{ofContent:function(c,d){return!c||c===b||c===a?new s(0,0,e.width(),e.height()):d?new s(0,0,c.scrollWidth,c.scrollHeight):new s(c.offsetLeft-c.scrollLeft,c.offsetTop-c.scrollTop,c.scrollWidth,c.scrollHeight)},ofViewport:function(c,e){return!c||c===b||c===a?new s(d.scrollLeft(),d.scrollTop(),d.width(),d.height()):e?new s(c.scrollLeft,c.scrollTop,c.clientWidth,c.clientHeight):new s(c.offsetLeft,c.offsetTop,c.clientWidth,c.clientHeight)},ofElement:function(a){var b=c(a);if(!b.is(":visible"))return null;var d=b.offset();return new s(d.left,d.top,b.outerWidth(),b.outerHeight())}});var t=function(a,b,c,d){this.visible=a||0,this.viewport=b||0,this.possible=c||0,this.rects=d&&f({},d)||null};f(t.prototype,{equals:function(a){return this.fracsEqual(a)&&this.rectsEqual(a)},fracsEqual:function(a){return r(this,a,["visible","viewport","possible"])},rectsEqual:function(a){return r(this.rects,a.rects,["document","element","viewport"])}}),f(t,{of:function(a,b){var c,d,e;return a=n(a)&&s.ofElement(a)||a,b=n(b)&&s.ofViewport(b)||b||s.ofViewport(),c=a.intersection(b),c?(d=c.area(),e=j(a.width,b.width)*j(a.height,b.height),new t(d/a.area(),d/b.area(),d/e,{document:c,element:c.relativeTo(a),viewport:c.relativeTo(b)})):new t}});var u=function(a,b){this.els=a,this.viewport=b},v=["width","height","left","right","top","bottom"],w=["possible","visible","viewport"],x=function(a,b,d){var e;return c.inArray(d,v)>=0?e=s.ofElement(a):c.inArray(d,w)>=0&&(e=t.of(a,b)),e?e[d]:0},y=function(a,b){return a.val-b.val},z=function(a,b){return b.val-a.val};f(u.prototype,{sorted:function(a,b){var d=this.viewport;return c.map(this.els,function(b){return{el:b,val:x(b,d,a)}}).sort(b?z:y)},best:function(a,b){return this.els.length?this.sorted(a,b)[0]:null}});var A=function(a){var b=s.ofContent(a,!0),c=s.ofViewport(a,!0),d=b.width-c.width,e=b.height-c.height;this.content=b,this.viewport=c,this.width=d<=0?null:c.left/d,this.height=e<=0?null:c.top/e,this.left=c.left,this.top=c.top,this.right=b.right-c.right,this.bottom=b.bottom-c.bottom};f(A.prototype,{equals:function(a){return r(this,a,["width","height","left","top","right","bottom","content","viewport"])}});var B=function(b){this.el=b||a};f(B.prototype,{equals:function(a){return r(this,a,["el"])},scrollState:function(){return new A(this.el)},scrollTo:function(b,d,e){var f=this.el===a?c("html,body"):c(this.el);b=b||0,d=d||0,e=isNaN(e)?1e3:e,f.stop(!0).animate({scrollLeft:b,scrollTop:d},e)},scroll:function(b,e,f){var g=this.el===a?d:c(this.el);b=b||0,e=e||0,this.scrollTo(g.scrollLeft()+b,g.scrollTop()+e,f)},scrollToRect:function(a,b,c,d){b=b||0,c=c||0,this.scrollTo(a.left-b,a.top-c,d)},scrollToElement:function(a,b,c,d){var e=s.ofElement(a).relativeTo(s.ofContent(this.el));this.scrollToRect(e,b,c,d)}});var C={init:function(){this.callbacks=c.Callbacks("memory unique"),this.currVal=null,this.prevVal=null,this.checkProxy=c.proxy(this.check,this),this.autoCheck()},bind:function(a){this.callbacks.add(a)},unbind:function(a){a?this.callbacks.remove(a):this.callbacks.empty()},trigger:function(){this.callbacks.fireWith(this.context,[this.currVal,this.prevVal])},check:function(a){var b=this.updatedValue(a);return b===undefined?!1:(this.prevVal=this.currVal,this.currVal=b,this.trigger(),!0)},$autoTarget:d,autoEvents:"load resize scroll",autoCheck:function(a){this.$autoTarget[a===!1?"off":"on"](this.autoEvents,this.checkProxy)}},D=function(a,b){this.context=a,this.viewport=b,this.init()};f(D.prototype,C,{updatedValue:function(){var a=t.of(this.context,this.viewport);if(!this.currVal||!this.currVal.equals(a))return a}});var E=function(a,b,c,d){this.context=new u(a,b),this.property=c,this.descending=d,this.init()};f(E.prototype,C,{updatedValue:function(){var a=this.context.best(this.property,this.descending);if(a){a=a.val>0?a.el:null;if(this.currVal!==a)return a}}});var F=function(d){!d||d===a||d===b?this.context=a:(this.context=d,this.$autoTarget=c(d)),this.init()};f(F.prototype,C,{updatedValue:function(){var a=new A(this.context);if(!this.currVal||!this.currVal.equals(a))return a}});var G=function(a,b){var d=f({},b),e=function(b,d,e,f){e=g(e)?e.apply(b,d):e;if(g(f[e]))return f[e].apply(b,d);c.error('Method "'+e+'" does not exist on jQuery.'+a)},i=function(){return e(this,h.call(arguments),d.defaultStatic,i)},j=function(a){return g(j[a])?j[a].apply(this,h.call(arguments,1)):e(this,h.call(arguments),d.defaultMethod,j)},k=function(a){a&&(f(i,a.statics),f(j,a.methods)),i.modplug=k};k.prev={statics:c[a],methods:c.fn[a]},k(b),c[a]=i,c.fn[a]=j},H="fracs";G(H,{statics:{version:"0.11",Rect:s,Fractions:t,Group:u,ScrollState:A,Viewport:B,FracsCallbacks:D,GroupCallbacks:E,ScrollStateCallbacks:F,fracs:function(a,b){return t.of(a,b)}},methods:{content:function(a){return this.length?s.ofContent(this[0],a):null},envelope:function(){return p(this,function(a){var b=s.ofElement(this);return a?a.envelope(b):b})},fracs:function(a,b,d){l(a,"string")||(d=b,b=a,a=null),g(b)||(d=b,b=null),d=o(d);var e=H+".fracs."+q(d);return a==="unbind"?this.each(function(){var a=c(this).data(e);a&&a.unbind(b)}):a==="check"?this.each(function(){var a=c(this).data(e);a&&a.check()}):g(b)?this.each(function(){var a=c(this),f=a.data(e);f||(f=new D(this,d),a.data(e,f)),f.bind(b)}):this.length?t.of(this[0],d):null},intersection:function(){return p(this,function(a){var b=s.ofElement(this);return a?a.intersection(b):b})},max:function(a,b,c){return g(b)||(c=b,b=null),c=o(c),b?((new E(this,c,a,!0)).bind(b),this):this.pushStack((new u(this,c)).best(a,!0).el)},min:function(a,b,c){return g(b)||(c=b,b=null),c=o(c),b?((new E(this,c,a)).bind(b),this):this.pushStack((new u(this,c)).best(a).el)},rect:function(){return this.length?s.ofElement(this[0]):null},scrollState:function(a,b){var d=H+".scrollState";return l(a,"string")||(b=a,a=null),a==="unbind"?this.each(function(){var a=c(this).data(d);a&&a.unbind(b)}):a==="check"?this.each(function(){var a=c(this).data(d);a&&a.check()}):g(b)?this.each(function(){var a=c(this),e=a.data(d);e||(e=new F(this),a.data(d,e)),e.bind(b)}):this.length?new A(this[0]):null},scroll:function(a,b,c){return this.each(function(){(new B(this)).scroll(a,b,c)})},scrollTo:function(a,b,d,e){return c.isNumeric(a)&&(e=d,d=b,b=a,a=null),a=o(a),this.each(function(){a?(new B(this)).scrollToElement(a,b,d,e):(new B(this)).scrollTo(b,d,e)})},scrollToThis:function(a,b,c,d){return d=new B(o(d)),d.scrollToElement(this[0],a,b,c),this},softLink:function(a,b,d,e){return e=new B(o(e)),this.filter("a[href^=#]").each(function(){var f=c(this);f.on("click",function(){e.scrollToElement(c(f.attr("href"))[0],a,b,d)})})},sort:function(a,b,d){return l(b,"boolean")||(d=b,b=null),d=o(d),this.pushStack(c.map((new u(this,d)).sorted(a,!b),function(a){return a.el}))},viewport:function(a){return this.length?s.ofViewport(this[0],a):null}},defaultStatic:"fracs",defaultMethod:"fracs"})})(window,document,jQuery) \ No newline at end of file diff --git a/src/_h5ai/js/lib/jquery.qrcode-0.2.min.js b/src/_h5ai/js/lib/jquery.qrcode-0.2.min.js deleted file mode 100644 index 99a664b1..00000000 --- a/src/_h5ai/js/lib/jquery.qrcode-0.2.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery.qrcode 0.2 - //larsjung.de/qrcode - MIT License */ -(function(a){"use strict";var b=function(a,b,c){var d=g(a,b);return d.addData(c),d.make(),d},c=function(a){for(var c=2;c<=40;c+=1)try{return b(c,"L",a)}catch(d){}return null},d=function(b){var d=c(b.text),e=a("").attr("width",b.width).attr("height",b.height),f=e[0].getContext("2d");b.bgColor&&(f.fillStyle=b.bgColor,f.fillRect(0,0,b.width,b.height));if(d){var g=d.getModuleCount(),h=b.width/g,i=b.height/g,j,k;f.beginPath();for(j=0;j").css({position:"relative",left:0,top:0,padding:0,margin:0,width:b.width,height:b.height});b.bgColor&&e.css("background-color",b.bgColor);if(d){var f=d.getModuleCount(),g=Math.floor(b.width/f),h=Math.floor(b.height/f),i=Math.floor(.5*(b.width-g*f)),j=Math.floor(.5*(b.height-h*f)),k,l;for(k=0;k").css({left:i+l*g,top:j+k*h}).appendTo(e);e.children().css({position:"absolute",padding:0,margin:0,width:g,height:h,"background-color":b.color})}return e},f={render:"canvas",width:256,height:256,color:"#000",bgColor:null,text:"no text"};a.fn.qrcode=function(b){var c=a.extend({},f,b);return this.each(function(){a(this).append(c.render==="canvas"?d(c):e(c))})};var g=function(){function g(a,b){if(typeof a.length=="undefined")throw new Error(a.length+"/"+b);var c=function(){var c=0;while(c=7&&x(a),p==null&&(p=B(k,l,q)),z(p,b)},t=function(a,b){for(var c=-1;c<=7;c+=1){if(a+c<=-1||n<=a+c)continue;for(var d=-1;d<=7;d+=1){if(b+d<=-1||n<=b+d)continue;0<=c&&c<=6&&(d==0||d==6)||0<=d&&d<=6&&(c==0||c==6)||2<=c&&c<=4&&2<=d&&d<=4?m[a+c][b+d]=!0:m[a+c][b+d]=!1}}},u=function(){var a=0,b=0;for(var c=0;c<8;c+=1){s(!0,c);var d=e.getLostPoint(r);if(c==0||a>d)a=d,b=c}return b},v=function(){for(var a=8;a>c&1)==1;m[Math.floor(c/3)][c%3+n-8-3]=d}for(var c=0;c<18;c+=1){var d=!a&&(b>>c&1)==1;m[c%3+n-8-3][Math.floor(c/3)]=d}},y=function(a,b){var c=l<<3|b,d=e.getBCHTypeInfo(c);for(var f=0;f<15;f+=1){var g=!a&&(d>>f&1)==1;f<6?m[f][8]=g:f<8?m[f+1][8]=g:m[n-15+f][8]=g}for(var f=0;f<15;f+=1){var g=!a&&(d>>f&1)==1;f<8?m[8][n-f-1]=g:f<9?m[8][15-f-1+1]=g:m[8][15-f-1]=g}m[n-8][8]=!a},z=function(a,b){var c=-1,d=n-1,f=7,g=0,h=e.getMaskFunction(b);for(var i=n-1;i>0;i-=2){i==6&&(i-=1);for(;;){for(var j=0;j<2;j+=1)if(m[d][i-j]==null){var k=!1;g>>f&1)==1);var l=h(d,i-j);l&&(k=!k),m[d][i-j]=k,f-=1,f==-1&&(g+=1,f=7)}d+=c;if(d<0||n<=d){d-=c,c=-c;break}}}},A=function(a,b){var c=0,d=0,f=0,h=new Array(b.length),i=new Array(b.length);for(var j=0;j=0?p.get(q):0}}var r=0;for(var m=0;mm*8)throw new Error("code length overflow. ("+j.getLengthInBits()+">"+m*8+")");j.getLengthInBits()+4<=m*8&&j.put(0,4);while(j.getLengthInBits()%8!=0)j.putBit(!1);for(;;){if(j.getLengthInBits()>=m*8)break;j.put(d,8);if(j.getLengthInBits()>=m*8)break;j.put(f,8)}return A(j,g)};return r.addData=function(a){var b=j(a);q.push(b),p=null},r.isDark=function(a,b){if(a<0||n<=a||b<0||n<=b)throw new Error(a+","+b);return m[a][b]},r.getModuleCount=function(){return n},r.make=function(){s(!1,u())},r.createTableTag=function(a,b){a=a||2,b=typeof b=="undefined"?a*4:b;var c="";c+='
          ";for(var e=0;e';c+=""}return c+="",c+="
          ",c},r.createImgTag=function(a,b){a=a||2,b=typeof b=="undefined"?a*4:b;var c=r.getModuleCount()*a+b*2,d=b,e=c-b;return o(c,c,function(b,c){if(d<=b&&b>>8),b.push(g&255)):b.push(d)}}return b}};var b={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},c={L:1,M:0,Q:3,H:2},d={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7},e=function(){var a=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],c=1335,e=7973,h=21522,i={},j=function(a){var b=0;while(a!=0)b+=1,a>>>=1;return b};return i.getBCHTypeInfo=function(a){var b=a<<10;while(j(b)-j(c)>=0)b^=c<=0)b^=e<5&&(c+=3+f-5)}for(var d=0;d=256)b-=255;return a[b]},d}(),h=function(){var a=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],b=function(a,b){var c={};return c.totalCount=a,c.dataCount=b,c},d={},e=function(b,d){switch(d){case c.L:return a[(b-1)*4+0];case c.M:return a[(b-1)*4+1];case c.Q:return a[(b-1)*4+2];case c.H:return a[(b-1)*4+3];default:return undefined}};return d.getRSBlocks=function(a,c){var d=e(a,c);if(typeof d=="undefined")throw new Error("bad rs block @ typeNumber:"+a+"/errorCorrectLevel:"+c);var f=d.length/3,g=new Array;for(var h=0;h>>7-b%8&1)==1},c.put=function(a,b){for(var d=0;d>>b-d-1&1)==1)},c.getLengthInBits=function(){return b},c.putBit=function(c){var d=Math.floor(b/8);a.length<=d&&a.push(0),c&&(a[d]|=128>>>b%8),b+=1},c},j=function(c){var d=b.MODE_8BIT_BYTE,e=c,f=a.stringToBytes(c),g={};return g.getMode=function(){return d},g.getLength=function(a){return f.length},g.write=function(a){for(var b=0;b>>8)},b.writeBytes=function(a,c,d){c=c||0,d=d||a.length;for(var e=0;e0&&(b+=","),b+=a[c];return b+="]",b},b},l=function(){var a=0,b=0,c=0,d="",e={},f=function(a){d+=String.fromCharCode(g(a&63))},g=function(a){if(!(a<0)){if(a<26)return 65+a;if(a<52)return 97+(a-26);if(a<62)return 48+(a-52);if(a==62)return 43;if(a==63)return 47}throw new Error("n:"+a)};return e.writeByte=function(d){a=a<<8|d&255,b+=8,c+=1;while(b>=6)f(a>>>b-6),b-=6},e.flush=function(){b>0&&(f(a<<6-b),a=0,b=0);if(c%3!=0){var e=3-c%3;for(var g=0;g=b.length){if(e==0)return-1;throw new Error("unexpected end of file./"+e)}var a=b.charAt(c);c+=1;if(a=="=")return e=0,-1;if(a.match(/^\s$/))continue;d=d<<6|g(a.charCodeAt(0)),e+=6}var f=d>>>e-8&255;return e-=8,f};var g=function(a){if(65<=a&&a<=90)return a-65;if(97<=a&&a<=122)return a-97+26;if(48<=a&&a<=57)return a-48+52;if(a==43)return 62;if(a==47)return 63;throw new Error("c:"+a)};return f},n=function(a,b){var c=a,d=b,e=new Array(a*b),f={};f.setPixel=function(a,b,d){e[b*c+a]=d},f.write=function(a){a.writeString("GIF87a"),a.writeShort(c),a.writeShort(d),a.writeByte(128),a.writeByte(0),a.writeByte(0),a.writeByte(0),a.writeByte(0),a.writeByte(0),a.writeByte(255),a.writeByte(255),a.writeByte(255),a.writeString(","),a.writeShort(0),a.writeShort(0),a.writeShort(c),a.writeShort(d),a.writeByte(0);var b=2,e=h(b);a.writeByte(b);var f=0;while(e.length-f>255)a.writeByte(255),a.writeBytes(e,f,255),f+=255;a.writeByte(e.length-f),a.writeBytes(e,f,e.length-f),a.writeByte(0),a.writeString(";")};var g=function(a){var b=a,c=0,d=0,e={};return e.write=function(a,e){if(a>>>e!=0)throw new Error("length over");while(c+e>=8)b.writeByte(255&(a<>>=8-c,d=0,c=0;d=a<0&&b.writeByte(d)},e},h=function(a){var b=1<'),e.$thumb=a('
          ').appendTo(e.$scrollbar),e.$el.addClass(f+"host").wrapInner('
          ').append(e.$scrollbar),e.$viewport=e.$el.find("> ."+f+"viewport"),e.$container=e.$viewport.find("> ."+f+"container"),e.$el.on("mousewheel",function(a,b,c,d){e.$viewport.scrollTop(e.$viewport.scrollTop()-50*d),e.update(),a.preventDefault(),a.stopPropagation()}).on("scroll",function(){e.update()}),e.$viewport.css({paddingRight:e.$scrollbar.outerWidth(!0),height:e.$el.height(),overflow:"hidden"}),e.$container.css({overflow:"hidden"}),e.$scrollbar.css({position:"absolute",top:0,right:0,overflow:"hidden"}).on("mousedown",function(a){e.mouseOffsetY=e.$thumb.outerHeight()/2,e.onMousedown(a)}).each(function(){e.onselectstart=function(){return!1}}),e.$thumb.css({position:"absolute",left:0,width:"100%"}).on("mousedown",function(a){e.mouseOffsetY=a.pageY-e.$thumb.offset().top,e.onMousedown(a)}),e.update()};a.extend(e.prototype,{update:function(a){var b=this;b.updateId&&!a?(clearInterval(b.updateId),b.updateId=0):!b.updateId&&a&&(b.updateId=setInterval(function(){b.update(!0)},50)),b.$viewport.css("height",b.$el.height());var c=b.$el.height(),d=b.$container.outerHeight(),e=b.$viewport.scrollTop(),f=e/d,g=Math.min(c/d,1),h=b.$scrollbar.height();g<1?(b.$scrollbar.css({height:b.$el.innerHeight()+h-b.$scrollbar.outerHeight(!0)}).fadeIn(50),b.$thumb.css({top:h*f,height:h*g})):b.$scrollbar.fadeOut(50)},scroll:function(a){var b=this,c=(a.pageY-b.$scrollbar.offset().top-b.mouseOffsetY)/b.$scrollbar.height();b.$viewport.scrollTop(b.$container.outerHeight()*c),b.update(),a.preventDefault(),a.stopPropagation()},onMousedown:function(a){var c=this;c.scroll(a),c.$scrollbar.addClass("active"),b.on("mousemove",c.scrollProxy).one("mouseup",function(a){c.$scrollbar.removeClass("active"),b.off("mousemove",c.scrollProxy),c.scroll(a)})}}),a.fn[c]=function(b,d){return this.each(function(){var f=a(this),g=f.data(c);g||(g=new e(this,b),g.update(),f.data(c,g)),b==="update"&&g.update(d)})}})(jQuery) \ No newline at end of file diff --git a/src/_h5ai/js/lib/modernizr-2.6.1.min.js b/src/_h5ai/js/lib/modernizr-2.6.1.min.js deleted file mode 100644 index 4ccdbe86..00000000 --- a/src/_h5ai/js/lib/modernizr-2.6.1.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/* Modernizr 2.6.1 (Custom Build) | MIT & BSD - * Build: http://modernizr.com/download/#-opacity-rgba-canvas-history-audio-video-shiv-cssclasses-prefixes - */ -;window.Modernizr=function(a,b,c){function v(a){j.cssText=a}function w(a,b){return v(m.join(a+";")+(b||""))}function x(a,b){return typeof a===b}function y(a,b){return!!~(""+a).indexOf(b)}function z(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:x(f,"function")?f.bind(d||b):f}return!1}var d="2.6.1",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m=" -webkit- -moz- -o- -ms- ".split(" "),n={},o={},p={},q=[],r=q.slice,s,t={}.hasOwnProperty,u;!x(t,"undefined")&&!x(t.call,"undefined")?u=function(a,b){return t.call(a,b)}:u=function(a,b){return b in a&&x(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=r.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(r.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(r.call(arguments)))};return e}),n.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},n.history=function(){return!!a.history&&!!history.pushState},n.rgba=function(){return v("background-color:rgba(150,255,150,.5)"),y(j.backgroundColor,"rgba")},n.opacity=function(){return w("opacity:.55"),/^0.55$/.test(j.opacity)},n.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},n.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c};for(var A in n)u(n,A)&&(s=A.toLowerCase(),e[s]=n[A](),q.push((e[s]?"":"no-")+s));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)u(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},v(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=m,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+q.join(" "):""),e}(this,this.document); \ No newline at end of file diff --git a/src/_h5ai/js/lib/sh/shAutoloader.js b/src/_h5ai/js/lib/sh/shAutoloader.js deleted file mode 100644 index 4e29bdde..00000000 --- a/src/_h5ai/js/lib/sh/shAutoloader.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * SyntaxHighlighter - * http://alexgorbatchev.com/SyntaxHighlighter - * - * SyntaxHighlighter is donationware. If you are using it, please donate. - * http://alexgorbatchev.com/SyntaxHighlighter/donate.html - * - * @version - * 3.0.83 (July 02 2010) - * - * @copyright - * Copyright (C) 2004-2010 Alex Gorbatchev. - * - * @license - * Dual licensed under the MIT and GPL licenses. - */ -eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(2(){1 h=5;h.I=2(){2 n(c,a){4(1 d=0;d35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('3 u={8:{}};u.8={A:4(c,k,l,m,n,o){4 d(a,b){2 a!=1?a:b}4 f(a){2 a!=1?a.E():1}c=c.I(":");3 g=c[0],e={};t={"r":K};M=1;5=8.5;9(3 j R c)e[c[j]]="r";k=f(d(k,5.C));l=f(d(l,5.D));m=f(d(m,5.s));o=f(d(o,5.Q));n=f(d(n,5["x-y"]));2{P:g,C:d(t[e.O],k),D:d(t[e.N],l),s:d({"r":r}[e.s],m),"x-y":d(4(a,b){9(3 h=T S("^"+b+"\\\\[(?\\\\w+)\\\\]$","U"),i=1,p=0;p>1):c.left+e)+"px",top:(c.top=="auto"?i.y-h.y+(a.offsetHeight>>1):c.top+e)+"px"})),d.setAttribute("aria-role","progressbar"),b.lines(d,b.opts);if(!f){var j=0,k=c.fps,m=k/c.speed,o=(1-c.opacity)/(m*c.trail/100),p=m/c.lines;!function q(){j++;for(var a=c.lines;a;a--){var e=Math.max(1-(j+a*p)%m*o,c.opacity);b.opacity(d,c.lines-a,e,c)}b.timeout=b.el&&setTimeout(q,~~(1e3/k))}()}return b},stop:function(){var a=this.el;return a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=c),this},lines:function(a,b){function e(a,d){return l(g(),{position:"absolute",width:b.length+b.width+"px",height:b.width+"px",background:a,boxShadow:d,transformOrigin:"left",transform:"rotate("+~~(360/b.lines*c+b.rotate)+"deg) translate("+b.radius+"px"+",0)",borderRadius:(b.width>>1)+"px"})}var c=0,d;for(;c',b)}var b=l(g("group"),{behavior:"url(#default#VML)"});!k(b,"transform")&&b.adj?(i.addRule(".spin-vml","behavior:url(#default#VML)"),p.prototype.lines=function(b,c){function f(){return l(a("group",{coordsize:e+" "+e,coordorigin:-d+" "+ -d}),{width:e,height:e})}function k(b,e,g){h(i,h(l(f(),{rotation:360/c.lines*b+"deg",left:~~e}),h(l(a("roundrect",{arcsize:1}),{width:d,height:c.width,left:c.radius,top:-c.width>>1,filter:g}),a("fill",{color:c.color,opacity:c.opacity}),a("stroke",{opacity:0}))))}var d=c.length+c.width,e=2*d,g=-(c.width+c.length)*2+"px",i=l(f(),{position:"absolute",top:g,left:g}),j;if(c.shadow)for(j=1;j<=c.lines;j++)k(j,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(j=1;j<=c.lines;j++)k(j);return h(b,i)},p.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+dgetOptions(); - - -function json_exit($obj) { - - $obj["code"] = 0; - echo json_encode($obj); - exit; -} - -function json_fail($code, $msg = "", $cond = true) { - - if ($cond) { - echo json_encode(array("code" => $code, "msg" => $msg)); - exit; - } -} - -function check_keys($keys) { - $values = array(); - foreach ($keys as $key) { - json_fail(101, "parameter '$key' is missing", !array_key_exists($key, $_REQUEST)); - $values[] = $_REQUEST[$key]; - } - return $values; -} - - -list($action) = check_keys(array("action")); - - -if ($action === "getthumbsrc") { - - if (!$options["thumbnails"]["enabled"]) { - json_fail(1, "thumbnails disabled"); - } - - H5ai::req_once("/php/inc/Thumb.php"); - if (!Thumb::is_supported()) { - json_fail(2, "thumbnails not supported"); - } - - list($type, $srcAbsHref, $mode, $width, $height) = check_keys(array("type", "href", "mode", "width", "height")); - - $thumb = new Thumb($h5ai); - $thumbHref = $thumb->thumb($type, $srcAbsHref, $mode, $width, $height); - if ($thumbHref === null) { - json_fail(3, "thumbnail creation failed"); - } - - json_exit(array("absHref" => $thumbHref)); -} - - -else if ($action === "archive") { - - json_fail(1, "downloads disabled", !$options["download"]["enabled"]); - - list($execution, $format, $hrefs) = check_keys(array("execution", "format", "hrefs")); - - H5ai::req_once("/php/inc/Archive.php"); - $archive = new Archive($h5ai); - - $hrefs = explode(":", trim($hrefs)); - $target = $archive->create($execution, $format, $hrefs); - - if (!is_string($target)) { - json_fail($target, "package creation failed"); - } - - json_exit(array("id" => basename($target), "size" => filesize($target))); -} - - -else if ($action === "getarchive") { - - json_fail(1, "downloads disabled", !$options["download"]["enabled"]); - - list($id, $as) = check_keys(array("id", "as")); - json_fail(2, "file not found", !preg_match("/^h5ai-selection-/", $id)); - - $target = H5ai::normalize_path(sys_get_temp_dir(), true) . $id; - json_fail(3, "file not found", !file_exists($target)); - - header("Content-Type: application/octet-stream"); - header("Content-Length: " . filesize($target)); - header("Content-Disposition: attachment; filename=\"$as\""); - header("Connection: close"); - readfile($target); -} - - -else if ($action === "getchecks") { - - $php = version_compare(PHP_VERSION, "5.2.1") >= 0; - $archive = class_exists("PharData"); - $gd = false; - if (function_exists("gd_info")) { - $gdinfo = gd_info(); - $gd = array_key_exists("JPG Support", $gdinfo) && $gdinfo["JPG Support"] || array_key_exists("JPEG Support", $gdinfo) && $gdinfo["JPEG Support"]; - } - $cache = is_writable($h5ai->getH5aiAbsPath() . "/cache"); - $temp = is_writable(sys_get_temp_dir()); - $tar = preg_match("/tar$/", `which tar`) > 0; - $zip = preg_match("/zip$/", `which zip`) > 0; - $convert = preg_match("/convert$/", `which convert`) > 0; - $ffmpeg = preg_match("/ffmpeg$/", `which ffmpeg`) > 0; - $du = preg_match("/du$/", `which du`) > 0; - - json_exit(array( - "php" => $php, - "cache" => $cache, - "thumbs" => $gd, - "temp" => $temp, - "archive" => $archive, - "tar" => $tar, - "zip" => $zip, - "convert" => $convert, - "ffmpeg" => $ffmpeg, - "du" => $du - )); -} - - -else if ($action === "getentries") { - - list($href, $content) = check_keys(array("href", "content")); - - $content = intval($content, 10); - - json_exit(array("entries" => $h5ai->getEntries($href, $content))); -} - - -else { - json_fail(100, "unsupported action"); -} - - -?> \ No newline at end of file diff --git a/src/_h5ai/php/h5ai-index.php b/src/_h5ai/php/h5ai-index.php deleted file mode 100644 index 75303370..00000000 --- a/src/_h5ai/php/h5ai-index.php +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - Directory index · styled with h5ai - - - - - - - - - -
          - -
          -
          -
          -
          -
          - - h5ai {{version}} - ⚡ JavaScript is disabled! ⚡ - ⚡ Some features disabled! Works best in modern browsers. ⚡ - - - -
          - -
          - getNoJsFallback(); - } ?> -
          - - - - \ No newline at end of file diff --git a/src/_h5ai/php/inc/Archive.php b/src/_h5ai/php/inc/Archive.php deleted file mode 100644 index 159e00a4..00000000 --- a/src/_h5ai/php/inc/Archive.php +++ /dev/null @@ -1,131 +0,0 @@ -h5ai = $h5ai; - } - - - public function create($execution, $format, $hrefs) { - - $this->dirs = array(); - $this->files = array(); - $this->sc401 = false; - - $this->add_hrefs($hrefs); - - if ($this->sc401) { - return 401; - } else if (count($this->dirs) === 0 && count($this->files) === 0) { - return 404; - } - - $target = H5ai::normalize_path(sys_get_temp_dir(), true) . "h5ai-selection-" . microtime(true) . rand() . "." . $format; - - try { - if ($execution === "shell") { - - if ($format === "tar") { - $cmd = Archive::$TAR_CMD; - } else if ($format === "zip") { - $cmd = Archive::$ZIP_CMD; - } else { - return null; - } - $cmd = str_replace("[ROOTDIR]", "\"" . $this->h5ai->getRootAbsPath() . "\"", $cmd); - $cmd = str_replace("[TARGET]", "\"" . $target . "\"", $cmd); - $cmd = str_replace("[DIRS]", count($this->dirs) ? "\"" . implode("\" \"", array_values($this->dirs)) . "\"" : "", $cmd); - $cmd = str_replace("[FILES]", count($this->files) ? "\"" . implode("\" \"", array_values($this->files)) . "\"" : "", $cmd); - - `$cmd`; - - } else if ($execution === "php") { - - $archive = new PharData($target); - foreach ($this->dirs as $archivedDir) { - $archive->addEmptyDir($archivedDir); - } - foreach ($this->files as $realFile => $archivedFile) { - $archive->addFile($realFile, $archivedFile); // very, very slow :/ - } - - } - } catch (Exeption $err) { - return 500; - } - - return @filesize($target) ? $target : null; - } - - - private function add_hrefs($hrefs) { - - foreach ($hrefs as $href) { - - $d = H5ai::normalize_path(dirname($href), true); - $n = basename($href); - - $code = $this->h5ai->getHttpCode($d); - if ($code == 401) { - $this->sc401 = true; - } - - if ($code == "h5ai" && !$this->h5ai->is_ignored($n)) { - - $realFile = $this->h5ai->getAbsPath($href); - $archivedFile = preg_replace("!^" . H5ai::normalize_path($this->h5ai->getRootAbsPath(), true) . "!", "", $realFile); - - if (is_dir($realFile)) { - $this->add_dir($realFile, $archivedFile); - } else { - $this->add_file($realFile, $archivedFile); - } - } - } - } - - - private function add_file($realFile, $archivedFile) { - - if (is_readable($realFile)) { - $this->files[$realFile] = $archivedFile; - } - } - - - private function add_dir($realDir, $archivedDir) { - - $code = $this->h5ai->getHttpCode($this->h5ai->getAbsHref($realDir)); - if ($code == 401) { - $this->sc401 = true; - } - - if ($code == "h5ai") { - $this->dirs[] = $archivedDir; - - $files = $this->h5ai->read_dir($realDir); - foreach ($files as $file) { - - $realFile = $realDir . "/" . $file; - $archivedFile = $archivedDir . "/" . $file; - - if (is_dir($realFile)) { - $this->add_dir($realFile, $archivedFile); - } else { - $this->add_file($realFile, $archivedFile); - } - } - } - } -} - -?> \ No newline at end of file diff --git a/src/_h5ai/php/inc/Entry.php b/src/_h5ai/php/inc/Entry.php deleted file mode 100644 index 85101309..00000000 --- a/src/_h5ai/php/inc/Entry.php +++ /dev/null @@ -1,119 +0,0 @@ -absHref, $entry2->absHref); - } - - uasort(Entry::$cache, "cmp"); - } - - - - - public $h5ai, $absPath, $absHref, $date, $size, $isFolder, $parent, $isContentFetched; - - - private function __construct($h5ai, $absPath, $absHref) { - - $this->h5ai = $h5ai; - - $this->absPath = H5ai::normalize_path($absPath); - - $this->isFolder = is_dir($this->absPath); - $this->absHref = H5ai::normalize_path($absHref, $this->isFolder); - - $this->date = filemtime($this->absPath); - - if ($this->isFolder) { - $this->size = null; - $options = $h5ai->getOptions(); - if ($options["foldersize"]["enabled"]) { - $cmd = str_replace("[DIR]", $this->absPath, Entry::$FOLDER_SIZE_CMD); - $this->size = intval(preg_replace("/\s.*$/", "", `$cmd`), 10); - } - } else { - $this->size = filesize($this->absPath); - } - - $this->parent = null; - if ($this->absHref !== "/") { - $this->parent = Entry::get($this->h5ai, H5ai::normalize_path(dirname($this->absPath)), H5ai::normalize_path(dirname($this->absHref), true)); - } - - $this->isContentFetched = false; - - Entry::$cache[$this->absHref] = $this; - } - - - public function toJsonObject($withStatus) { - - $obj = array( - "absHref" => $this->absHref, - "time" => ($this->date * 1000), - "size" => $this->size - ); - - if ($withStatus && $this->isFolder) { - $obj["status"] = $this->h5ai->getHttpCode($this->absHref); - $obj["content"] = $this->isContentFetched; - } - - return $obj; - } - - - public function getParent() { - - return $this->parent; - } - - - public function getContent() { - - $content = array(); - - if ($this->h5ai->getHttpCode($this->absHref) !== "h5ai") { - return $content; - } - - $files = $this->h5ai->read_dir($this->absPath); - foreach ($files as $file) { - $entry = Entry::get($this->h5ai, $this->absPath . "/" . $file, $this->absHref . rawurlencode($file)); - $content[$entry->absPath] = $entry; - } - - $this->isContentFetched = true; - - return $content; - } -} - -?> \ No newline at end of file diff --git a/src/_h5ai/php/inc/H5ai.php b/src/_h5ai/php/inc/H5ai.php deleted file mode 100644 index 470c779b..00000000 --- a/src/_h5ai/php/inc/H5ai.php +++ /dev/null @@ -1,336 +0,0 @@ -requested_from = H5ai::normalize_path($requested_from); - - $this->h5aiAbsPath = H5ai::normalize_path(H5AI_ABS_PATH); - - global $H5AI_CONFIG; - $this->rootAbsPath = H5ai::normalize_path($H5AI_CONFIG["ROOT_ABS_PATH"]); - $this->ignore_names = $H5AI_CONFIG["IGNORE"]; - $this->ignore_patterns = $H5AI_CONFIG["IGNORE_PATTERNS"]; - $this->index_files = $H5AI_CONFIG["INDEX_FILES"]; - - $this->config = H5ai::load_config($this->h5aiAbsPath . "/config.js"); - $this->options = $this->config["options"]; - - $this->rootAbsHref = H5ai::normalize_path($this->options["rootAbsHref"], true); - $this->h5aiAbsHref = H5ai::normalize_path($this->options["h5aiAbsHref"], true); - - $this->absHref = H5ai::normalize_path(preg_replace('/[^\\/]*$/', '', getenv("REQUEST_URI")), true); - $this->absPath = $this->getAbsPath($this->absHref); - } - - - public function getRootAbsPath() { - - return $this->rootAbsPath; - } - - - public function getH5aiAbsPath() { - - return $this->h5aiAbsPath; - } - - - public function getRootAbsHref() { - - return $this->rootAbsHref; - } - - - public function getH5aiAbsHref() { - - return $this->h5aiAbsHref; - } - - - public function getOptions() { - - return $this->options; - } - - - public function getAbsHref($absPath = null, $endWithSlash = true) { - - if ($absPath === null) { - return $this->absHref; - } - - $absPath = substr($absPath, strlen($this->rootAbsPath)); - - $parts = explode("/", $absPath); - $encodedParts = array(); - foreach ($parts as $part) { - $encodedParts[] = rawurlencode($part); - } - - return H5ai::normalize_path($this->rootAbsHref . implode("/", $encodedParts), $endWithSlash); - } - - - public function getAbsPath($absHref = null) { - - if ($absHref === null) { - return $this->absPath; - } - - $absHref = substr($absHref, strlen($this->rootAbsHref)); - - return H5ai::normalize_path($this->rootAbsPath . "/" . rawurldecode($absHref)); - } - - - public function is_ignored($name) { - - // always ignore - if ($name === "." || $name === "..") { - return true; - } - - if (in_array($name, $this->ignore_names)) { - return true; - } - foreach ($this->ignore_patterns as $re) { - if (preg_match($re, $name)) { - return true; - } - } - - return false; - } - - - public function read_dir($path) { - - $content = array(); - if (is_dir($path)) { - if ($dir = opendir($path)) { - while (($file = readdir($dir)) !== false) { - if (!$this->is_ignored($file)) { - $content[] = $file; - } - } - closedir($dir); - } - } - return $content; - } - - - public function getHttpCode($absHref) { - - if (!is_dir($this->getAbsPath($absHref))) { - return null; - } - - if ($this->options["folderstatus"]["enabled"]) { - $folders = $this->options["folderstatus"]["folders"]; - if (array_key_exists($absHref, $folders)) { - return $folders[$absHref]; - } - } - - // return $this->fetchHttpCode($absHref); - return $this->guessHttpCode($absHref); - } - - - public function guessHttpCode($absHref) { - - $absPath = $this->getAbsPath($absHref); - - foreach ($this->index_files as $if) { - if (file_exists($absPath . "/" . $if)) { - if ($if === "index.php") { - $fileheader = file_get_contents($absPath . "/" . $if, false, null, -1, 50); - return stripos($fileheader, H5ai::$H5AI_CONTENT_TYPE) === false ? 200 : "h5ai"; - } - return 200; - } - } - return "h5ai"; - } - - - public function fetchHttpCode($absHref) { - - $host = getenv("HTTP_HOST"); - $port = getenv("SERVER_PORT"); - $msg = "HEAD $absHref HTTP/1.1\r\nHost: $host\r\nConnection: Close\r\n"; - if (isset($_SERVER['PHP_AUTH_USER'])) { - $msg .= "Authorization: Basic " . base64_encode($_SERVER['PHP_AUTH_USER'] . ":" . $_SERVER['PHP_AUTH_PW']) . "\r\n"; - } - $msg .= "\r\n"; - - $errno = ""; - $errstr = ""; - $socket = fsockopen($host, $port, $errno, $errstr, 30); - if($socket === 0) { - return null; - } - - fwrite($socket, $msg); - $content = fgets($socket); - $code = intval(trim(substr($content, 9, 4))); - if ($code === 200) { - while ($content !== false && stripos($content, "Content-Type") === false) { - $content = fgets($socket); - } - if (stripos($content, H5ai::$H5AI_CONTENT_TYPE) !== false) { - $code = "h5ai"; - } - } - fclose($socket); - - return $code; - } - - - private function fileExists($file) { - - return is_string($file) && file_exists($file); - } - - - public function getGenericJson() { - - $entries = $this->getEntries($this->absHref, 1); - - $header = $this->options["custom"]["header"]; - $footer = $this->options["custom"]["footer"]; - $header = $this->fileExists($header ? $this->absPath . "/" . $header : null) ? $header : null; - $footer = $this->fileExists($footer ? $this->absPath . "/" . $footer : null) ? $footer : null; - - $json = array( - "entries" => $entries, - "customHeader" => $header, - "customFooter" => $footer, - "mode" => $this->requested_from === $this->h5aiAbsPath . "/php/h5ai-index.php" ? "php" : "idx.php", - "server" => array( - "name" => strtolower(preg_replace("/\\/.*$/", "", getenv("SERVER_SOFTWARE"))), - "version" => strtolower(preg_replace("/^.*\\//", "", preg_replace("/\\s.*$/", "", getenv("SERVER_SOFTWARE")))) - ) - ); - - return json_encode($json) . "\n"; - } - - - public function getEntries($absHref, $content) { - - $folder = Entry::get($this, $this->getAbsPath($absHref), $absHref); - if ($content > 1 && $folder !== null) { - foreach ($folder->getContent() as $entry) { - $entry->getContent(); - } - $folder = $folder->getParent(); - } - while ($content > 0 && $folder !== null) { - $folder->getContent(); - $folder = $folder->getParent(); - } - Entry::sort(); - - $entries = array(); - foreach (Entry::get_cache() as $entry) { - $entries[] = $entry->toJsonObject(true); - } - - return $entries; - } - - - public function getNoJsFallback() { - - date_default_timezone_set ("UTC"); - - function _cmp($entry1, $entry2) { - - if ($entry1->isFolder && !$entry2->isFolder) { - return -1; - } - if (!$entry1->isFolder && $entry2->isFolder) { - return 1; - } - - return strcasecmp($entry1->absHref, $entry2->absHref); - } - - $folder = Entry::get($this, $this->absPath, $this->absHref); - $entries = $folder->getContent(); - uasort($entries, "_cmp"); - - $html = ""; - $html .= ""; - if ($folder->parent) { - $html .= ""; - } - foreach ($entries as $entry) { - $html .= ""; - $html .= ""; - $html .= ""; - $html .= ""; - $html .= ""; - $html .= ""; - } - $html .= "
          NameLast modifiedSize
          Parent Directory
          absHref . "\">" . basename($entry->absPath) . ($entry->isFolder ? "/" : "") . "" . date("Y-m-d H:i", $entry->date) . "" . ($entry->size !== null ? intval($entry->size / 1000) . " KB" : "" ) . "
          "; - - return $html; - } -} - -?> \ No newline at end of file diff --git a/src/_h5ai/apache/autoindex.htaccess b/src/_h5ai/server/aai/aai.htaccess similarity index 64% rename from src/_h5ai/apache/autoindex.htaccess rename to src/_h5ai/server/aai/aai.htaccess index 99595977..497f7381 100644 --- a/src/_h5ai/apache/autoindex.htaccess +++ b/src/_h5ai/server/aai/aai.htaccess @@ -1,15 +1,15 @@ ################################ -# h5ai {{version}} +# {{pkg.name}} {{pkg.version}} # customized .htaccess ################################ Options +Indexes Options +FollowSymLinks -HeaderName /_h5ai/apache/h5ai-header.html -ReadmeName /_h5ai/apache/h5ai-footer.html +HeaderName /_{{pkg.name}}/server/aai/header.html +ReadmeName /_{{pkg.name}}/server/aai/footer.html -IndexIgnore _h5ai* +IndexIgnore _{{pkg.name}}* IndexOptions Charset=UTF-8 IndexOptions FancyIndexing @@ -19,5 +19,5 @@ IndexOptions NameWidth=* IndexOptions SuppressDescription IndexOptions SuppressHTMLPreamble IndexOptions SuppressRules -IndexOptions Type=text/html;h5ai={{version}} +IndexOptions Type=text/html;{{pkg.name}}={{pkg.version}} IndexOptions XHTML diff --git a/src/_h5ai/server/aai/footer.html.jade b/src/_h5ai/server/aai/footer.html.jade new file mode 100644 index 00000000..4b4a411d --- /dev/null +++ b/src/_h5ai/server/aai/footer.html.jade @@ -0,0 +1,3 @@ + +// generated code ends here +|
          diff --git a/src/_h5ai/server/aai/header.html.jade b/src/_h5ai/server/aai/header.html.jade new file mode 100644 index 00000000..29106464 --- /dev/null +++ b/src/_h5ai/server/aai/header.html.jade @@ -0,0 +1,45 @@ + +- var href = "/_{{pkg.name}}/" + +doctype 5 +//if lt IE 9 + +//[if gt IE 8]> +// + +div#topbar.clearfix + ul#navbar + +div#content + div#extended.clearfix + +div#bottombar.clearfix + span.left + a#h5ai-reference( href="{{pkg.url}}", title="{{pkg.name}} · {{pkg.description}}" ) + | {{pkg.name}} {{pkg.version}} + span.hideOnJs.noJsMsg + | ⚡ JavaScript is disabled! ⚡ + span.oldBrowser + | ⚡ Some features disabled! Works best in + a( href="http://browsehappy.com" ) modern browsers + | . ⚡ + span.right + span.center + +|
          +// The following code was generated by Apache's autoindex module. diff --git a/src/_h5ai/server/php/inc/Api.php b/src/_h5ai/server/php/inc/Api.php new file mode 100644 index 00000000..3e66af6c --- /dev/null +++ b/src/_h5ai/server/php/inc/Api.php @@ -0,0 +1,228 @@ +app = $app; + } + + + public function apply() { + + $options = $this->app->get_options(); + + list($action) = use_request_params(array("action")); + + if ($action === "get") { + + $response = array(); + + if (array_key_exists("options", $_REQUEST)) { + + use_request_params("options"); + $response["options"] = $this->app->get_options(); + } + + if (array_key_exists("types", $_REQUEST)) { + + use_request_params("types"); + $response["types"] = $this->app->get_types(); + } + + if (array_key_exists("langs", $_REQUEST)) { + + use_request_params("langs"); + $response["langs"] = $this->app->get_l10n_list(); + } + + if (array_key_exists("l10n", $_REQUEST)) { + + list($iso_codes) = use_request_params("l10nCodes", "l10n"); + $iso_codes = explode(":", $iso_codes); + $response["l10n"] = $this->app->get_l10n($iso_codes); + } + + if (array_key_exists("checks", $_REQUEST)) { + + use_request_params("checks"); + $response["checks"] = $this->app->get_server_checks(); + } + + if (array_key_exists("server", $_REQUEST)) { + + use_request_params("server"); + $response["server"] = $this->app->get_server_details(); + } + + if (array_key_exists("custom", $_REQUEST)) { + + list($abs_href) = use_optional_request_params("customHref", "custom"); + $response["custom"] = $this->app->get_customizations($abs_href); + } + + if (array_key_exists("entries", $_REQUEST)) { + + list($abs_href, $what) = use_optional_request_params("entriesHref", "entriesWhat", "entries"); + $what = is_numeric($what) ? intval($what, 10) : 1; + $response["entries"] = $this->app->get_entries($abs_href, $what); + } + + if (count($_REQUEST)) { + $response["unused"] = $_REQUEST; + } + + json_exit($response); + } + + + else if ($action === "getThumbHref") { + + if (!$options["thumbnails"]["enabled"]) { + json_fail(1, "thumbnails disabled"); + } + + normalized_require_once("/server/php/inc/Thumb.php"); + if (!Thumb::is_supported()) { + json_fail(2, "thumbnails not supported"); + } + + list($type, $src_abs_href, $mode, $width, $height) = use_request_params(array("type", "href", "mode", "width", "height")); + + $thumb = new Thumb($this->app); + $thumb_href = $thumb->thumb($type, $src_abs_href, $mode, $width, $height); + if ($thumb_href === null) { + json_fail(3, "thumbnail creation failed"); + } + + json_exit(array("absHref" => $thumb_href)); + } + + + else if ($action === "createArchive") { + + json_fail(1, "downloads disabled", !$options["download"]["enabled"]); + + list($execution, $format, $hrefs) = use_request_params(array("execution", "format", "hrefs")); + + normalized_require_once("/server/php/inc/Archive.php"); + $archive = new Archive($this->app); + + $hrefs = explode(":", trim($hrefs)); + $target = $archive->create($execution, $format, $hrefs); + + if (!is_string($target)) { + json_fail($target, "package creation failed"); + } + + json_exit(array("id" => basename($target), "size" => filesize($target))); + } + + + else if ($action === "getArchive") { + + json_fail(1, "downloads disabled", !$options["download"]["enabled"]); + + list($id, $as) = use_request_params(array("id", "as")); + json_fail(2, "file not found", !preg_match("/^package-/", $id)); + + $target = $this->app->get_cache_abs_path() . "/" . $id; + json_fail(3, "file not found", !file_exists($target)); + + header("Content-Type: application/octet-stream"); + header("Content-Length: " . filesize($target)); + header("Content-Disposition: attachment; filename=\"$as\""); + header("Connection: close"); + register_shutdown_function("delete_tempfile", $target); + readfile($target); + } + + + else if ($action === "upload") { + + list($href) = use_request_params(array("href")); + + json_fail(1, "wrong HTTP method", strtolower($_SERVER["REQUEST_METHOD"]) !== "post"); + json_fail(2, "something went wrong", !array_key_exists("userfile", $_FILES)); + + $userfile = $_FILES["userfile"]; + + json_fail(3, "something went wrong [" . $userfile["error"] . "]", $userfile["error"] !== 0); + json_fail(4, "folders not supported", file_get_contents($userfile["tmp_name"]) === "null"); + + $upload_dir = $this->app->get_abs_path($href); + $code = $this->app->get_http_code($href); + + json_fail(5, "upload dir no h5ai folder or ignored", $code !== App::$MAGIC_SEQUENCE || $this->app->is_ignored($upload_dir)); + + $dest = $upload_dir . "/" . utf8_encode($userfile["name"]); + + json_fail(6, "already exists", file_exists($dest)); + json_fail(7, "can't move uploaded file", !move_uploaded_file($userfile["tmp_name"], $dest)); + + json_exit(); + } + + + else if ($action === "delete") { + + json_fail(1, "deletion disabled", !$options["delete"]["enabled"]); + + list($hrefs) = use_request_params(array("hrefs")); + + $hrefs = explode(":", trim($hrefs)); + $errors = array(); + + foreach ($hrefs as $href) { + + $d = normalize_path(dirname($href), true); + $n = basename($href); + + $code = $this->app->get_http_code($d); + + if ($code == App::$MAGIC_SEQUENCE && !$this->app->is_ignored($n)) { + + $abs_path = $this->app->get_abs_path($href); + + if (!unlink($abs_path)) { + $errors[] = $href; + } + } + } + + if (count($errors)) { + json_fail(2, "deletion failed for some"); + } else { + json_exit(); + } + } + + + else if ($action === "rename") { + + json_fail(1, "renaming disabled", !$options["rename"]["enabled"]); + + list($href, $name) = use_request_params(array("href", "name")); + + $d = normalize_path(dirname($href), true); + $n = basename($href); + + $code = $this->app->get_http_code($d); + + if ($code == App::$MAGIC_SEQUENCE && !$this->app->is_ignored($n)) { + + $abs_path = $this->app->get_abs_path($href); + $folder = normalize_path(dirname($abs_path)); + + if (!rename($abs_path, $folder . "/" . $name)) { + json_fail(2, "renaming failed"); + } + } + + json_exit(); + } + } +} + +?> \ No newline at end of file diff --git a/src/_h5ai/server/php/inc/App.php b/src/_h5ai/server/php/inc/App.php new file mode 100644 index 00000000..241a195f --- /dev/null +++ b/src/_h5ai/server/php/inc/App.php @@ -0,0 +1,318 @@ +app_abs_path = normalize_path($app_abs_path); + $this->root_abs_path = normalize_path(dirname($this->app_abs_path)); + + $this->app_abs_href = normalize_path($app_abs_href, true); + $this->root_abs_href = normalize_path(dirname($this->app_abs_href), true); + + $this->abs_href = normalize_path($abs_href, true); + $this->abs_path = $this->get_abs_path($this->abs_href); + + $this->options = load_commented_json($this->app_abs_path . "/conf/options.json"); + } + + + public function get_root_abs_path() { + + return $this->root_abs_path; + } + + + public function get_root_abs_href() { + + return $this->root_abs_href; + } + + + public function get_app_abs_href() { + + return $this->app_abs_href; + } + + + public function get_cache_abs_path() { + + return $this->app_abs_path . '/' . App::$CACHE_DIR; + } + + + public function get_cache_abs_href() { + + return $this->app_abs_href . App::$CACHE_DIR . '/'; + } + + + public function get_abs_href($abs_path = null, $trailing_slash = true) { + + if ($abs_path === null) { + return $this->abs_href; + } + + $abs_path = substr($abs_path, strlen($this->root_abs_path)); + + $parts = explode("/", $abs_path); + $encoded_parts = array(); + foreach ($parts as $part) { + if ($part) { + $encoded_parts[] = rawurlencode($part); + } + } + + return normalize_path($this->root_abs_href . implode("/", $encoded_parts), $trailing_slash); + } + + + public function get_abs_path($abs_href = null) { + + if ($abs_href === null) { + return $this->abs_path; + } + + $abs_href = substr($abs_href, strlen($this->root_abs_href)); + + return normalize_path($this->root_abs_path . "/" . rawurldecode($abs_href)); + } + + + public function is_ignored($name) { + + // always ignore + if ($name === "." || $name === "..") { + return true; + } + + foreach ($this->options["view"]["ignore"] as $re) { + $re = App::$RE_DELIMITER . str_replace(App::$RE_DELIMITER, '\\' . App::$RE_DELIMITER, $re) . App::$RE_DELIMITER; + if (preg_match($re, $name)) { + return true; + } + } + + return false; + } + + + public function read_dir($path) { + + $content = array(); + if (is_dir($path)) { + if ($dir = opendir($path)) { + while (($file = readdir($dir)) !== false) { + if (!$this->is_ignored($file) && !$this->is_ignored($this->get_abs_href($path) . $file)) { + $content[] = $file; + } + } + closedir($dir); + } + } + return $content; + } + + + public function get_options() { + + return $this->options; + } + + + public function get_http_code($abs_href) { + + if (!is_dir($this->get_abs_path($abs_href))) { + return 500; + } + + $abs_path = $this->get_abs_path($abs_href); + + foreach ($this->options["view"]["indexFiles"] as $if) { + if (file_exists($abs_path . "/" . $if)) { + return 200; + } + } + return App::$MAGIC_SEQUENCE; + } + + + public function get_generic_json() { + + return json_encode(array("entries" => $this->get_entries($this->abs_href, 1))) . "\n"; + } + + + public function get_entries($abs_href, $what) { + + $cache = array(); + $folder = Entry::get($this, $this->get_abs_path($abs_href), $cache); + + // add content of subfolders + if ($what >= 2 && $folder !== null) { + foreach ($folder->get_content($cache) as $entry) { + $entry->get_content($cache); + } + $folder = $folder->get_parent($cache); + } + + // add content of this folder and all parent folders + while ($what >= 1 && $folder !== null) { + $folder->get_content($cache); + $folder = $folder->get_parent($cache); + } + + uasort($cache, array("Entry", "cmp")); + $result = array(); + foreach ($cache as $p => $entry) { + $result[] = $entry->to_json_object(); + } + + return $result; + } + + + public function get_no_js_fallback() { + + date_default_timezone_set("UTC"); + + $cache = array(); + $folder = Entry::get($this, $this->abs_path, $cache); + $entries = $folder->get_content($cache); + uasort($entries, array("Entry", "cmp")); + + $html = ""; + $html .= ""; + if ($folder->get_parent($cache)) { + $html .= ""; + } + foreach ($entries as $entry) { + $html .= ""; + $html .= ""; + $html .= ""; + $html .= ""; + $html .= ""; + $html .= ""; + } + $html .= "
          NameLast modifiedSize
          app_abs_href . "client/icons/16x16/folder-parent.png\"/>Parent Directory
          app_abs_href . "client/icons/16x16/" . ($entry->is_folder ? "folder" : "default") . ".png\"/>abs_href . "\">" . basename($entry->abs_path) . "" . date("Y-m-d H:i", $entry->date) . "" . ($entry->size !== null ? intval($entry->size / 1000) . " KB" : "" ) . "
          "; + + return $html; + } + + + public function get_types() { + + return load_commented_json($this->app_abs_path . "/conf/types.json"); + } + + + public function get_l10n_list() { + + $langs = array(); + $l10nDir = $this->app_abs_path . "/conf/l10n"; + if (is_dir($l10nDir)) { + if ($dir = opendir($l10nDir)) { + while (($file = readdir($dir)) !== false) { + if (ends_with($file, ".json")) { + $translations = load_commented_json($l10nDir . "/" . $file); + $langs[basename($file, ".json")] = $translations["lang"]; + } + } + closedir($dir); + } + } + ksort($langs); + return $langs; + } + + + public function get_l10n($iso_codes) { + + if (!is_array($iso_codes)) { + $iso_codes = func_get_args(); + } + + $result = array(); + foreach ($iso_codes as $iso_code) { + if ($iso_code !== "") { + $file = $this->app_abs_path . "/conf/l10n/" . $iso_code . ".json"; + $result[$iso_code] = load_commented_json($file); + $result[$iso_code]["isoCode"] = $iso_code; + } + } + + return $result; + } + + + public function get_server_checks() { + + $php = version_compare(PHP_VERSION, "5.2.1") >= 0; + $archive = class_exists("PharData"); + $gd = false; + if (function_exists("gd_info")) { + $gdinfo = gd_info(); + $gd = array_key_exists("JPG Support", $gdinfo) && $gdinfo["JPG Support"] || array_key_exists("JPEG Support", $gdinfo) && $gdinfo["JPEG Support"]; + } + $cache = @is_writable($this->get_cache_abs_path()); + $tar = @preg_match("/tar$/", `which tar`) > 0; + $zip = @preg_match("/zip$/", `which zip`) > 0; + $convert = @preg_match("/convert$/", `which convert`) > 0; + $ffmpeg = @preg_match("/ffmpeg$/", `which ffmpeg`) > 0; + $du = @preg_match("/du$/", `which du`) > 0; + + return array( + "php" => $php, + "cache" => $cache, + "thumbs" => $gd, + "archive" => $archive, + "tar" => $tar, + "zip" => $zip, + "convert" => $convert, + "ffmpeg" => $ffmpeg, + "du" => $du + ); + } + + + public function get_server_details() { + + return array( + "backend" => "php", + "api" => true, + "name" => strtolower(preg_replace("/\\/.*$/", "", getenv("SERVER_SOFTWARE"))), + "version" => strtolower(preg_replace("/^.*\\//", "", preg_replace("/\\s.*$/", "", getenv("SERVER_SOFTWARE")))) + ); + } + + + public function get_customizations($abs_href) { + + $abs_path = $this->get_abs_path($abs_href); + + $file = $abs_path . "/" . App::$FILE_PREFIX . ".header.html"; + $header = is_string($file) && file_exists($file) ? file_get_contents($file) : null; + $file = $abs_path . "/" . App::$FILE_PREFIX . ".footer.html"; + $footer = is_string($file) && file_exists($file) ? file_get_contents($file) : null; + + return array( + "header" => $header, + "footer" => $footer + ); + } +} + +?> \ No newline at end of file diff --git a/src/_h5ai/server/php/inc/Archive.php b/src/_h5ai/server/php/inc/Archive.php new file mode 100644 index 00000000..2d6ab6fc --- /dev/null +++ b/src/_h5ai/server/php/inc/Archive.php @@ -0,0 +1,124 @@ +app = $app; + } + + + public function create($execution, $format, $hrefs) { + + $this->dirs = array(); + $this->files = array(); + + $this->add_hrefs($hrefs); + + if (count($this->dirs) === 0 && count($this->files) === 0) { + return 404; + } + + $target = $this->app->get_cache_abs_path() . "/package-" . sha1(microtime(true) . rand()) . "." . $format; + + try { + if ($execution === "shell") { + + if ($format === "tar") { + $cmd = Archive::$TAR_CMD; + } else if ($format === "zip") { + $cmd = Archive::$ZIP_CMD; + } else { + return null; + } + // $cmd = str_replace("[ROOTDIR]", "\"" . $this->app->get_root_abs_path() . "\"", $cmd); + $cmd = str_replace("[ROOTDIR]", "\"" . $this->app->get_abs_path() . "\"", $cmd); + $cmd = str_replace("[TARGET]", "\"" . $target . "\"", $cmd); + $cmd = str_replace("[DIRS]", count($this->dirs) ? "\"" . implode("\" \"", array_values($this->dirs)) . "\"" : "", $cmd); + $cmd = str_replace("[FILES]", count($this->files) ? "\"" . implode("\" \"", array_values($this->files)) . "\"" : "", $cmd); + + shell_exec($cmd); + + } else if ($execution === "php") { + + $archive = new PharData($target); + foreach ($this->dirs as $archived_dir) { + $archive->addEmptyDir($archived_dir); + } + foreach ($this->files as $real_file => $archived_file) { + $archive->addFile($real_file, $archived_file); // very, very slow :/ + } + + } + } catch (Exeption $err) { + return 500; + } + + return @filesize($target) ? $target : null; + } + + + private function add_hrefs($hrefs) { + + foreach ($hrefs as $href) { + + $d = normalize_path(dirname($href), true); + $n = basename($href); + + $code = $this->app->get_http_code($d); + + if ($code == App::$MAGIC_SEQUENCE && !$this->app->is_ignored($n)) { + + $real_file = $this->app->get_abs_path($href); + // $archived_file = preg_replace("!^" . normalize_path($this->app->get_root_abs_path(), true) . "!", "", $real_file); + $archived_file = preg_replace("!^" . normalize_path($this->app->get_abs_path(), true) . "!", "", $real_file); + + if (is_dir($real_file)) { + $this->add_dir($real_file, $archived_file); + } else { + $this->add_file($real_file, $archived_file); + } + } + } + } + + + private function add_file($real_file, $archived_file) { + + if (is_readable($real_file)) { + $this->files[$real_file] = $archived_file; + } + } + + + private function add_dir($real_dir, $archived_dir) { + + $code = $this->app->get_http_code($this->app->get_abs_href($real_dir)); + + if ($code == App::$MAGIC_SEQUENCE) { + $this->dirs[] = $archived_dir; + + $files = $this->app->read_dir($real_dir); + foreach ($files as $file) { + + $real_file = $real_dir . "/" . $file; + $archived_file = $archived_dir . "/" . $file; + + if (is_dir($real_file)) { + $this->add_dir($real_file, $archived_file); + } else { + $this->add_file($real_file, $archived_file); + } + } + } + } +} + +?> \ No newline at end of file diff --git a/src/_h5ai/server/php/inc/Entry.php b/src/_h5ai/server/php/inc/Entry.php new file mode 100644 index 00000000..580058a0 --- /dev/null +++ b/src/_h5ai/server/php/inc/Entry.php @@ -0,0 +1,118 @@ +is_folder && !$entry2->is_folder) { + return -1; + } + if (!$entry1->is_folder && $entry2->is_folder) { + return 1; + } + + return strcasecmp($entry1->abs_path, $entry2->abs_path); + } + + public static function get($app, $abs_path, &$cache) { + + if (!starts_with($abs_path, $app->get_root_abs_path())) { + error_log("ILLEGAL REQUEST: " . $abs_path . ", " . $app->get_root_abs_path()); + return null; + } + + if (is_array($cache) && array_key_exists($abs_path, $cache)) { + return $cache[$abs_path]; + } + + $entry = new Entry($app, $abs_path); + + if (is_array($cache)) { + $cache[$abs_path] = $entry; + } + return $entry; + } + + + public $app, + $abs_path, $abs_href, + $date, $size, + $is_folder, + $is_content_fetched; + + + private function __construct($app, $abs_path) { + + $this->app = $app; + + $this->abs_path = normalize_path($abs_path); + $this->is_folder = is_dir($this->abs_path); + $this->abs_href = $this->app->get_abs_href($abs_path, $this->is_folder); + + $this->date = @filemtime($this->abs_path); + + if ($this->is_folder) { + $this->size = null; + $options = $app->get_options(); + if ($options["foldersize"]["enabled"]) { + $cmd = str_replace("[DIR]", $this->abs_path, Entry::$FOLDER_SIZE_CMD); + $this->size = intval(preg_replace("/\s.*$/", "", `$cmd`), 10); + } + } else { + $this->size = @filesize($this->abs_path); + } + + $this->is_content_fetched = false; + } + + + public function to_json_object() { + + $obj = array( + "absHref" => $this->abs_href, + "time" => $this->date * 1000, // seconds (PHP) to milliseconds (JavaScript) + "size" => $this->size + ); + + if ($this->is_folder) { + $obj["status"] = $this->app->get_http_code($this->abs_href); + $obj["content"] = $this->is_content_fetched; + } + + return $obj; + } + + + public function get_parent(&$cache) { + + $parent_abs_path = normalize_path(dirname($this->abs_path)); + if (starts_with($parent_abs_path, $this->app->get_root_abs_path())) { + return Entry::get($this->app, $parent_abs_path, $cache); + } + return null; + } + + + public function get_content(&$cache) { + + $content = array(); + + if ($this->app->get_http_code($this->abs_href) !== App::$MAGIC_SEQUENCE) { + return $content; + } + + $files = $this->app->read_dir($this->abs_path); + foreach ($files as $file) { + $entry = Entry::get($this->app, $this->abs_path . "/" . $file, $cache); + $content[$entry->abs_path] = $entry; + } + + $this->is_content_fetched = true; + + return $content; + } +} + +?> \ No newline at end of file diff --git a/src/_h5ai/php/inc/Thumb.php b/src/_h5ai/server/php/inc/Thumb.php similarity index 61% rename from src/_h5ai/php/inc/Thumb.php rename to src/_h5ai/server/php/inc/Thumb.php index 667d206f..08a04441 100644 --- a/src/_h5ai/php/inc/Thumb.php +++ b/src/_h5ai/server/php/inc/Thumb.php @@ -2,8 +2,8 @@ class Thumb { - private static $FFMPEG = "ffmpeg -i \"[SOURCE]\" -an -ss 3 -vframes 1 \"[TARGET]\""; - private static $CONVERT = "convert -strip \"[SOURCE][0]\" \"[TARGET]\""; + private static $FFMPEG_CMD = "ffmpeg -i \"[SOURCE]\" -an -ss 3 -vframes 1 \"[TARGET]\""; + private static $CONVERT_CMD = "convert -strip \"[SOURCE][0]\" \"[TARGET]\""; public static final function is_supported() { @@ -16,71 +16,67 @@ class Thumb { } - private $h5ai; + private $app; - public function __construct($h5ai) { + public function __construct($app) { - $this->h5ai = $h5ai; + $this->app = $app; } - public function thumb($type, $sourceAbsHref, $mode, $width, $height) { + public function thumb($type, $source_abs_href, $mode, $width, $height) { - $sourceAbsPath = $this->h5ai->getAbsPath($sourceAbsHref); + $source_abs_path = $this->app->get_abs_path($source_abs_href); if ($type === "img") { - $captureAbsPath = $sourceAbsPath; + $capture_abs_path = $source_abs_path; } else if ($type === "mov") { - $captureAbsPath = $this->capture(Thumb::$FFMPEG, $sourceAbsPath); + $capture_abs_path = $this->capture(Thumb::$FFMPEG_CMD, $source_abs_path); } else if ($type === "doc") { - $captureAbsPath = $this->capture(Thumb::$CONVERT, $sourceAbsPath); + $capture_abs_path = $this->capture(Thumb::$CONVERT_CMD, $source_abs_path); } - return $this->thumb_href($captureAbsPath, $mode, $width, $height); + return $this->thumb_href($capture_abs_path, $mode, $width, $height); } - private function thumb_href($sourceAbsPath, $mode, $width, $height) { + private function thumb_href($source_abs_path, $mode, $width, $height) { - if (!file_exists($sourceAbsPath)) { + if (!file_exists($source_abs_path)) { return null; } - $name = "cache/thumb-" . sha1("$sourceAbsPath-$width-$height-$mode") . ".jpg"; - // $name = "cache/thumb-" . sha1("$sourceAbsPath-$width-$height-$mode") . ".png"; - $thumbAbsHref = $this->h5ai->getH5aiAbsHref() . $name; - $thumbAbsPath = $this->h5ai->getH5aiAbsPath() . "/" . $name; + $name = "thumb-" . sha1("$source_abs_path-$width-$height-$mode") . ".jpg"; + $thumb_abs_path = $this->app->get_cache_abs_path() . "/" . $name; + $thumb_abs_href = $this->app->get_cache_abs_href() . $name; - if (!file_exists($thumbAbsPath) || filemtime($sourceAbsPath) >= filemtime($thumbAbsPath)) { + if (!file_exists($thumb_abs_path) || filemtime($source_abs_path) >= filemtime($thumb_abs_path)) { $image = new Image(); - $image->setSource($sourceAbsPath); + $image->set_source($source_abs_path); $image->thumb($mode, $width, $height); - $image->saveDestJpeg($thumbAbsPath, 80); - - // $image->saveDestPng($thumbAbsPath, 9); - // Magic::thumb($mode, $sourceAbsPath, $thumbAbsPath, $width, $height); + $image->save_dest_jpeg($thumb_abs_path, 80); } - return file_exists($thumbAbsPath) ? $thumbAbsHref : null; + return file_exists($thumb_abs_path) ? $thumb_abs_href : null; } - private function capture($cmd, $sourceAbsPath) { + private function capture($cmd, $source_abs_path) { - if (!file_exists($sourceAbsPath)) { + if (!file_exists($source_abs_path)) { return null; } - $captureAbsPath = $this->h5ai->getH5aiAbsPath() . "/cache/capture-" . sha1($sourceAbsPath) . ".jpg"; + $capture_abs_path = $this->app->get_cache_abs_path() . "/capture-" . sha1($source_abs_path) . ".jpg"; - if (!file_exists($captureAbsPath) || filemtime($sourceAbsPath) >= filemtime($captureAbsPath)) { - $cmd = str_replace("[SOURCE]", $sourceAbsPath, $cmd); - $cmd = str_replace("[TARGET]", $captureAbsPath, $cmd); + if (!file_exists($capture_abs_path) || filemtime($source_abs_path) >= filemtime($capture_abs_path)) { + $cmd = str_replace("[SOURCE]", $source_abs_path, $cmd); + $cmd = str_replace("[TARGET]", $capture_abs_path, $cmd); `$cmd`; } - return file_exists($captureAbsPath) ? $captureAbsPath : null; + return file_exists($capture_abs_path) ? $capture_abs_path : null; } } @@ -147,7 +143,7 @@ class Magic { class Image { - private $sourceFile, $source, $width, $height, $type, $dest; + private $source_file, $source, $width, $height, $type, $dest; public static final function is_supported() { @@ -163,7 +159,7 @@ class Image { public function __construct($filename = null) { - $this->sourceFile = null; + $this->source_file = null; $this->source = null; $this->width = null; $this->height = null; @@ -171,43 +167,43 @@ class Image { $this->dest = null; - $this->setSource($filename); + $this->set_source($filename); } public function __destruct() { - $this->releaseSource(); - $this->releaseDest(); + $this->release_source(); + $this->release_dest(); } - public function setSource($filename) { + public function set_source($filename) { - $this->releaseSource(); - $this->releaseDest(); + $this->release_source(); + $this->release_dest(); if (is_null($filename)) { return; } - $this->sourceFile = $filename; + $this->source_file = $filename; - list($this->width, $this->height, $this->type) = @getimagesize($this->sourceFile); + list($this->width, $this->height, $this->type) = @getimagesize($this->source_file); if (!$this->width || !$this->height) { - $this->sourceFile = null; + $this->source_file = null; $this->width = null; $this->height = null; $this->type = null; return; } - $this->source = imagecreatefromstring(file_get_contents($this->sourceFile)); + $this->source = imagecreatefromstring(file_get_contents($this->source_file)); } - public function saveDestJpeg($filename, $quality = 80) { + public function save_dest_jpeg($filename, $quality = 80) { if (!is_null($this->dest)) { @imagejpeg($this->dest, $filename, $quality); @@ -216,7 +212,7 @@ class Image { } - public function saveDestPng($filename, $quality = 9) { + public function save_dest_png($filename, $quality = 9) { if (!is_null($this->dest)) { @imagepng($this->dest, $filename, $quality); @@ -225,7 +221,7 @@ class Image { } - public function releaseDest() { + public function release_dest() { if (!is_null($this->dest)) { @imagedestroy($this->dest); @@ -234,11 +230,11 @@ class Image { } - public function releaseSource() { + public function release_source() { if (!is_null($this->source)) { @imagedestroy($this->source); - $this->sourceFile = null; + $this->source_file = null; $this->source = null; $this->width = null; $this->height = null; @@ -247,29 +243,29 @@ class Image { } - private function magic($destX, $destY, $srcX, $srcY, $destWidth, $destHeight, $srcWidth, $srcHeight, $canWidth = null, $canHeight = null, $color = null) { + private function magic($dest_x, $dest_y, $src_x, $src_y, $dest_width, $dest_height, $src_width, $src_height, $can_width = null, $can_height = null, $color = null) { if (is_null($this->source)) { return; } - if ($canWidth === 0) { - $canWidth = 1; + if ($can_width === 0) { + $can_width = 1; } - if ($canHeight === 0) { - $canHeight = 1; + if ($can_height === 0) { + $can_height = 1; } - if ($destWidth === 0) { - $destWidth = 1; + if ($dest_width === 0) { + $dest_width = 1; } - if ($destHeight === 0) { - $destHeight = 1; + if ($dest_height === 0) { + $dest_height = 1; } - if (!is_null($canWidth) && !is_null($canHeight)) { - $this->dest = imagecreatetruecolor($canWidth, $canHeight); + if (!is_null($can_width) && !is_null($can_height)) { + $this->dest = imagecreatetruecolor($can_width, $can_height); } else { - $this->dest = imagecreatetruecolor($destWidth, $destHeight); + $this->dest = imagecreatetruecolor($dest_width, $dest_height); } if (is_null($color)) { @@ -278,7 +274,7 @@ class Image { $icol = imagecolorallocate($this->dest, $color[0], $color[1], $color[2]); imagefill($this->dest, 0, 0, $icol); - imagecopyresampled($this->dest, $this->source, $destX, $destY, $srcX, $srcY, $destWidth, $destHeight, $srcWidth, $srcHeight); + imagecopyresampled($this->dest, $this->source, $dest_x, $dest_y, $src_x, $src_y, $dest_width, $dest_height, $src_width, $src_height); } @@ -288,18 +284,18 @@ class Image { $height = $width; } if ($mode === "square") { - $this->squareThumb($width); + $this->square_thumb($width); } elseif ($mode === "rational") { - $this->rationalThumb($width, $height); + $this->rational_thumb($width, $height); } elseif ($mode === "center") { - $this->centerThumb($width, $height, $color); + $this->center_thumb($width, $height, $color); } else { - $this->freeThumb($width, $height); + $this->free_thumb($width, $height); } } - public function squareThumb($width) { + public function square_thumb($width) { if (is_null($this->source)) { return; @@ -313,7 +309,7 @@ class Image { } - public function rationalThumb($width, $height) { + public function rational_thumb($width, $height) { if (is_null($this->source)) { return; @@ -337,7 +333,7 @@ class Image { } - public function centerThumb($width, $height, $color = null) { + public function center_thumb($width, $height, $color = null) { if (is_null($this->source)) { return; @@ -364,7 +360,7 @@ class Image { } - public function freeThumb($width, $height) { + public function free_thumb($width, $height) { if (is_null($this->source)) { return; diff --git a/src/_h5ai/server/php/inc/init.php b/src/_h5ai/server/php/inc/init.php new file mode 100644 index 00000000..2d90bade --- /dev/null +++ b/src/_h5ai/server/php/inc/init.php @@ -0,0 +1,41 @@ +apply(); + + json_fail(100, "unsupported request"); + +} else { + + $HREF = $app->get_app_abs_href(); + $JSON = $app->get_generic_json(); + $FALLBACK = $app->get_no_js_fallback(); +} + +?> \ No newline at end of file diff --git a/src/_h5ai/server/php/inc/util.php b/src/_h5ai/server/php/inc/util.php new file mode 100644 index 00000000..bed071e6 --- /dev/null +++ b/src/_h5ai/server/php/inc/util.php @@ -0,0 +1,91 @@ + $code, "msg" => $msg)); + exit; + } +} + +function use_request_params($keys) { + + if (!is_array($keys)) { + $keys = func_get_args(); + } + + $values = array(); + foreach ($keys as $key) { + json_fail(101, "parameter '$key' is missing", !array_key_exists($key, $_REQUEST)); + $values[] = $_REQUEST[$key]; + unset($_REQUEST[$key]); + } + return $values; +} + +function use_optional_request_params($keys) { + + if (!is_array($keys)) { + $keys = func_get_args(); + } + + $values = array(); + foreach ($keys as $key) { + if (array_key_exists($key, $_REQUEST)) { + $values[] = $_REQUEST[$key]; + unset($_REQUEST[$key]); + } else { + $values[] = null; + } + } + return $values; +} + +function delete_tempfile($file) { + + @unlink($file); +} + +function starts_with($sequence, $head) { + + return substr($sequence, 0, strlen($head)) === $head; +} + +function ends_with($sequence, $tail) { + + return substr($sequence, -strlen($tail)) === $tail; +} + +function load_commented_json($file) { + + if (!file_exists($file)) { + return array(); + } + + $str = file_get_contents($file); + + // remove comments to get pure json + $str = preg_replace("/\/\*.*?\*\/|\/\/.*?(\n|$)/s", "", $str); + + return json_decode($str, true); +} + +function merge_config($a, $b) { + + $result = array_merge(array(), $a); + + foreach ($b as $key => $value) { + $result[$key] = array_merge($result[$key], $b[$key]); + } + + return $result; +} + +?> \ No newline at end of file diff --git a/src/_h5ai/server/php/index.php.jade b/src/_h5ai/server/php/index.php.jade new file mode 100644 index 00000000..ac4ef7d2 --- /dev/null +++ b/src/_h5ai/server/php/index.php.jade @@ -0,0 +1,49 @@ +| + +- var href = "" +- var json = "" +- var fallback = "" + +doctype 5 +//if lt IE 9 + +//[if gt IE 8]>