diff --git a/README.md b/README.md index 1f84df19..38ae36d5 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,18 @@ ## *PATHFINDER* -Mapping tool for *EVE ONLINE* +Mapping tool for [*EVE ONLINE*](https://www.eveonline.com) -url: https://www.pathfinder.exodus4d.de +- Project[https://www.pathfinder.exodus4d.de](https://www.pathfinder.exodus4d.de) +- Community[google +](https://plus.google.com/u/0/b/110257318165279088853/110257318165279088853) +- Screenshots[imgur.com](http://imgur.com/a/k2aVa) +- Media[youtube.com](https://www.youtube.com/channel/UC7HU7XEoMbqRwqxDTbMjSPg) +- Licence[MIT](http://opensource.org/licenses/MIT) -### Project requirements -------------------------------------------------- +##### Beta Information +> This project is still in beta phase and is not officially released! Feel free to check the code for security issues. +You can not get the project to work, on your own server, until some required SQL dumps have been included to this repository! +I will provide all required dumps once the beta phase is over. + +## Requirements #### APACHE Webserver - PHP 5.3.4 or higher - PCRE 8.02 or higher (usually shipped with PHP package, but needs to be additionally updated on CentOS or Red Hat systems) @@ -12,8 +21,8 @@ url: https://www.pathfinder.exodus4d.de - cURL, sockets or stream extension (for Web plugin) - Gzip compression - Nginx and Lighttpd configurations are also possible. - http://fatfreeframework.com/system-requirements +> Nginx and Lighttpd configurations are also possible. +http://fatfreeframework.com/system-requirements #### Database - mysql: MySQL 5.x - sqlite: SQLite 3 and SQLite 2 @@ -23,12 +32,130 @@ url: https://www.pathfinder.exodus4d.de - odbc: ODBC v3 - oci: Oracle - Here is a list of links to DSN connection details for all currently supported engines in the SQL layer: - http://fatfreeframework.com/sql -#### Development Environment - - t.b.a. +>Here is a list of links to DSN connection details for all currently supported engines in the SQL layer: +http://fatfreeframework.com/sql -### Folder structure (production) ---------------------------------------- +## Setup +#### Backend (PHP) + +*PATHFINDER* is pretty easy to configure! If you are not planning "getting your hands dirty" with programming stuff, +you donīt have to change a lot. All configuration files can be found here: +- [config.ini](https://github.com/exodus4d/pathfinder/blob/master/app/config.ini) Main config **(DO NOT CHANGE)** +- [pathfinder.ini](https://github.com/exodus4d/pathfinder/blob/master/app/pathfinder.ini) Pathfinder config +- [cron.ini](https://github.com/exodus4d/pathfinder/blob/master/app/cron.ini) Cronjob config +- [routes.ini](https://github.com/exodus4d/pathfinder/blob/master/app/routes.ini) Routes config **(DO NOT CHANGE)** + +> The default configuration should be fine in most cases. Edit all values with caution! + +#### Frontend (JS) +There is **no** need to change any javascript configuration, except *Signature names* that can be changed/added +- [init.js](https://github.com/exodus4d/pathfinder/blob/master/js/app/init.js) Main config **(DO NOT CHANGE)** +- [signature_type.js](https://github.com/exodus4d/pathfinder/blob/master/js/app/config/signature_type.js) Signature mapping config **(DO NOT CHANGE)** +- [system_effect](https://github.com/exodus4d/pathfinder/blob/master/js/app/config/system_effect.js) System effect config **(DO NOT CHANGE)** + +> If you found any *Signature Names* or other information missing in these files, please create an [Issue](https://github.com/exodus4d/pathfinder/issues) for that! +Iīll try to fix it with the next release. +If you still want to change anything in here, make sure to run the `build` process afterwards (see below). + +## Development Environment +*PATHFINDER* comes along with a simple, [*Gulp*](http://gulpjs.com/) based, build process. +There are two main *Gulp tasks* that should help you. +- `default` task is designed for *"continuous development"* scenario +- `production` task is designed for *"production deployment"* scenario + +> If you are **not** planning to change the codebase, you donīt have to do the following steps! + +**1. Install [Node.js](https://nodejs.org)(> v.4.0.1) with [npm](https://www.npmjs.com/)** + +**2. [Copy/Fork](https://help.github.com/articles/fork-a-repo/) this Repo** + ``` + $ git clone https://github.com/exodus4d/pathfinder.git + ``` +**3. Install all required `node_modules` for *"continuous development"* from `package.json` (e.g.[Gulp](http://gulpjs.com/))** + ``` + $ npm install + ``` +**4. Run *Gulp* task `default` with your version `tag` as param. It will do:** + - clean `dist` folder (./public/js/x.x.x) + - init file watcher for \*.js changes + - running [jsHint](http://jshint.com/docs/) on file change + - copying **raw** *\*.js* files from *./js* to `dist` folder on file change + ``` + $ gulp default --tag v0.0.10 + ``` + +## Production Environment +**1. Install all required dependencies (check "Development Environment" steps )** + +**2. Run *Gulp* task `production` with your version `tag` as param. It will do:** + - clean `dist` folder (./public/js/x.x.x) + - running [jsHint](http://jshint.com/docs/) + - running [requireJs Optimizer](http://requirejs.org/docs/optimization.html) (see [build.js](https://github.com/exodus4d/pathfinder/blob/master/build.js)) + - minify \*.js files + - uglyfy \*.js files + - combine \*.js dependencies + - generate \.js `source maps` + - copying **compressed** *\*.js* to `dist` folder for production deployment + ``` + $ gulp production --tag v0.0.10 + ``` +> The `production` task may take some seconds (30+ seconds)! +As a result, you should have all generated \*.js files ready for deployment in the `dist` folder. +The unique version `tag` in this path should ensure that `cache busting` is working correct. + +## CSS generation +If you are planning to change/edit any *CSS* styles, you need to install [Compass](http://compass-style.org/), +in order to build the single \*.css file out of the **raw** \*.scss source files. + +**1. [Ruby install](https://www.ruby-lang.org/en/)** + +**2. [Compass install](http://compass-style.org/install/)** + +**3. Start *Compass* file watcher for \*.scss changes in project `root` (see [config.rb](https://github.com/exodus4d/pathfinder/blob/master/config.rb))** + ``` + $ compass watch + ``` +> This will watch all \*.scss files for changes and generate a compressed \*.css file (./public/css/pathfinder.css). +Donīt worry about `cache busting`. Your current version `tag` will be added to the final path (e.g. ./public/css/pathfinder.css?v.0.0.10) + +## SQL Schema +To get *PATHFINDER* to work, you will need (at least) **two** databases. The first one is the [SDE](https://developers.eveonline.com/resource/static-data-export) +from *CCP*. The second database is *PATHFINDERS*īs own DB. Make sure, you have the correct DB export for your version! + +**1. *CCP* Static Data Export ([SDE](https://developers.eveonline.com/resource/static-data-export))** + +You need to import the Eve SDE into the database specified in the `DB_CCP_*` settings. You can do this like the following: + ``` + wget https://www.fuzzwork.co.uk/dump/mysql-latest.tar.bz2 + tar xf mysql-latest.tar.bz2 + cd mysql-{}/ + mysql -u -p __DATABASE_NAME__ < db_file.sql + ``` +> If you need an older versions of the SDE, check out[**Fuzzwork**](https://www.fuzzwork.co.uk/dump/)īs awesome dumps! + +**2. *PATHFINDER* Clean Data Export ([CDE](https://www.google.de))** +> Make sure, that all column `indexes` and foreign `key constraints` have been imported correct! +Otherwise you will get DB errors and the cache engine can not track all tables (Models), which may result in bad performance! + +## Cronjob configuration +*PATHFINDER* requires some dynamic `system data` from *CCP*īs [XML APIv2](http://wiki.eve-id.net/APIv2_Page_Index). +This data is automatically imported by a [*Cron-Job*](https://en.wikipedia.org/wiki/Cron) into the DB. + +Moreover, there are some predefined *Cron-Jobs* that handle some `db maintenance` and clean up tasks. + +You have to setup a **single** *Cron-Jobs* for this, that handles **all** other *Cron-Jobs* and works as a "*dispatcher*". + - **Important**: Block access to `[YOUR INSTALLATION]/cron` (e.g. by `.htaccess` or edit `cron.ini`) + - Trigger `[YOUR INSTALLATION]/cron` by [*CLI*](http://php.net/manual/en/features.commandline.php) **every minute**, e.g create `cron.phpx`: + ``` php + exec('wget -qO- /dev/null [YOUR INSTALLATION]/cron &> /dev/null', $out, $result); + echo "start:"; + echo "Returncode: " .$result ."
"; + echo "Ausgabe des Scripts: " ."
"; + echo "
"; print_r($out);
+ ```
+ - ... or use [*CURL*](http://php.net/manual/en/book.curl.php) for this ;)
+
+## Project structure
 
 ```
   |-- (0755) app              --> backend [*.php]
@@ -49,12 +176,13 @@ url: https://www.pathfinder.exodus4d.de
       |-- app.js            --> require.js config (!required for production!)
   |-- (0777) logs           --> log files
       |-- ...
-  | -- node_modules         --> node.js modules (not used for production )     
+  | -- node_modules         --> node.js modules (not used for production) [check "Development Environment" section]
       |-- ...
   |-- (0755) public         --> frontend source
-      |-- css               --> CSS build folder (minified)
-      |-- fonts             --> Web/Icon fonts
+      |-- css               --> CSS dist/build folder (minified)
+      |-- fonts             --> (icon)-Fonts
       |-- img               --> images
+      |-- js                --> JS dist/build folder
       |-- templates         --> templates
   |-- sass                  --> SCSS source (not used for production )
       |-- ...
@@ -62,4 +190,19 @@ url: https://www.pathfinder.exodus4d.de
       |-- ...
   |-- (0755) .htaccess      --> reroute/caching rules
   |-- (0755) index.php
+
+  --------------------------
+  CI/CD config files:
+  --------------------------
+  |-- build.js              --> "RequireJs Optimizer" config (not used for production )
+  |-- config.rb             --> "Compass" config (not used for production )
+  |-- gulpfile.js           --> "Gulp" task config (not used for production )
+  |-- package.json          --> "Node.js" dependency config (not used for production )
+  |-- README.md             --> This file :) (not used for production )
 ```
+
+## Thanks!
+Iīm very proud that **you** are using *PATHFINDER*!
+
+It took me month of time in development until this project got into the first *BETA*. If you like it, please help to improve it.
+(report bugs, find security issues,...)
\ No newline at end of file
diff --git a/app/main/controller/controller.php b/app/main/controller/controller.php
index e9df401c..5d10bbcc 100644
--- a/app/main/controller/controller.php
+++ b/app/main/controller/controller.php
@@ -49,7 +49,7 @@ class Controller {
         $f3->set('isIngame', self::isIGB() );
 
         // js path (build/minified or raw uncompressed files)
-        $f3->set('pathJs', self::getEnvironmentData('PATH_JS') );
+        $f3->set('pathJs', 'public/js/' . $f3->get('PATHFINDER.VERSION') );
     }
 
     /**
diff --git a/build.js b/build.js
new file mode 100644
index 00000000..767e9d94
--- /dev/null
+++ b/build.js
@@ -0,0 +1,204 @@
+({
+    //The top level directory that contains your app. If this option is used
+    //then it assumed your scripts are in a subdirectory under this path.
+    //This option is not required. If it is not specified, then baseUrl
+    //below is the anchor point for finding things. If this option is specified,
+    //then all the files from the app directory will be copied to the dir:
+    //output area, and baseUrl will assume to be a relative path under
+    //this directory.
+    appDir: "./js",
+
+    //By default, all modules are located relative to this path. If baseUrl
+    //is not explicitly set, then all modules are loaded relative to
+    //the directory that holds the build file. If appDir is set, then
+    //baseUrl should be specified as relative to the appDir.
+    baseUrl: "./",
+
+    //By default all the configuration for optimization happens from the command
+    //line or by properties in the config file, and configuration that was
+    //passed to requirejs as part of the app's runtime "main" JS file is *not*
+    //considered. However, if you prefer the "main" JS file configuration
+    //to be read for the build so that you do not have to duplicate the values
+    //in a separate configuration, set this property to the location of that
+    //main JS file. The first requirejs({}), require({}), requirejs.config({}),
+    //or require.config({}) call found in that file will be used.
+    //As of 2.1.10, mainConfigFile can be an array of values, with the last
+    //value's config take precedence over previous values in the array.
+    mainConfigFile: './js/app.js',
+
+    //Specify modules to stub out in the optimized file. The optimizer will
+    //use the source version of these modules for dependency tracing and for
+    //plugin use, but when writing the text into an optimized bundle, these
+    //modules will get the following text instead:
+    //If the module is used as a plugin:
+    //    define({load: function(id){throw new Error("Dynamic load not allowed: " + id);}});
+    //If just a plain module:
+    //    define({});
+    //This is useful particularly for plugins that inline all their resources
+    //and use the default module resolution behavior (do *not* implement the
+    //normalize() method). In those cases, an AMD loader just needs to know
+    //that the module has a definition. These small stubs can be used instead of
+    //including the full source for a plugin.
+    //stubModules: ['text'],
+
+    //As of RequireJS 2.0.2, the dir above will be deleted before the
+    //build starts again. If you have a big build and are not doing
+    //source transforms with onBuildRead/onBuildWrite, then you can
+    //set keepBuildDir to true to keep the previous dir. This allows for
+    //faster rebuilds, but it could lead to unexpected errors if the
+    //built code is transformed in some way.
+    keepBuildDir: false,
+
+    //Finds require() dependencies inside a require() or define call. By default
+    //this value is false, because those resources should be considered dynamic/runtime
+    //calls. However, for some optimization scenarios, it is desirable to
+    //include them in the build.
+    //Introduced in 1.0.3. Previous versions incorrectly found the nested calls
+    //by default.
+    findNestedDependencies: false,
+
+
+    //Inlines the text for any text! dependencies, to avoid the separate
+    //async XMLHttpRequest calls to load those dependencies.
+    inlineText: false,
+
+    //If set to true, any files that were combined into a build bundle will be
+    //removed from the output folder.
+    removeCombined: true,
+
+    //List the modules that will be optimized. All their immediate and deep
+    //dependencies will be included in the module's file when the build is
+    //done. If that module or any of its dependencies includes i18n bundles,
+    //only the root bundles will be included unless the locale: section is set above.
+    modules: [
+        //Just specifying a module name means that module will be converted into
+        //a built file that contains all of its dependencies. If that module or any
+        //of its dependencies includes i18n bundles, they may not be included in the
+        //built file unless the locale: section is set above.
+        {
+            name: 'mappage',
+            include: ['text'],
+            excludeShallow: [
+                'app'
+            ]
+        },{
+            name: 'landingpage',
+            include: ['text'],
+            excludeShallow: [
+                'app'
+            ]
+        },{
+            name: 'app/notification',
+            excludeShallow: [
+                'app',
+                'jquery'
+            ]
+        }
+    ],
+
+    //By default, comments that have a license in them are preserved in the
+    //output when a minifier is used in the "optimize" option.
+    //However, for a larger built files there could be a lot of
+    //comment files that may be better served by having a smaller comment
+    //at the top of the file that points to the list of all the licenses.
+    //This option will turn off the auto-preservation, but you will need
+    //work out how best to surface the license information.
+    //NOTE: As of 2.1.7, if using xpcshell to run the optimizer, it cannot
+    //parse out comments since its native Reflect parser is used, and does
+    //not have the same comments option support as esprima.
+    preserveLicenseComments: false, // not working with "generate source maps" :(
+
+    //Introduced in 2.1.2 and considered experimental.
+    //If the minifier specified in the "optimize" option supports generating
+    //source maps for the minified code, then generate them. The source maps
+    //generated only translate minified JS to non-minified JS, it does not do
+    //anything magical for translating minified JS to transpiled source code.
+    //Currently only optimize: "uglify2" is supported when running in node or
+    //rhino, and if running in rhino, "closure" with a closure compiler jar
+    //build after r1592 (20111114 release).
+    //The source files will show up in a browser developer tool that supports
+    //source maps as ".js.src" files.
+    generateSourceMaps: true,
+
+    //Sets the logging level. It is a number. If you want "silent" running,
+    //set logLevel to 4. From the logger.js file:
+    //TRACE: 0,
+    //INFO: 1,
+    //WARN: 2,
+    //ERROR: 3,
+    //SILENT: 4
+    //Default is 0.
+    logLevel: 0,
+
+    //How to optimize all the JS files in the build output directory.
+    //Right now only the following values
+    //are supported:
+    //- "uglify": (default) uses UglifyJS to minify the code.
+    //- "uglify2": in version 2.1.2+. Uses UglifyJS2.
+    //- "closure": uses Google's Closure Compiler in simple optimization
+    //mode to minify the code. Only available if running the optimizer using
+    //Java.
+    //- "closure.keepLines": Same as closure option, but keeps line returns
+    //in the minified files.
+    //- "none": no minification will be done.
+    optimize: 'uglify2',
+
+    //Introduced in 2.1.2: If using "dir" for an output directory, normally the
+    //optimize setting is used to optimize the build bundles (the "modules"
+    //section of the config) and any other JS file in the directory. However, if
+    //the non-build bundle JS files will not be loaded after a build, you can
+    //skip the optimization of those files, to speed up builds. Set this value
+    //to true if you want to skip optimizing those other non-build bundle JS
+    //files.
+    //skipDirOptimize: true,
+
+    //If using UglifyJS2 for script optimization, these config options can be
+    //used to pass configuration values to UglifyJS2.
+    //For possible `output` values see:
+    //https://github.com/mishoo/UglifyJS2#beautifier-options
+    //For possible `compress` values see:
+    //https://github.com/mishoo/UglifyJS2#compressor-options
+    uglify2: {
+        //Example of a specialized config. If you are fine
+        //with the default options, no need to specify
+        //any of these properties.
+        output: {
+            beautify: false,
+            comments: false
+        },
+        compress: {
+            sequences: false,
+            drop_console: true,
+            global_defs: {
+                DEBUG: false
+            }
+        },
+        warnings: false,
+        mangle: true
+    },
+
+    //A function that will be called for every write to an optimized bundle
+    //of modules. This allows transforms of the content before serialization.
+    onBuildWrite: function (moduleName, path, contents) {
+
+        // show module names for each file
+        if(moduleName === 'mappage'){
+            // perform transformations on the original source
+            contents = contents.replace( /#version/i, new Date().toString() );
+        }
+
+        return contents;
+    },
+
+    paths: {
+        app: "./../js/app" // the main config file will not be build
+    },
+
+    //The directory path to save the output. If not specified, then
+    //the path will default to be a directory called "build" as a sibling
+    //to the build file. All relative paths are relative to the build file.
+    dir: "./build_js"
+
+
+
+})
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 00000000..251dca56
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,199 @@
+/* GULP itself */
+var gulp = require('gulp-param')(require('gulp'), process.argv);
+var jshint = require('gulp-jshint');
+var notify = require('gulp-notify');
+var plumber = require('gulp-plumber');
+var gulpif = require('gulp-if');
+var clean = require('gulp-clean');
+
+var runSequence = require('run-sequence');
+var exec = require('child_process').exec;
+var path = require('path');
+var stylish = require('jshint-stylish');
+
+/*******************************************/
+// Source and destination file paths
+
+var _src = {
+    GULP: './gulpfile.js',
+    ICON: './public/img/notifications/logo.png',
+ //   JS_CONFIG: './src/main/conf/build.js', // path to requirejs config file
+    JS_SRC: './js/**/*.js',
+    JS_LIBS: './js/lib/**/*.js',
+    JS_BUILD: './build_js',
+    JS_DIST: './public/js',
+    PACKAGE: './package.json'
+};
+
+// Gulp plumber error handler
+var onError = function(err) {
+    console.log(err);
+};
+
+/*******************************************/
+// Build Configuration
+
+var isProductionBuild = false;
+/**
+ * Version nr (e.g. v0.0.4)
+ * required for "production" task
+ * @type {null}
+ */
+var tagVersion = null;
+
+/**
+ * RequireJS build task using the r.js optimizer.
+ */
+gulp.task('requirejs', ['jshint'], function() {
+
+    var rjsPath = path.resolve(__dirname, './node_modules/requirejs/bin/r.js');
+    var oPath = path.resolve(__dirname, './build.js');
+
+    exec('node ' + rjsPath + ' -o ' + oPath, function(error, stdout, stderr) {
+        var success = true;
+        console.log('[RequireJS]', stderr);
+
+        if (error !== null) {
+            console.log('[RequireJS]', error);
+            success = false;
+        }
+
+        runSequence(
+            'copyBuildFiles',
+            'removeBuildFiles'
+        );
+    });
+});
+
+/*******************************************/
+/**
+ * JSHint JavaScript and JSON
+ * see .jshintrc for configuration
+ * http://jshint.com/docs/
+ * http://jshint.com/docs/options/
+ */
+gulp.task('jshint', function(){
+    return gulp.src([
+        _src.JS_SRC,
+        '!' + _src.JS_LIBS
+        ])
+        .pipe(plumber({
+            errorHandler: onError
+        }))
+        .pipe(jshint())
+        .pipe(jshint.reporter(stylish))
+        .pipe(notify({
+                icon: path.resolve(__dirname, _src.ICON),
+                title: 'JSHint',
+                message: 'Task complete',
+                onLast: true
+        }));
+    // .pipe(jshint.reporter('fail')); // uncomment this line to stop build on error
+});
+
+/**
+ * Copy optimized/uglyfied js files from "js_build" folder to "public/js/x.x.x/*" folder
+ * for release deployment (cache busting)
+ */
+gulp.task('copyBuildFiles', ['removeDistFiles'], function () {
+
+    // raw files
+    var source = _src.JS_SRC;
+
+    if(isProductionBuild){
+        // build files
+        source = _src.JS_BUILD + '/**/*';
+    }
+
+    return gulp
+        .src( source  )
+        .pipe(
+        gulpif(
+            tagVersion !== null,
+            gulp.dest( _src.JS_DIST + '/' + tagVersion  )
+        )
+    ).pipe(notify({
+            icon: path.resolve(__dirname, _src.ICON),
+            title: 'Copy JS to dist',
+            message: 'Task complete',
+            onLast: true
+        }));
+});
+
+/**
+ * task removes temp build js files
+ */
+gulp.task('removeBuildFiles', function () {
+    'use strict';
+
+    return gulp.src( _src.JS_BUILD ).pipe( clean( _src.JS_BUILD ) );
+});
+
+/**
+ * task removes "dist" js files
+ */
+gulp.task('removeDistFiles', function () {
+    'use strict';
+
+    var dist = _src.JS_DIST + '/' + tagVersion;
+
+    return gulp.src(dist).pipe( clean(dist) );
+});
+
+/*******************************************/
+// Watch
+// execute only during continuous development!
+gulp.task('watch', function(tag) {
+
+    if(tag){
+        tagVersion = tag;
+    }
+
+    gulp.watch([
+        _src.JS_SRC,
+        '!' + _src.JS_LIBS,
+    ], ['jshint', 'copyBuildFiles']);
+
+
+});
+
+
+/*******************************************/
+// Default Tasks
+
+/**
+ * Production task for deployment.
+ * Triggered by Maven Plugin.
+ * $ gulp production --tag v0.0.9
+ * WARNING: DO NOT REMOVE THIS TASK!!!
+ */
+gulp.task('production', function(tag) {
+
+    if(tag !== null){
+        tagVersion = tag;
+        isProductionBuild = true;
+
+        // use run-sequence until gulp v4.0 is released
+        runSequence(
+            'requirejs'
+        );
+    }
+});
+
+/**
+ * Default task for continuous development.
+ * $ gulp default --tag v0.0.9
+ * WARNING: DO NOT REMOVE THIS TASK!!!
+ */
+gulp.task('default', function(tag) {
+
+    if(tag){
+        tagVersion = tag;
+    }
+
+    runSequence(
+        'jshint',
+        'copyBuildFiles',
+        'watch'
+    );
+});
\ No newline at end of file
diff --git a/js/app.js b/js/app.js
index 59f2f641..b60bef4b 100644
--- a/js/app.js
+++ b/js/app.js
@@ -13,6 +13,8 @@ requirejs.config({
         layout: 'layout',
         config: 'app/config',                                           // path for "configuration" files dir
         dialog: 'app/ui/dialog',                                        // path for "dialog" files dir
+        templates: '../../templates',                                   // template dir
+        img: '../../img',                                               // images dir
 
         // main views
         landingpage: './app/landingpage',                               // initial start "landing page" view
@@ -24,8 +26,6 @@ requirejs.config({
         mustache: 'lib/mustache.min',                                   // v1.0.0 Javascript template engine - http://mustache.github.io/
         velocity: 'lib/velocity.min',                                   // v1.2.2 animation engine - http://julian.com/research/velocity/
         velocityUI: 'lib/velocity.ui.min',                              // v5.0.4 plugin for velocity - http://julian.com/research/velocity/#uiPack
-        templates: '../public/templates',                               // template dir
-        img: '../public/img',                                           // images dir
         slidebars: 'lib/slidebars',                                     // v0.10 Slidebars - side menu plugin http://plugins.adchsm.me/slidebars/
         jsPlumb: 'lib/dom.jsPlumb-1.7.6-min',                           // v1.7.6 jsPlumb (Vanilla)- main map draw plugin https://jsplumbtoolkit.com/
         customScrollbar: 'lib/jquery.mCustomScrollbar.concat.min',      // v3.0.9 Custom scroll bars - http://manos.malihu.gr/
diff --git a/js/app/landingpage.js b/js/app/landingpage.js
index c5eaf9cb..a2c2bc58 100644
--- a/js/app/landingpage.js
+++ b/js/app/landingpage.js
@@ -274,7 +274,7 @@ define([
         };
 
         // initialize carousel ------------------------------------------
-        var carousel = Gallery([
+        var carousel = new Gallery([
             {
                 title: 'IGB',
                 href: 'ui/map',
@@ -389,7 +389,7 @@ define([
                     titleProperty: 'description'
                 };
 
-                Gallery(thumbLinks, options);
+                new Gallery(thumbLinks, options);
             });
         });
     };
diff --git a/js/app/map/map.js b/js/app/map/map.js
index 83a445c7..71c191e7 100644
--- a/js/app/map/map.js
+++ b/js/app/map/map.js
@@ -77,7 +77,7 @@ define([
     // active connections per map (cache object)
     var activeConnections = {};
 
-    // characterID => systemIdīs are cached temporary where the active user character is in
+    // characterID => systemIds are cached temporary where the active user character is in
     // if a character switches/add system, establish connection with "previous" system
     var activeSystemCache = '';
 
@@ -1833,6 +1833,8 @@ define([
                 // system name
                 var currentSystemName = currentSystem.getSystemInfo( ['alias'] );
 
+                var systemData = {};
+
                 switch(action){
                     case 'add_system':
                         // add a new system
@@ -1919,17 +1921,17 @@ define([
                         });
                         break;
                     case 'ingame_show_info':
-                        var systemData = system.getSystemData();
+                        systemData = system.getSystemData();
 
                         CCPEVE.showInfo(5, systemData.systemId );
                         break;
                     case 'ingame_set_destination':
-                        var systemData = system.getSystemData();
+                        systemData = system.getSystemData();
 
                         CCPEVE.setDestination( systemData.systemId );
                         break;
                     case 'ingame_add_waypoint':
-                        var systemData = system.getSystemData();
+                        systemData = system.getSystemData();
 
                         CCPEVE.addWaypoint( systemData.systemId );
                         break;
diff --git a/js/app/module_map.js b/js/app/module_map.js
index 8b0937f4..27f9f990 100644
--- a/js/app/module_map.js
+++ b/js/app/module_map.js
@@ -411,7 +411,7 @@ define([
         var contentElement = $('
', { id: config.mapTabIdPrefix + parseInt( options.id ), class: [config.mapTabContentClass].join(' ') - }) + }); contentElement.addClass('tab-pane'); @@ -707,7 +707,7 @@ define([ /** * collect all data (systems/connections) for export/save from each active map in the map module - * if no change detected -> donīt attach map data to return array + * if no change detected -> do not attach map data to return array * @returns {Array} */ $.fn.getMapModuleDataForUpdate = function(){ diff --git a/js/app/ui/dialog/notification.js b/js/app/ui/dialog/notification.js index 212bbec0..98c77f2b 100644 --- a/js/app/ui/dialog/notification.js +++ b/js/app/ui/dialog/notification.js @@ -32,7 +32,7 @@ define([ if( !CCP.isInGameBrowser() ){ headlineElement.delay(300).velocity('transition.shrinkIn', { duration: 500 - }).delay(800) + }).delay(800); headlineElement.velocity({ scale: 1.05 diff --git a/js/app/ui/dialog/trust.js b/js/app/ui/dialog/trust.js index 006c307f..0fd1e6c0 100644 --- a/js/app/ui/dialog/trust.js +++ b/js/app/ui/dialog/trust.js @@ -30,7 +30,7 @@ define([ pageElement.find('h1').delay(300).velocity('transition.shrinkIn', { duration: 500 - }).delay(800) + }).delay(800); pageElement.find('h1').velocity({ scale: 1.05 diff --git a/js/app/ui/header.js b/js/app/ui/header.js index 7444ac19..b1aeb211 100644 --- a/js/app/ui/header.js +++ b/js/app/ui/header.js @@ -48,8 +48,8 @@ define([ var closest = []; var p1 = points[i]; for(var j = 0; j < points.length; j++) { - var p2 = points[j] - if(!(p1 === p2)) { + var p2 = points[j]; + if(p1 !== p2) { var placed = false; for(var k = 0; k < connectionCount; k++) { if(!placed) { @@ -60,10 +60,10 @@ define([ } } - for(var k = 0; k < connectionCount; k++) { + for(var m = 0; k < connectionCount; m++) { if(!placed) { - if(getDistance(p1, p2) < getDistance(p1, closest[k])) { - closest[k] = p2; + if(getDistance(p1, p2) < getDistance(p1, closest[m])) { + closest[m] = p2; placed = true; } } @@ -74,9 +74,9 @@ define([ } // assign a circle to each point - for(var i in points) { - var c = new Circle(points[i], 2+Math.random()*2, 'rgba(255,255,255,0.3)'); - points[i].circle = c; + for(var n in points) { + var c = new Circle(points[n], 2+Math.random()*2, 'rgba(255,255,255,0.3)'); + points[n].circle = c; } }; diff --git a/js/app/ui/system_info.js b/js/app/ui/system_info.js index e63d807f..1c40ce56 100644 --- a/js/app/ui/system_info.js +++ b/js/app/ui/system_info.js @@ -152,7 +152,7 @@ define([ // hide/disable description field // hide tool button - descriptionButton.hide() + descriptionButton.hide(); showToolsActionElement(); } diff --git a/package.json b/package.json new file mode 100644 index 00000000..59a08584 --- /dev/null +++ b/package.json @@ -0,0 +1,41 @@ +{ + "name": "pathfinder", + "version": "1.0.0", + "description": "System mapping tool for EVE ONLINE", + "main": "index.php", + "dependencies": { + "requirejs": "^2.1.20" + }, + "devDependencies": { + "gulp": "^3.9.0", + "gulp-clean": "^0.3.1", + "gulp-if": "^1.2.5", + "gulp-jshint": "^1.11.2", + "gulp-notify": "^2.2.0", + "gulp-param": "^0.6.3", + "gulp-plumber": "^1.0.1", + "jshint": "^2.8.0", + "jshint-stylish": "^2.0.1", + "requirejs": "^2.1.20", + "run-sequence": "^1.1.2" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/exodus4d/pathfinder.git" + }, + "keywords": [ + "Pathfinder", + "Exodus 4D", + "EVE ONLINE", + "Wormhole" + ], + "author": "Exodus 4D", + "license": "ISC", + "bugs": { + "url": "https://github.com/exodus4d/pathfinder/issues" + }, + "homepage": "https://github.com/exodus4d/pathfinder#readme" +} diff --git a/public/js/v0.0.10/app.js b/public/js/v0.0.10/app.js new file mode 100644 index 00000000..a19f6cdb --- /dev/null +++ b/public/js/v0.0.10/app.js @@ -0,0 +1,2 @@ +var mainScriptPath=document.body.getAttribute("data-script"),jsBaseUrl=document.body.getAttribute("data-js-path");requirejs.config({baseUrl:"js",paths:{layout:"layout",config:"app/config",dialog:"app/ui/dialog",templates:"../../templates",img:"../../img",landingpage:"./app/landingpage",mappage:"./app/mappage",jquery:"lib/jquery-1.11.3.min",bootstrap:"lib/bootstrap.min",text:"lib/requirejs/text",mustache:"lib/mustache.min",velocity:"lib/velocity.min",velocityUI:"lib/velocity.ui.min",slidebars:"lib/slidebars",jsPlumb:"lib/dom.jsPlumb-1.7.6-min",customScrollbar:"lib/jquery.mCustomScrollbar.concat.min",datatables:"lib/datatables/jquery.dataTables.min",datatablesResponsive:"lib/datatables/extensions/responsive/dataTables.responsive",datatablesTableTools:"lib/datatables/extensions/tabletools/js/dataTables.tableTools",xEditable:"lib/bootstrap-editable.min",morris:"lib/morris.min",raphael:"lib/raphael-min",bootbox:"lib/bootbox.min",easyPieChart:"lib/jquery.easypiechart.min",dragToSelect:"lib/jquery.dragToSelect",hoverIntent:"lib/jquery.hoverIntent.minified",fullScreen:"lib/jquery.fullscreen.min",select2:"lib/select2.min",validator:"lib/validator.min",lazylinepainter:"lib/jquery.lazylinepainter-1.5.1.min",blueImpGallery:"lib/blueimp-gallery",blueImpGalleryHelper:"lib/blueimp-helper",blueImpGalleryBootstrap:"lib/bootstrap-image-gallery",bootstrapConfirmation:"lib/bootstrap-confirmation",bootstrapToggle:"lib/bootstrap2-toggle.min",easePack:"lib/EasePack.min",tweenLite:"lib/TweenLite.min",pnotify:"lib/pnotify/pnotify.core","pnotify.buttons":"lib/pnotify/pnotify.buttons","pnotify.confirm":"lib/pnotify/pnotify.confirm","pnotify.nonblock":"lib/pnotify/pnotify.nonblock","pnotify.desktop":"lib/pnotify/pnotify.desktop","pnotify.history":"lib/pnotify/pnotify.history","pnotify.callbacks":"lib/pnotify/pnotify.callbacks","pnotify.reference":"lib/pnotify/pnotify.reference"},shim:{bootstrap:{deps:["jquery"]},velocity:{deps:["jquery"]},velocityUI:{deps:["velocity"]},slidebars:{deps:["jquery"]},customScrollbar:{deps:["jquery"]},datatables:{deps:["jquery"]},datatablesBootstrap:{deps:["datatables"]},datatablesResponsive:{deps:["datatables"]},datatablesTableTools:{deps:["datatables"]},xEditable:{deps:["bootstrap"]},bootbox:{deps:["jquery","bootstrap"],exports:"bootbox"},morris:{deps:["jquery","raphael"],exports:"Morris"},pnotify:{deps:["jquery"]},easyPieChart:{deps:["jquery"]},dragToSelect:{deps:["jquery"]},hoverIntent:{deps:["jquery"]},fullScreen:{deps:["jquery"]},select2:{deps:["jquery"],exports:"Select2"},validator:{deps:["jquery","bootstrap"]},lazylinepainter:{deps:["jquery","bootstrap"]},blueImpGallery:{deps:["jquery"]},bootstrapConfirmation:{deps:["bootstrap"]},bootstrapToggle:{deps:["jquery"]}}});require.config({baseUrl:jsBaseUrl});requirejs([mainScriptPath]); +//# sourceMappingURL=app.js.map \ No newline at end of file diff --git a/public/js/v0.0.10/app.js.map b/public/js/v0.0.10/app.js.map new file mode 100644 index 00000000..30faa74d --- /dev/null +++ b/public/js/v0.0.10/app.js.map @@ -0,0 +1 @@ +{"version":3,"file":"app.js.map","sources":["app.js.src.js"],"names":["mainScriptPath","document","body","getAttribute","jsBaseUrl","requirejs","config","baseUrl","paths","layout","dialog","templates","img","landingpage","mappage","jquery","bootstrap","text","mustache","velocity","velocityUI","slidebars","jsPlumb","customScrollbar","datatables","datatablesResponsive","datatablesTableTools","xEditable","morris","raphael","bootbox","easyPieChart","dragToSelect","hoverIntent","fullScreen","select2","validator","lazylinepainter","blueImpGallery","blueImpGalleryHelper","blueImpGalleryBootstrap","bootstrapConfirmation","bootstrapToggle","easePack","tweenLite","pnotify","pnotify.buttons","pnotify.confirm","pnotify.nonblock","pnotify.desktop","pnotify.history","pnotify.callbacks","pnotify.reference","shim","deps","datatablesBootstrap","exports","require"],"mappings":"AACA,GAAIA,gBAAiBC,SAASC,KAAKC,aAAa,eAI5CC,UAAYH,SAASC,KAAKC,aAAa,eAG3CE,WAAUC,QACNC,QAAS,KAETC,OACIC,OAAQ,SACRH,OAAQ,aACRI,OAAQ,gBACRC,UAAW,kBACXC,IAAK,YAGLC,YAAa,oBACbC,QAAS,gBAETC,OAAQ,wBACRC,UAAW,oBACXC,KAAM,qBACNC,SAAU,mBACVC,SAAU,mBACVC,WAAY,sBACZC,UAAW,gBACXC,QAAS,4BACTC,gBAAiB,yCACjBC,WAAY,uCAEZC,qBAAsB,6DAEtBC,qBAAsB,gEACtBC,UAAW,6BACXC,OAAQ,iBACRC,QAAS,kBACTC,QAAS,kBACTC,aAAc,8BACdC,aAAc,0BACdC,YAAa,kCACbC,WAAY,4BACZC,QAAS,kBACTC,UAAW,oBACXC,gBAAiB,uCACjBC,eAAgB,sBAChBC,qBAAsB,qBACtBC,wBAAyB,8BACzBC,sBAAuB,6BACvBC,gBAAiB,4BAGjBC,SAAU,mBACVC,UAAW,oBAGXC,QAAS,2BACTC,kBAAmB,8BACnBC,kBAAmB,8BACnBC,mBAAoB,+BACpBC,kBAAmB,8BACnBC,kBAAmB,8BACnBC,oBAAqB,gCACrBC,oBAAqB,iCAGzBC,MACIrC,WACIsC,MAAO,WAEXnC,UACImC,MAAO,WAEXlC,YACIkC,MAAO,aAEXjC,WACIiC,MAAO,WAEX/B,iBACI+B,MAAO,WAEX9B,YACI8B,MAAO,WAEXC,qBACID,MAAO,eAEX7B,sBACI6B,MAAO,eAEX5B,sBACI4B,MAAO,eAEX3B,WACI2B,MAAO,cAEXxB,SACIwB,MAAO,SAAU,aACjBE,QAAS,WAEb5B,QACI0B,MAAO,SAAU,WACjBE,QAAS,UAEbX,SACIS,MAAQ,WAEZvB,cACIuB,MAAQ,WAEZtB,cACIsB,MAAQ,WAEZrB,aACIqB,MAAQ,WAEZpB,YACIoB,MAAQ,WAEZnB,SACImB,MAAQ,UACRE,QAAS,WAEbpB,WACIkB,MAAQ,SAAU,cAEtBjB,iBACIiB,MAAQ,SAAU,cAEtBhB,gBACIgB,MAAQ,WAEZb,uBACIa,MAAQ,cAEZZ,iBACIY,MAAQ,aAQpBG,SAAQnD,QACJC,QAASH,WAIbC,YAAYL"} \ No newline at end of file diff --git a/build_js/app.js.src.js b/public/js/v0.0.10/app.js.src.js similarity index 98% rename from build_js/app.js.src.js rename to public/js/v0.0.10/app.js.src.js index 59f2f641..b60bef4b 100644 --- a/build_js/app.js.src.js +++ b/public/js/v0.0.10/app.js.src.js @@ -13,6 +13,8 @@ requirejs.config({ layout: 'layout', config: 'app/config', // path for "configuration" files dir dialog: 'app/ui/dialog', // path for "dialog" files dir + templates: '../../templates', // template dir + img: '../../img', // images dir // main views landingpage: './app/landingpage', // initial start "landing page" view @@ -24,8 +26,6 @@ requirejs.config({ mustache: 'lib/mustache.min', // v1.0.0 Javascript template engine - http://mustache.github.io/ velocity: 'lib/velocity.min', // v1.2.2 animation engine - http://julian.com/research/velocity/ velocityUI: 'lib/velocity.ui.min', // v5.0.4 plugin for velocity - http://julian.com/research/velocity/#uiPack - templates: '../public/templates', // template dir - img: '../public/img', // images dir slidebars: 'lib/slidebars', // v0.10 Slidebars - side menu plugin http://plugins.adchsm.me/slidebars/ jsPlumb: 'lib/dom.jsPlumb-1.7.6-min', // v1.7.6 jsPlumb (Vanilla)- main map draw plugin https://jsplumbtoolkit.com/ customScrollbar: 'lib/jquery.mCustomScrollbar.concat.min', // v3.0.9 Custom scroll bars - http://manos.malihu.gr/ diff --git a/build_js/app/landingpage.js b/public/js/v0.0.10/app/landingpage.js similarity index 98% rename from build_js/app/landingpage.js rename to public/js/v0.0.10/app/landingpage.js index 2a3981c1..42d407da 100644 --- a/build_js/app/landingpage.js +++ b/public/js/v0.0.10/app/landingpage.js @@ -10,6 +10,6 @@ return a?(this.showLoading(),i={name:this.options.name||"",value:e,pk:n},"functi viewseparator:", "}),t.fn.editabletypes.select2=e}(window.jQuery),function(t){var e=function(e,i){return this.$element=t(e),this.$element.is("input")?(this.options=t.extend({},t.fn.combodate.defaults,i,this.$element.data()),void this.init()):void t.error("Combodate should be applied to INPUT element")};e.prototype={constructor:e,init:function(){this.map={day:["D","date"],month:["M","month"],year:["Y","year"],hour:["[Hh]","hours"],minute:["m","minutes"],second:["s","seconds"],ampm:["[Aa]",""]},this.$widget=t('').html(this.getTemplate()),this.initCombos(),this.$widget.on("change","select",t.proxy(function(e){this.$element.val(this.getValue()).change(),this.options.smartDays&&(t(e.target).is(".month")||t(e.target).is(".year"))&&this.fillCombo("day")},this)),this.$widget.find("select").css("width","auto"),this.$element.hide().after(this.$widget),this.setValue(this.$element.val()||this.options.value)},getTemplate:function(){var e=this.options.template;return t.each(this.map,function(t,i){i=i[0];var n=new RegExp(i+"+"),a=i.length>1?i.substring(1,2):i;e=e.replace(n,"{"+a+"}")}),e=e.replace(/ /g," "),t.each(this.map,function(t,i){i=i[0];var n=i.length>1?i.substring(1,2):i;e=e.replace("{"+n+"}",'')}),e},initCombos:function(){for(var t in this.map){var e=this.$widget.find("."+t);this["$"+t]=e.length?e:null,this.fillCombo(t)}},fillCombo:function(t){var e=this["$"+t];if(e){var i="fill"+t.charAt(0).toUpperCase()+t.slice(1),n=this[i](),a=e.val();e.empty();for(var o=0;o'+n[o][1]+"");e.val(a)}},fillCommon:function(t){var e,i=[];if("name"===this.options.firstItem){e=moment.relativeTime||moment.langData()._relativeTime;var n="function"==typeof e[t]?e[t](1,!0,t,!1):e[t];n=n.split(" ").reverse()[0],i.push(["",n])}else"empty"===this.options.firstItem&&i.push(["",""]);return i},fillDay:function(){var t,e,i=this.fillCommon("d"),n=-1!==this.options.template.indexOf("DD"),a=31;if(this.options.smartDays&&this.$month&&this.$year){var o=parseInt(this.$month.val(),10),s=parseInt(this.$year.val(),10);isNaN(o)||isNaN(s)||(a=moment([s,o]).daysInMonth())}for(e=1;a>=e;e++)t=n?this.leadZero(e):e,i.push([e,t]);return i},fillMonth:function(){var t,e,i=this.fillCommon("M"),n=-1!==this.options.template.indexOf("MMMM"),a=-1!==this.options.template.indexOf("MMM"),o=-1!==this.options.template.indexOf("MM");for(e=0;11>=e;e++)t=n?moment().date(1).month(e).format("MMMM"):a?moment().date(1).month(e).format("MMM"):o?this.leadZero(e+1):e+1,i.push([e,t]);return i},fillYear:function(){var t,e,i=[],n=-1!==this.options.template.indexOf("YYYY");for(e=this.options.maxYear;e>=this.options.minYear;e--)t=n?e:(e+"").substring(2),i[this.options.yearDescending?"push":"unshift"]([e,t]);return i=this.fillCommon("y").concat(i)},fillHour:function(){var t,e,i=this.fillCommon("h"),n=-1!==this.options.template.indexOf("h"),a=(-1!==this.options.template.indexOf("H"),-1!==this.options.template.toLowerCase().indexOf("hh")),o=n?1:0,s=n?12:23;for(e=o;s>=e;e++)t=a?this.leadZero(e):e,i.push([e,t]);return i},fillMinute:function(){var t,e,i=this.fillCommon("m"),n=-1!==this.options.template.indexOf("mm");for(e=0;59>=e;e+=this.options.minuteStep)t=n?this.leadZero(e):e,i.push([e,t]);return i},fillSecond:function(){var t,e,i=this.fillCommon("s"),n=-1!==this.options.template.indexOf("ss");for(e=0;59>=e;e+=this.options.secondStep)t=n?this.leadZero(e):e,i.push([e,t]);return i},fillAmpm:function(){var t=-1!==this.options.template.indexOf("a"),e=(-1!==this.options.template.indexOf("A"),[["am",t?"am":"AM"],["pm",t?"pm":"PM"]]);return e},getValue:function(e){var i,n={},a=this,o=!1;return t.each(this.map,function(t){if("ampm"!==t){var e="day"===t?1:0;return n[t]=a["$"+t]?parseInt(a["$"+t].val(),10):e,isNaN(n[t])?(o=!0,!1):void 0}}),o?"":(this.$ampm&&(n.hour=12===n.hour?"am"===this.$ampm.val()?0:12:"am"===this.$ampm.val()?n.hour:n.hour+12),i=moment([n.year,n.month,n.day,n.hour,n.minute,n.second]),this.highlight(i),e=void 0===e?this.options.format:e,null===e?i.isValid()?i:null:i.isValid()?i.format(e):"")},setValue:function(e){function i(e,i){var n={};return e.children("option").each(function(e,a){var o,s=t(a).attr("value");""!==s&&(o=Math.abs(s-i),("undefined"==typeof n.distance||o=12?(o.ampm="pm",o.hour>12&&(o.hour-=12)):(o.ampm="am",0===o.hour&&(o.hour=12))),t.each(o,function(t,e){a["$"+t]&&("minute"===t&&a.options.minuteStep>1&&a.options.roundTime&&(e=i(a["$"+t],e)),"second"===t&&a.options.secondStep>1&&a.options.roundTime&&(e=i(a["$"+t],e)),a["$"+t].val(e))}),this.options.smartDays&&this.fillCombo("day"),this.$element.val(n.format(this.options.format)).change())}},highlight:function(t){t.isValid()?this.options.errorClass?this.$widget.removeClass(this.options.errorClass):this.$widget.find("select").css("border-color",this.borderColor):this.options.errorClass?this.$widget.addClass(this.options.errorClass):(this.borderColor||(this.borderColor=this.$widget.find("select").css("border-color")),this.$widget.find("select").css("border-color","red"))},leadZero:function(t){return 9>=t?"0"+t:t},destroy:function(){this.$widget.remove(),this.$element.removeData("combodate").show()}},t.fn.combodate=function(i){var n,a=Array.apply(null,arguments);return a.shift(),"getValue"===i&&this.length&&(n=this.eq(0).data("combodate"))?n.getValue.apply(n,a):this.each(function(){var n=t(this),o=n.data("combodate"),s="object"==typeof i&&i;o||n.data("combodate",o=new e(this,s)),"string"==typeof i&&"function"==typeof o[i]&&o[i].apply(o,a)})},t.fn.combodate.defaults={format:"DD-MM-YYYY HH:mm",template:"D / MMM / YYYY H : mm",value:null,minYear:1970,maxYear:2015,yearDescending:!0,minuteStep:5,secondStep:1,firstItem:"empty",errorClass:null,roundTime:!0,smartDays:!1}}(window.jQuery),function(t){"use strict";var e=function(i){this.init("combodate",i,e.defaults),this.options.viewformat||(this.options.viewformat=this.options.format),i.combodate=t.fn.editableutils.tryParseJson(i.combodate,!0),this.options.combodate=t.extend({},e.defaults.combodate,i.combodate,{format:this.options.format,template:this.options.template})};t.fn.editableutils.inherit(e,t.fn.editabletypes.abstractinput),t.extend(e.prototype,{render:function(){this.$input.combodate(this.options.combodate),"bs3"===t.fn.editableform.engine&&this.$input.siblings().find("select").addClass("form-control"),this.options.inputclass&&this.$input.siblings().find("select").addClass(this.options.inputclass)},value2html:function(t,i){var n=t?t.format(this.options.viewformat):"";e.superclass.value2html.call(this,n,i)},html2value:function(t){return t?moment(t,this.options.viewformat):null},value2str:function(t){return t?t.format(this.options.format):""},str2value:function(t){return t?moment(t,this.options.format):null},value2submit:function(t){return this.value2str(t)},value2input:function(t){this.$input.combodate("setValue",t)},input2value:function(){return this.$input.combodate("getValue",null)},activate:function(){this.$input.siblings(".combodate").find("select").eq(0).focus()},autosubmit:function(){}}),e.defaults=t.extend({},t.fn.editabletypes.abstractinput.defaults,{tpl:'',inputclass:null,format:"YYYY-MM-DD",viewformat:null,template:"D / MMM / YYYY",combodate:null}),t.fn.editabletypes.combodate=e}(window.jQuery),function(t){"use strict";var e=t.fn.editableform.Constructor.prototype.initInput;t.extend(t.fn.editableform.Constructor.prototype,{initTemplate:function(){this.$form=t(t.fn.editableform.template),this.$form.find(".control-group").addClass("form-group"),this.$form.find(".editable-error-block").addClass("help-block")},initInput:function(){e.apply(this);var i=null===this.input.options.inputclass||this.input.options.inputclass===!1,n="input-sm",a="text,select,textarea,password,email,url,tel,number,range,time,typeaheadjs".split(",");~t.inArray(this.input.type,a)&&(this.input.$input.addClass("form-control"),i&&(this.input.options.inputclass=n,this.input.$input.addClass(n)));for(var o=this.$form.find(".editable-buttons"),s=i?[n]:this.input.options.inputclass.split(" "),r=0;r',t.fn.editableform.errorGroupClass="has-error",t.fn.editableform.errorBlockClass=null,t.fn.editableform.engine="bs3"}(window.jQuery),function(t){"use strict";t.extend(t.fn.editableContainer.Popup.prototype,{containerName:"popover",containerDataName:"bs.popover",innerCss:".popover-content",defaults:t.fn.popover.Constructor.DEFAULTS,initContainer:function(){t.extend(this.containerOptions,{trigger:"manual",selector:!1,content:" ",template:this.defaults.template});var e;this.$element.data("template")&&(e=this.$element.data("template"),this.$element.removeData("template")),this.call(this.containerOptions),e&&this.$element.data("template",e)},innerShow:function(){this.call("show")},innerHide:function(){this.call("hide")},innerDestroy:function(){this.call("destroy")},setContainerOption:function(t,e){this.container().options[t]=e},setPosition:function(){!function(){var t=this.tip(),e="function"==typeof this.options.placement?this.options.placement.call(this,t[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,n=i.test(e);n&&(e=e.replace(i,"")||"top");var a=this.getPosition(),o=t[0].offsetWidth,s=t[0].offsetHeight;if(n){var r=this.$element.parent(),l=e,c=document.documentElement.scrollTop||document.body.scrollTop,u="body"==this.options.container?window.innerWidth:r.outerWidth(),d="body"==this.options.container?window.innerHeight:r.outerHeight(),h="body"==this.options.container?0:r.offset().left;e="bottom"==e&&a.top+a.height+s-c>d?"top":"top"==e&&a.top-c-s<0?"bottom":"right"==e&&a.right+o>u?"left":"left"==e&&a.left-othis.o.endDate?new Date(this.o.endDate):new Date(this.date),this.fill()}},fillDow:function(){var t=this.o.weekStart,e="";if(this.o.calendarWeeks){var i=' ';e+=i,this.picker.find(".datepicker-days thead tr:first-child").prepend(i)}for(;t'+u[this.o.language].daysMin[t++%7]+"";e+="",this.picker.find(".datepicker-days thead").append(e)},fillMonths:function(){for(var t="",e=0;12>e;)t+=''+u[this.o.language].monthsShort[e++]+"";this.picker.find(".datepicker-months td").html(t)},setRange:function(e){e&&e.length?this.range=t.map(e,function(t){return t.valueOf()}):delete this.range,this.fill()},getClassNames:function(e){var i=[],n=this.viewDate.getUTCFullYear(),a=this.viewDate.getUTCMonth(),o=this.date.valueOf(),s=new Date;return e.getUTCFullYear()n||e.getUTCFullYear()==n&&e.getUTCMonth()>a)&&i.push("new"),this.o.todayHighlight&&e.getUTCFullYear()==s.getFullYear()&&e.getUTCMonth()==s.getMonth()&&e.getUTCDate()==s.getDate()&&i.push("today"),o&&e.valueOf()==o&&i.push("active"),(e.valueOf()this.o.endDate||-1!==t.inArray(e.getUTCDay(),this.o.daysOfWeekDisabled))&&i.push("disabled"),this.range&&(e>this.range[0]&&e"),this.o.calendarWeeks)){var v=new Date(+h+864e5*((this.o.weekStart-h.getUTCDay()-7)%7)),y=new Date(+v+864e5*((11-v.getUTCDay())%7)),b=new Date(+(b=e(y.getUTCFullYear(),0,1))+864e5*((11-b.getUTCDay())%7)),w=(y-b)/864e5/7+1;g.push(''+w+"")}m=this.getClassNames(h),m.push("day");var C=this.o.beforeShowDay(h);void 0===C?C={}:"boolean"==typeof C?C={enabled:C}:"string"==typeof C&&(C={classes:C}),C.enabled===!1&&m.push("disabled"),C.classes&&(m=m.concat(C.classes.split(/\s+/))),C.tooltip&&(i=C.tooltip),m=t.unique(m),g.push('"+h.getUTCDate()+""),h.getUTCDay()==this.o.weekEnd&&g.push(""),h.setUTCDate(h.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").empty().append(g.join(""));var x=this.date&&this.date.getUTCFullYear(),S=this.picker.find(".datepicker-months").find("th:eq(1)").text(a).end().find("span").removeClass("active");x&&x==a&&S.eq(this.date.getUTCMonth()).addClass("active"),(s>a||a>l)&&S.addClass("disabled"),a==s&&S.slice(0,r).addClass("disabled"),a==l&&S.slice(c+1).addClass("disabled"),g="",a=10*parseInt(a/10,10);var T=this.picker.find(".datepicker-years").find("th:eq(1)").text(a+"-"+(a+9)).end().find("td");a-=1;for(var _=-1;11>_;_++)g+='a||a>l?" disabled":"")+'">'+a+"",a+=1;T.html(g)},updateNavArrows:function(){if(this._allow_update){var t=new Date(this.viewDate),e=t.getUTCFullYear(),i=t.getUTCMonth();switch(this.viewMode){case 0:this.o.startDate!==-1/0&&e<=this.o.startDate.getUTCFullYear()&&i<=this.o.startDate.getUTCMonth()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),1/0!==this.o.endDate&&e>=this.o.endDate.getUTCFullYear()&&i>=this.o.endDate.getUTCMonth()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"});break;case 1:case 2:this.o.startDate!==-1/0&&e<=this.o.startDate.getUTCFullYear()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),1/0!==this.o.endDate&&e>=this.o.endDate.getUTCFullYear()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"})}}},click:function(i){i.preventDefault();var n=t(i.target).closest("span, td, th");if(1==n.length)switch(n[0].nodeName.toLowerCase()){case"th":switch(n[0].className){case"datepicker-switch":this.showMode(1);break;case"prev":case"next":var a=d.modes[this.viewMode].navStep*("prev"==n[0].className?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveMonth(this.viewDate,a);break;case 1:case 2:this.viewDate=this.moveYear(this.viewDate,a)}this.fill();break;case"today":var o=new Date;o=e(o.getFullYear(),o.getMonth(),o.getDate(),0,0,0),this.showMode(-2);var s="linked"==this.o.todayBtn?null:"view";this._setDate(o,s);break;case"clear":var r;this.isInput?r=this.element:this.component&&(r=this.element.find("input")),r&&r.val("").change(),this._trigger("changeDate"),this.update(),this.o.autoclose&&this.hide()}break;case"span":if(!n.is(".disabled")){if(this.viewDate.setUTCDate(1),n.is(".month")){var l=1,c=n.parent().find("span").index(n),u=this.viewDate.getUTCFullYear();this.viewDate.setUTCMonth(c),this._trigger("changeMonth",this.viewDate),1===this.o.minViewMode&&this._setDate(e(u,c,l,0,0,0,0))}else{var u=parseInt(n.text(),10)||0,l=1,c=0;this.viewDate.setUTCFullYear(u),this._trigger("changeYear",this.viewDate),2===this.o.minViewMode&&this._setDate(e(u,c,l,0,0,0,0))}this.showMode(-1),this.fill()}break;case"td":if(n.is(".day")&&!n.is(".disabled")){var l=parseInt(n.text(),10)||1,u=this.viewDate.getUTCFullYear(),c=this.viewDate.getUTCMonth();n.is(".old")?0===c?(c=11,u-=1):c-=1:n.is(".new")&&(11==c?(c=0,u+=1):c+=1),this._setDate(e(u,c,l,0,0,0,0))}}},_setDate:function(t,e){e&&"date"!=e||(this.date=new Date(t)),e&&"view"!=e||(this.viewDate=new Date(t)),this.fill(),this.setValue(),this._trigger("changeDate");var i;this.isInput?i=this.element:this.component&&(i=this.element.find("input")),i&&(i.change(),!this.o.autoclose||e&&"date"!=e||this.hide())},moveMonth:function(t,e){if(!e)return t;var i,n,a=new Date(t.valueOf()),o=a.getUTCDate(),s=a.getUTCMonth(),r=Math.abs(e);if(e=e>0?1:-1,1==r)n=-1==e?function(){return a.getUTCMonth()==s}:function(){return a.getUTCMonth()!=i},i=s+e,a.setUTCMonth(i),(0>i||i>11)&&(i=(i+12)%12);else{for(var l=0;r>l;l++)a=this.moveMonth(a,e);i=a.getUTCMonth(),a.setUTCDate(o),n=function(){return i!=a.getUTCMonth()}}for(;n();)a.setUTCDate(--o),a.setUTCMonth(i);return a},moveYear:function(t,e){return this.moveMonth(t,12*e)},dateWithinRange:function(t){return t>=this.o.startDate&&t<=this.o.endDate},keydown:function(t){if(this.picker.is(":not(:visible)"))return void(27==t.keyCode&&this.show());var e,i,n,a=!1;switch(t.keyCode){case 27:this.hide(),t.preventDefault();break;case 37:case 39:if(!this.o.keyboardNavigation)break;e=37==t.keyCode?-1:1,t.ctrlKey?(i=this.moveYear(this.date,e),n=this.moveYear(this.viewDate,e)):t.shiftKey?(i=this.moveMonth(this.date,e),n=this.moveMonth(this.viewDate,e)):(i=new Date(this.date),i.setUTCDate(this.date.getUTCDate()+e),n=new Date(this.viewDate),n.setUTCDate(this.viewDate.getUTCDate()+e)),this.dateWithinRange(i)&&(this.date=i,this.viewDate=n,this.setValue(),this.update(),t.preventDefault(),a=!0);break;case 38:case 40:if(!this.o.keyboardNavigation)break;e=38==t.keyCode?-1:1,t.ctrlKey?(i=this.moveYear(this.date,e),n=this.moveYear(this.viewDate,e)):t.shiftKey?(i=this.moveMonth(this.date,e),n=this.moveMonth(this.viewDate,e)):(i=new Date(this.date),i.setUTCDate(this.date.getUTCDate()+7*e),n=new Date(this.viewDate),n.setUTCDate(this.viewDate.getUTCDate()+7*e)),this.dateWithinRange(i)&&(this.date=i,this.viewDate=n,this.setValue(),this.update(),t.preventDefault(),a=!0);break;case 13:this.hide(),t.preventDefault();break;case 9:this.hide()}if(a){this._trigger("changeDate");var o;this.isInput?o=this.element:this.component&&(o=this.element.find("input")),o&&o.change()}},showMode:function(t){t&&(this.viewMode=Math.max(this.o.minViewMode,Math.min(2,this.viewMode+t))),this.picker.find(">div").hide().filter(".datepicker-"+d.modes[this.viewMode].clsName).css("display","block"),this.updateNavArrows()}};var o=function(e,i){this.element=t(e),this.inputs=t.map(i.inputs,function(t){return t.jquery?t[0]:t}),delete i.inputs,t(this.inputs).datepicker(i).bind("changeDate",t.proxy(this.dateUpdated,this)),this.pickers=t.map(this.inputs,function(e){return t(e).data("datepicker")}),this.updateDates()};o.prototype={updateDates:function(){this.dates=t.map(this.pickers,function(t){return t.date}),this.updateRanges()},updateRanges:function(){var e=t.map(this.dates,function(t){return t.valueOf()});t.each(this.pickers,function(t,i){i.setRange(e)})},dateUpdated:function(e){var i=t(e.target).data("datepicker"),n=i.getUTCDate(),a=t.inArray(e.target,this.inputs),o=this.inputs.length;if(-1!=a){if(n=0&&nthis.dates[a])for(;o>a&&n>this.dates[a];)this.pickers[a++].setUTCDate(n);this.updateDates()}},remove:function(){t.map(this.pickers,function(t){t.remove()}),delete this.element.data().datepicker}};var s=t.fn.datepicker,r=t.fn.datepicker=function(e){var s=Array.apply(null,arguments);s.shift();var r;return this.each(function(){var c=t(this),u=c.data("datepicker"),d="object"==typeof e&&e;if(!u){var h=i(this,"date"),p=t.extend({},l,h,d),f=n(p.language),m=t.extend({},l,f,h,d);if(c.is(".input-daterange")||m.inputs){var g={inputs:m.inputs||c.find("input").toArray()};c.data("datepicker",u=new o(this,t.extend(m,g)))}else c.data("datepicker",u=new a(this,m))}return"string"==typeof e&&"function"==typeof u[e]&&(r=u[e].apply(u,s),void 0!==r)?!1:void 0}),void 0!==r?r:this},l=t.fn.datepicker.defaults={autoclose:!1,beforeShowDay:t.noop,calendarWeeks:!1,clearBtn:!1,daysOfWeekDisabled:[],endDate:1/0,forceParse:!0,format:"mm/dd/yyyy",keyboardNavigation:!0,language:"en",minViewMode:0,rtl:!1,startDate:-1/0,startView:0,todayBtn:!1,todayHighlight:!1,weekStart:0},c=t.fn.datepicker.locale_opts=["format","rtl","weekStart"];t.fn.datepicker.Constructor=a;var u=t.fn.datepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today",clear:"Clear"}},d={modes:[{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(t){return 0===t%4&&0!==t%100||0===t%400},getDaysInMonth:function(t,e){return[31,d.isLeapYear(t)?29:28,31,30,31,30,31,31,30,31,30,31][e]},validParts:/dd?|DD?|mm?|MM?|yy(?:yy)?/g,nonpunctuation:/[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,parseFormat:function(t){var e=t.replace(this.validParts,"\x00").split("\x00"),i=t.match(this.validParts);if(!e||!e.length||!i||0===i.length)throw new Error("Invalid date format.");return{separators:e,parts:i}},parseDate:function(i,n,o){if(i instanceof Date)return i;if("string"==typeof n&&(n=d.parseFormat(n)),/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(i)){var s,r,l=/([\-+]\d+)([dmwy])/,c=i.match(/([\-+]\d+)([dmwy])/g);i=new Date;for(var h=0;he;)e+=12;for(e%=12,t.setUTCMonth(e);t.getUTCMonth()!=e;)t.setUTCDate(t.getUTCDate()-1);return t},d:function(t,e){return t.setUTCDate(e)}};v.M=v.MM=v.mm=v.m,v.dd=v.d,i=e(i.getFullYear(),i.getMonth(),i.getDate(),0,0,0);var y=n.parts.slice();if(c.length!=y.length&&(y=t(y).filter(function(e,i){return-1!==t.inArray(i,g)}).toArray()),c.length==y.length){for(var h=0,b=y.length;b>h;h++){if(p=parseInt(c[h],10),s=y[h],isNaN(p))switch(s){case"MM":f=t(u[o].months).filter(function(){var t=this.slice(0,c[h].length),e=c[h].slice(0,t.length);return t==e}),p=t.inArray(f[0],u[o].months)+1;break;case"M":f=t(u[o].monthsShort).filter(function(){var t=this.slice(0,c[h].length),e=c[h].slice(0,t.length);return t==e}),p=t.inArray(f[0],u[o].monthsShort)+1}m[s]=p}for(var w,h=0;h=s;s++)o.length&&e.push(o.shift()),e.push(a[i.parts[s]]);return e.join("")},headTemplate:'',contTemplate:'',footTemplate:''};d.template='
'+d.headTemplate+""+d.footTemplate+'
'+d.headTemplate+d.contTemplate+d.footTemplate+'
'+d.headTemplate+d.contTemplate+d.footTemplate+"
",t.fn.datepicker.DPGlobal=d,t.fn.datepicker.noConflict=function(){return t.fn.datepicker=s,this},t(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(e){var i=t(this);i.data("datepicker")||(e.preventDefault(),r.call(i,"show"))}),t(function(){r.call(t('[data-provide="datepicker-inline"]'))})}(window.jQuery),function(t){"use strict";t.fn.bdatepicker=t.fn.datepicker.noConflict(),t.fn.datepicker||(t.fn.datepicker=t.fn.bdatepicker);var e=function(t){this.init("date",t,e.defaults),this.initPicker(t,e.defaults)};t.fn.editableutils.inherit(e,t.fn.editabletypes.abstractinput),t.extend(e.prototype,{ initPicker:function(e,i){this.options.viewformat||(this.options.viewformat=this.options.format),e.datepicker=t.fn.editableutils.tryParseJson(e.datepicker,!0),this.options.datepicker=t.extend({},i.datepicker,e.datepicker,{format:this.options.viewformat}),this.options.datepicker.language=this.options.datepicker.language||"en",this.dpg=t.fn.bdatepicker.DPGlobal,this.parsedFormat=this.dpg.parseFormat(this.options.format),this.parsedViewFormat=this.dpg.parseFormat(this.options.viewformat)},render:function(){this.$input.bdatepicker(this.options.datepicker),this.options.clear&&(this.$clear=t('').html(this.options.clear).click(t.proxy(function(t){t.preventDefault(),t.stopPropagation(),this.clear()},this)),this.$tpl.parent().append(t('
').append(this.$clear)))},value2html:function(t,i){var n=t?this.dpg.formatDate(t,this.parsedViewFormat,this.options.datepicker.language):"";e.superclass.value2html.call(this,n,i)},html2value:function(t){return this.parseDate(t,this.parsedViewFormat)},value2str:function(t){return t?this.dpg.formatDate(t,this.parsedFormat,this.options.datepicker.language):""},str2value:function(t){return this.parseDate(t,this.parsedFormat)},value2submit:function(t){return this.value2str(t)},value2input:function(t){this.$input.bdatepicker("update",t)},input2value:function(){return this.$input.data("datepicker").date},activate:function(){},clear:function(){this.$input.data("datepicker").date=null,this.$input.find(".active").removeClass("active"),this.options.showbuttons||this.$input.closest("form").submit()},autosubmit:function(){this.$input.on("mouseup",".day",function(e){if(!t(e.currentTarget).is(".old")&&!t(e.currentTarget).is(".new")){var i=t(this).closest("form");setTimeout(function(){i.submit()},200)}})},parseDate:function(t,e){var i,n=null;return t&&(n=this.dpg.parseDate(t,e,this.options.datepicker.language),"string"==typeof t&&(i=this.dpg.formatDate(n,e,this.options.datepicker.language),t!==i&&(n=null))),n}}),e.defaults=t.extend({},t.fn.editabletypes.abstractinput.defaults,{tpl:'
',inputclass:null,format:"yyyy-mm-dd",viewformat:null,datepicker:{weekStart:0,startView:0,minViewMode:0,autoclose:!1},clear:"× clear"}),t.fn.editabletypes.date=e}(window.jQuery),function(t){"use strict";var e=function(t){this.init("datefield",t,e.defaults),this.initPicker(t,e.defaults)};t.fn.editableutils.inherit(e,t.fn.editabletypes.date),t.extend(e.prototype,{render:function(){this.$input=this.$tpl.find("input"),this.setClass(),this.setAttr("placeholder"),this.$tpl.bdatepicker(this.options.datepicker),this.$input.off("focus keydown"),this.$input.keyup(t.proxy(function(){this.$tpl.removeData("date"),this.$tpl.bdatepicker("update")},this))},value2input:function(t){this.$input.val(t?this.dpg.formatDate(t,this.parsedViewFormat,this.options.datepicker.language):""),this.$tpl.bdatepicker("update")},input2value:function(){return this.html2value(this.$input.val())},activate:function(){t.fn.editabletypes.text.prototype.activate.call(this)},autosubmit:function(){}}),e.defaults=t.extend({},t.fn.editabletypes.date.defaults,{tpl:'
',inputclass:"input-small",datepicker:{weekStart:0,startView:0,minViewMode:0,autoclose:!0}}),t.fn.editabletypes.datefield=e}(window.jQuery),function(t){"use strict";var e=function(t){this.init("datetime",t,e.defaults),this.initPicker(t,e.defaults)};t.fn.editableutils.inherit(e,t.fn.editabletypes.abstractinput),t.extend(e.prototype,{initPicker:function(e,i){this.options.viewformat||(this.options.viewformat=this.options.format),e.datetimepicker=t.fn.editableutils.tryParseJson(e.datetimepicker,!0),this.options.datetimepicker=t.extend({},i.datetimepicker,e.datetimepicker,{format:this.options.viewformat}),this.options.datetimepicker.language=this.options.datetimepicker.language||"en",this.dpg=t.fn.datetimepicker.DPGlobal,this.parsedFormat=this.dpg.parseFormat(this.options.format,this.options.formatType),this.parsedViewFormat=this.dpg.parseFormat(this.options.viewformat,this.options.formatType)},render:function(){this.$input.datetimepicker(this.options.datetimepicker),this.$input.on("changeMode",function(){var e=t(this).closest("form").parent();setTimeout(function(){e.triggerHandler("resize")},0)}),this.options.clear&&(this.$clear=t('').html(this.options.clear).click(t.proxy(function(t){t.preventDefault(),t.stopPropagation(),this.clear()},this)),this.$tpl.parent().append(t('
').append(this.$clear)))},value2html:function(t,i){var n=t?this.dpg.formatDate(this.toUTC(t),this.parsedViewFormat,this.options.datetimepicker.language,this.options.formatType):"";return i?void e.superclass.value2html.call(this,n,i):n},html2value:function(t){var e=this.parseDate(t,this.parsedViewFormat);return e?this.fromUTC(e):null},value2str:function(t){return t?this.dpg.formatDate(this.toUTC(t),this.parsedFormat,this.options.datetimepicker.language,this.options.formatType):""},str2value:function(t){var e=this.parseDate(t,this.parsedFormat);return e?this.fromUTC(e):null},value2submit:function(t){return this.value2str(t)},value2input:function(t){t&&this.$input.data("datetimepicker").setDate(t)},input2value:function(){var t=this.$input.data("datetimepicker");return t.date?t.getDate():null},activate:function(){},clear:function(){this.$input.data("datetimepicker").date=null,this.$input.find(".active").removeClass("active"),this.options.showbuttons||this.$input.closest("form").submit()},autosubmit:function(){this.$input.on("mouseup",".minute",function(){var e=t(this).closest("form");setTimeout(function(){e.submit()},200)})},toUTC:function(t){return t?new Date(t.valueOf()-6e4*t.getTimezoneOffset()):t},fromUTC:function(t){return t?new Date(t.valueOf()+6e4*t.getTimezoneOffset()):t},parseDate:function(t,e){var i,n=null;return t&&(n=this.dpg.parseDate(t,e,this.options.datetimepicker.language,this.options.formatType),"string"==typeof t&&(i=this.dpg.formatDate(n,e,this.options.datetimepicker.language,this.options.formatType),t!==i&&(n=null))),n}}),e.defaults=t.extend({},t.fn.editabletypes.abstractinput.defaults,{tpl:'
',inputclass:null,format:"yyyy-mm-dd hh:ii",formatType:"standard",viewformat:null,datetimepicker:{todayHighlight:!1,autoclose:!1},clear:"× clear"}),t.fn.editabletypes.datetime=e}(window.jQuery),function(t){"use strict";var e=function(t){this.init("datetimefield",t,e.defaults),this.initPicker(t,e.defaults)};t.fn.editableutils.inherit(e,t.fn.editabletypes.datetime),t.extend(e.prototype,{render:function(){this.$input=this.$tpl.find("input"),this.setClass(),this.setAttr("placeholder"),this.$tpl.datetimepicker(this.options.datetimepicker),this.$input.off("focus keydown"),this.$input.keyup(t.proxy(function(){this.$tpl.removeData("date"),this.$tpl.datetimepicker("update")},this))},value2input:function(t){this.$input.val(this.value2html(t)),this.$tpl.datetimepicker("update")},input2value:function(){return this.html2value(this.$input.val())},activate:function(){t.fn.editabletypes.text.prototype.activate.call(this)},autosubmit:function(){}}),e.defaults=t.extend({},t.fn.editabletypes.datetime.defaults,{tpl:'
',inputclass:"input-medium",datetimepicker:{todayHighlight:!1,autoclose:!0}}),t.fn.editabletypes.datetimefield=e}(window.jQuery);define("xEditable",["bootstrap"],function(){});!function(t,e){"object"==typeof exports?module.exports=e(require("jquery")):"function"==typeof define&&define.amd?define("easyPieChart",["jquery"],e):e(t.jQuery)}(this,function(t){var e=function(t,e){var i,n=document.createElement("canvas");t.appendChild(n),"undefined"!=typeof G_vmlCanvasManager&&G_vmlCanvasManager.initElement(n);var a=n.getContext("2d");n.width=n.height=e.size;var o=1;window.devicePixelRatio>1&&(o=window.devicePixelRatio,n.style.width=n.style.height=[e.size,"px"].join(""),n.width=n.height=e.size*o,a.scale(o,o)),a.translate(e.size/2,e.size/2),a.rotate((-.5+e.rotate/180)*Math.PI);var s=(e.size-e.lineWidth)/2;e.scaleColor&&e.scaleLength&&(s-=e.scaleLength+2),Date.now=Date.now||function(){return+new Date};var r=function(t,e,i){i=Math.min(Math.max(-1,i||0),1);var n=0>=i?!0:!1;a.beginPath(),a.arc(0,0,s,0,2*Math.PI*i,n),a.strokeStyle=t,a.lineWidth=e,a.stroke()},l=function(){var t,i;a.lineWidth=1,a.fillStyle=e.scaleColor,a.save();for(var n=24;n>0;--n)n%6===0?(i=e.scaleLength,t=0):(i=.6*e.scaleLength,t=e.scaleLength-i),a.fillRect(-e.size/2+t,0,i,1),a.rotate(Math.PI/12);a.restore()},c=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(t){window.setTimeout(t,1e3/60)}}(),u=function(){e.scaleColor&&l(),e.trackColor&&r(e.trackColor,e.trackWidth||e.lineWidth,1)};this.getCanvas=function(){return n},this.getCtx=function(){return a},this.clear=function(){a.clearRect(e.size/-2,e.size/-2,e.size,e.size)},this.draw=function(t){e.scaleColor||e.trackColor?a.getImageData&&a.putImageData?i?a.putImageData(i,0,0):(u(),i=a.getImageData(0,0,e.size*o,e.size*o)):(this.clear(),u()):this.clear(),a.lineCap=e.lineCap;var n;n="function"==typeof e.barColor?e.barColor(t):e.barColor,r(n,e.lineWidth,t/100)}.bind(this),this.animate=function(t,i){var n=Date.now();e.onStart(t,i);var a=function(){var o=Math.min(Date.now()-n,e.animate.duration),s=e.easing(this,o,t,i-t,e.animate.duration);this.draw(s),e.onStep(t,i,s),o>=e.animate.duration?e.onStop(t,i):c(a)}.bind(this);c(a)}.bind(this)},i=function(t,i){var n={barColor:"#ef1e25",trackColor:"#f9f9f9",scaleColor:"#dfe0e0",scaleLength:5,lineCap:"round",lineWidth:3,trackWidth:void 0,size:110,rotate:0,animate:{duration:1e3,enabled:!0},easing:function(t,e,i,n,a){return e/=a/2,1>e?n/2*e*e+i:-n/2*(--e*(e-2)-1)+i},onStart:function(){},onStep:function(){},onStop:function(){}};if("undefined"!=typeof e)n.renderer=e;else{if("undefined"==typeof SVGRenderer)throw new Error("Please load either the SVG- or the CanvasRenderer");n.renderer=SVGRenderer}var a={},o=0,s=function(){this.el=t,this.options=a;for(var e in n)n.hasOwnProperty(e)&&(a[e]=i&&"undefined"!=typeof i[e]?i[e]:n[e],"function"==typeof a[e]&&(a[e]=a[e].bind(this)));a.easing="string"==typeof a.easing&&"undefined"!=typeof jQuery&&jQuery.isFunction(jQuery.easing[a.easing])?jQuery.easing[a.easing]:n.easing,"number"==typeof a.animate&&(a.animate={duration:a.animate,enabled:!0}),"boolean"!=typeof a.animate||a.animate||(a.animate={duration:1e3,enabled:a.animate}),this.renderer=new a.renderer(t,a),this.renderer.draw(o),t.dataset&&t.dataset.percent?this.update(parseFloat(t.dataset.percent)):t.getAttribute&&t.getAttribute("data-percent")&&this.update(parseFloat(t.getAttribute("data-percent")))}.bind(this);this.update=function(t){return t=parseFloat(t),a.animate.enabled?this.renderer.animate(o,t):this.renderer.draw(t),o=t,this}.bind(this),this.disableAnimation=function(){return a.animate.enabled=!1,this},this.enableAnimation=function(){return a.animate.enabled=!0,this},s()};t.fn.easyPieChart=function(e){return this.each(function(){var n;t.data(this,"easyPieChart")||(n=t.extend({},e,t(this).data()),t.data(this,"easyPieChart",new i(this,n)))})}});!function(t){t.fn.hoverIntent=function(e,i,n){var a={interval:100,sensitivity:6,timeout:0};a="object"==typeof e?t.extend(a,e):t.isFunction(i)?t.extend(a,{over:e,out:i,selector:n}):t.extend(a,{over:e,out:e,selector:i});var o,s,r,l,c=function(t){o=t.pageX;s=t.pageY},u=function(e,i){i.hoverIntent_t=clearTimeout(i.hoverIntent_t);if(Math.sqrt((r-o)*(r-o)+(l-s)*(l-s))

'});i.prototype=t.extend({},t.fn.popover.Constructor.prototype);i.prototype.constructor=i;i.prototype.getDefaults=function(){return i.DEFAULTS};i.prototype.setContent=function(){var e=this,i=this.tip(),n=this.getTitle(),a=i.find('[data-apply="confirmation"]'),o=i.find('[data-dismiss="confirmation"]'),s=this.options;a.addClass(this.getBtnOkClass()).html(this.getBtnOkLabel()).prepend(t("").addClass(this.getBtnOkIcon())," ").attr("href",this.getHref()).attr("target",this.getTarget()).off("click").on("click",function(t){e.$element.confirmation("hide");s.onConfirm(t,e.$element)});o.addClass(this.getBtnCancelClass()).html(this.getBtnCancelLabel()).prepend(t("").addClass(this.getBtnCancelIcon())," ").off("click").on("click",function(t){s.onCancel(t,e.$element);e.$element.confirmation("hide")});i.find(".popover-title")[this.options.html?"html":"text"](n);i.removeClass("fade top bottom left right in");i.find(".popover-title").html()||i.find(".popover-title").hide()};i.prototype.getBtnOkClass=function(){var t=this.$element,e=this.options;return t.attr("data-btnOkClass")||("function"==typeof e.btnOkClass?e.btnOkClass.call(t[0]):e.btnOkClass)};i.prototype.getBtnOkLabel=function(){var t=this.$element,e=this.options;return t.attr("data-btnOkLabel")||("function"==typeof e.btnOkLabel?e.btnOkLabel.call(t[0]):e.btnOkLabel)};i.prototype.getBtnOkIcon=function(){var t=this.$element,e=this.options;return t.attr("data-btnOkIcon")||("function"==typeof e.btnOkIcon?e.btnOkIcon.call(t[0]):e.btnOkIcon)};i.prototype.getBtnCancelClass=function(){var t=this.$element,e=this.options;return t.attr("data-btnCancelClass")||("function"==typeof e.btnCancelClass?e.btnCancelClass.call(t[0]):e.btnCancelClass)};i.prototype.getBtnCancelLabel=function(){var t=this.$element,e=this.options;return t.attr("data-btnCancelLabel")||("function"==typeof e.btnCancelLabel?e.btnCancelLabel.call(t[0]):e.btnCancelLabel)};i.prototype.getBtnCancelIcon=function(){var t=this.$element,e=this.options;return t.attr("data-btnCancelIcon")||("function"==typeof e.btnCancelIcon?e.btnCancelIcon.call(t[0]):e.btnCancelIcon)};i.prototype.getHref=function(){var t=this.$element,e=this.options;return t.attr("data-href")||("function"==typeof e.href?e.href.call(t[0]):e.href)};i.prototype.getTarget=function(){var t=this.$element,e=this.options;return t.attr("data-target")||("function"==typeof e.target?e.target.call(t[0]):e.target)};i.prototype.isPopout=function(){var t,e=this.$element,i=this.options;t=e.attr("data-popout")||("function"==typeof i.popout?i.popout.call(e[0]):i.popout);"false"==t&&(t=!1);return t};var n=t.fn.confirmation;t.fn.confirmation=function(e){var n=this;return this.each(function(){var a=t(this),o=a.data("bs.confirmation"),s="object"==typeof e&&e;s=s||{};s.all_selector=n.selector;if(o||"destroy"!=e){o||a.data("bs.confirmation",o=new i(this,s));"string"==typeof e&&o[e]()}})};t.fn.confirmation.Constructor=i;t.fn.confirmation.noConflict=function(){t.fn.confirmation=n;return this}}(jQuery);define("bootstrapConfirmation",["bootstrap"],function(){});+function(t){"use strict";function e(e){return this.each(function(){var n=t(this),a=n.data("bs.toggle"),o="object"==typeof e&&e;a||n.data("bs.toggle",a=new i(this,o)),"string"==typeof e&&a[e]&&a[e]()})}var i=function(e,i){this.$element=t(e),this.options=t.extend({},this.defaults(),i),this.render()};i.VERSION="2.2.0",i.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"default",size:"normal",style:"",width:null,height:null},i.prototype.defaults=function(){return{on:this.$element.attr("data-on")||i.DEFAULTS.on,off:this.$element.attr("data-off")||i.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||i.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||i.DEFAULTS.offstyle,size:this.$element.attr("data-size")||i.DEFAULTS.size,style:this.$element.attr("data-style")||i.DEFAULTS.style,width:this.$element.attr("data-width")||i.DEFAULTS.width,height:this.$element.attr("data-height")||i.DEFAULTS.height}},i.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var e="large"===this.options.size?"btn-large":"small"===this.options.size?"btn-small":"mini"===this.options.size?"btn-mini":"",i=t('