├── Procfile ├── tests ├── mocha │ ├── data │ │ ├── map_0_name.dat │ │ ├── map_1_name.dat │ │ ├── map_2_name.dat │ │ ├── map_3_name.dat │ │ ├── map_0.dat │ │ └── mapitem.json │ ├── test-server-helper.js │ └── test-server.js ├── casperjs │ └── testdata │ │ └── 2013-10-18_00.28.30.png └── yadda │ ├── main_test.js │ ├── features │ └── createMinecraftMapsClientSide.feature │ └── main_steps.js ├── .travis.yml ├── src ├── server │ ├── .jshintrc │ └── server.js └── client │ ├── commandblock.js │ ├── settings.js │ ├── commandblock_worker.js │ └── main.js ├── assets ├── img │ └── logo_bg.png ├── css │ └── main.css └── html │ ├── faq.html │ ├── commandblock.html │ ├── settings.html │ └── index.html ├── vendor ├── img │ ├── glyphicons-halflings.png │ └── glyphicons-halflings-white.png ├── js │ ├── cookies.min.js │ ├── Colour.js │ └── bootstrap.min.js └── css │ ├── bootstrap-theme.min.css │ └── bootstrap-theme.css ├── .gitignore ├── package.json ├── README.md ├── gulpfile.js └── LICENSE /Procfile: -------------------------------------------------------------------------------- 1 | web: npm start -------------------------------------------------------------------------------- /tests/mocha/data/map_0_name.dat: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/mocha/data/map_1_name.dat: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/mocha/data/map_2_name.dat: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/mocha/data/map_3_name.dat: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6" -------------------------------------------------------------------------------- /src/server/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esnext": true, 4 | "onevar": true 5 | } -------------------------------------------------------------------------------- /assets/img/logo_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djfun/mc-map-item-tool/HEAD/assets/img/logo_bg.png -------------------------------------------------------------------------------- /tests/mocha/data/map_0.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djfun/mc-map-item-tool/HEAD/tests/mocha/data/map_0.dat -------------------------------------------------------------------------------- /vendor/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djfun/mc-map-item-tool/HEAD/vendor/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /vendor/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djfun/mc-map-item-tool/HEAD/vendor/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /tests/casperjs/testdata/2013-10-18_00.28.30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djfun/mc-map-item-tool/HEAD/tests/casperjs/testdata/2013-10-18_00.28.30.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/casperjs 2 | node_modules/phantomjs 3 | node_modules/yadda 4 | node_modules/async 5 | node_modules/node-nbt 6 | node_modules/node-static 7 | node_modules/archiver 8 | node_modules/.bin 9 | node_modules/mkdirp 10 | node_modules/gulp 11 | node_modules/del 12 | node_modules/merge-stream 13 | node_modules/gulp-babel 14 | node_modules/babel 15 | node_modules/moment 16 | node_modules/mocha 17 | node_modules/chai 18 | node_modules/gulp-mocha 19 | node_modules/lazystream 20 | node_modules/gulp-casperjs 21 | node_modules/gulp-shell 22 | node_modules/require-dir 23 | node_modules/winston 24 | assets/html/google* 25 | public/* 26 | lib/* 27 | log/* -------------------------------------------------------------------------------- /src/client/commandblock.js: -------------------------------------------------------------------------------- 1 | document.getElementById("submit").addEventListener("click", create_command, false); 2 | 3 | function create_command(event) { 4 | var mapnumber = $('#mapnumber').val(); 5 | var map_parts_horizontal = $('#map_parts_horizontal').val(); 6 | var map_parts_vertical = $('#map_parts_vertical').val(); 7 | var direction = $('#direction').val(); 8 | 9 | var worker = new Worker("commandblock_worker.js"); 10 | 11 | worker.postMessage({mapnumber: mapnumber, 12 | count: map_parts_horizontal * map_parts_vertical, 13 | dim_vertical: map_parts_vertical, 14 | direction: direction}); 15 | 16 | worker.onmessage = function(oEvent) { 17 | $('#output').val(oEvent.data); 18 | }; 19 | 20 | 21 | } -------------------------------------------------------------------------------- /tests/mocha/test-server-helper.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var querystring = require('querystring'); 3 | 4 | function doPostRequest(path, data, callback) { 5 | var dataString = querystring.stringify(data); 6 | var body = ''; 7 | var postRequest = http.request({ 8 | host: 'localhost', 9 | port: 3000, 10 | path: path, 11 | method: 'POST', 12 | headers: { 13 | 'Content-Type': 'application/x-www-form-urlencoded', 14 | 'Content-Length': dataString.length 15 | }}, function(res) { 16 | res.on('data', function(chunk) { 17 | body += chunk; 18 | }); 19 | res.on('end', function() { 20 | callback(res, body); 21 | }); 22 | }); 23 | postRequest.write(dataString); 24 | postRequest.end(); 25 | } 26 | 27 | function doGetRequest(path, callback) { 28 | var body = ''; 29 | http.get({host: 'localhost', port: 3000, path: path}, function(res) { 30 | res.on('data', function(chunk) { 31 | body += chunk; 32 | }); 33 | res.on('end', function() { 34 | callback(res, body); 35 | }); 36 | }); 37 | } 38 | 39 | module.exports.doPostRequest = doPostRequest; 40 | module.exports.doGetRequest = doGetRequest; -------------------------------------------------------------------------------- /vendor/js/cookies.min.js: -------------------------------------------------------------------------------- 1 | /*! Cookies.js - 0.2.1; Copyright (c) 2012, Scott Hamper; http://www.opensource.org/licenses/MIT */ 2 | (function(f,e){var b=function(c,d,a){return 1===arguments.length?b.get(c):b.set(c,d,a)};b.get=function(c){f.cookie!==b._cacheString&&b._populateCache();return b._cache[c]};b.defaults={path:"/"};b.set=function(c,d,a){a={path:a&&a.path||b.defaults.path,domain:a&&a.domain||b.defaults.domain,expires:a&&a.expires||b.defaults.expires,secure:a&&a.secure!==e?a.secure:b.defaults.secure};d===e&&(a.expires=-1);switch(typeof a.expires){case "number":a.expires=new Date((new Date).getTime()+1E3*a.expires);break; 3 | case "string":a.expires=new Date(a.expires)}c=encodeURIComponent(c)+"="+(d+"").replace(/[^!#-+\--:<-\[\]-~]/g,encodeURIComponent);c+=a.path?";path="+a.path:"";c+=a.domain?";domain="+a.domain:"";c+=a.expires?";expires="+a.expires.toGMTString():"";c+=a.secure?";secure":"";f.cookie=c;return b};b.expire=function(c,d){return b.set(c,e,d)};b._populateCache=function(){b._cache={};b._cacheString=f.cookie;for(var c=b._cacheString.split("; "),d=0;d=18" 26 | }, 27 | "devDependencies": { 28 | "async": "^3.2.4", 29 | "babel-cli": "^6.26.0", 30 | "babel-core": "^6.26.3", 31 | "casperjs": "^1.1.4", 32 | "chai": "^4.3.7", 33 | "gulp": "^4.0.2", 34 | "gulp-babel": "^8.0.0", 35 | "gulp-casperjs": "^0.0.7", 36 | "gulp-mocha": "^8.0.0", 37 | "merge-stream": "^2.0.0", 38 | "mkdirp": "^3.0.1", 39 | "mocha": "^10.2.0", 40 | "phantomjs-prebuilt": "^2.1.16", 41 | "require-dir": "^1.2.0", 42 | "yadda": "^2.2.0" 43 | }, 44 | "dependencies": { 45 | "archiver": "^5.3.1", 46 | "babel-polyfill": "^6.26.0", 47 | "lazystream": "^1.0.1", 48 | "moment": "^2.29.4", 49 | "node-nbt": "^1.0.0", 50 | "node-static": "^0.7.11", 51 | "winston": "^3.8.2" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/yadda/main_test.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var async = require(fs.workingDirectory + '/node_modules/async/dist/async'); 3 | var Yadda = require(fs.workingDirectory + '/node_modules/yadda/lib/index'); 4 | var xpath = require('casper').selectXPath; 5 | 6 | var English = Yadda.localisation.English; 7 | 8 | var parser = new Yadda.parsers.FeatureParser(); 9 | var library = require(fs.workingDirectory + '/tests/yadda/main_steps').init(); 10 | var yadda = new Yadda.Yadda(library); 11 | Yadda.plugins.casper(yadda, casper); 12 | 13 | new Yadda.FeatureFileSearch(fs.workingDirectory + '/tests/yadda/features').each(function(file) { 14 | console.log(file); 15 | var feature = parser.parse(fs.read(file)); 16 | 17 | // casper.options.verbose = true; 18 | // casper.options.logLevel ="debug"; 19 | 20 | casper.on('remote.message', function(message) { 21 | this.echo(message); 22 | }); 23 | 24 | casper.on("page.error", function(msg, trace) { 25 | this.echo("Error: " + msg, "ERROR"); 26 | }); 27 | 28 | casper.test.begin(feature.title, function suite(test) { 29 | async.eachSeries(feature.scenarios, function(scenario, next) { 30 | casper.options.viewportSize = {width: 1024, height: 768}; 31 | casper.start(); 32 | console.log(""); 33 | casper.test.info(scenario.title); 34 | console.log(""); 35 | casper.yadda(scenario.steps); 36 | casper.run(function() { 37 | next(); 38 | }); 39 | }, function(err) { 40 | casper.test.done(); 41 | }); 42 | }); 43 | 44 | }); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | mc-map-item-tool [![Build Status](https://travis-ci.org/djfun/mc-map-item-tool.png?branch=master)](https://travis-ci.org/djfun/mc-map-item-tool) 2 | ================ 3 | 4 | [nodejs](http://nodejs.org) webtool for converting images to Minecraft map items. 5 | 6 | Other code/libraries used: [jquery](http://jquery.com/), [bootstrap](http://twitter.github.com/bootstrap/), [Colour.js](http://stevehanov.ca/blog/index.php?id=116), [cookies.js](https://github.com/ScottHamper/Cookies), [node-nbt](https://github.com/djfun/node-nbt), [archiver](https://github.com/ctalkington/node-archiver), [babel](https://github.com/babel/babel), [lazystream](https://github.com/jpommerening/node-lazystream), [moment](https://github.com/moment/moment), [node-static](https://github.com/cloudhead/node-static), [winston](https://github.com/winstonjs/winston) 7 | 8 | How to setup and run your own server 9 | ------------------------------------ 10 | 1. Get and install [nodejs](http://nodejs.org) 11 | 2. Download the files from this repository 12 | 3. Use `npm install` to get the dependencies 13 | 4. Optional: Run the tests with `npm test` 14 | 5. Run the build process with `npm run build` 15 | 6. Optional: Copy `public/`, `lib/` and `package.json` to your server machine and run `npm install --production` there 16 | 7. Start the server with `npm start` 17 | 18 | If you don't need your own server, you can just use my instance at [http://mc-map.djfun.de](http://mc-map.djfun.de). 19 | 20 | 21 | License 22 | ------- 23 | mc-map-item-tool is licensed under the MIT license. 24 | 25 | 26 | Tests 27 | ----- 28 | Run client and server tests with 29 | 30 | npm test 31 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var child_process = require('child_process'); 3 | var merge = require('merge-stream'); 4 | var mkdirp = require('mkdirp'); 5 | var to5 = require("gulp-babel"); 6 | var requireDir = require('require-dir'); 7 | 8 | mkdirp.sync('tasks'); 9 | 10 | var dir = requireDir('./tasks'); 11 | 12 | 13 | var DEST_CLIENT = 'public/'; 14 | var DEST_SERVER = 'lib/'; 15 | 16 | gulp.task('clean', function(cb) { 17 | child_process.exec('rm -rf public/* lib/*', cb); 18 | }); 19 | 20 | gulp.task('default', gulp.series('clean', function() { 21 | var client = gulp.src('src/client/*') 22 | .pipe(gulp.dest(DEST_CLIENT)); 23 | var vendor = gulp.src('vendor/**') 24 | .pipe(gulp.dest(DEST_CLIENT)); 25 | var assets = gulp.src(['assets/**', '!assets/html/*']) 26 | .pipe(gulp.dest(DEST_CLIENT)); 27 | var assets_html = gulp.src('assets/html/*') 28 | .pipe(gulp.dest(DEST_CLIENT)); 29 | var server = gulp.src('src/server/*') 30 | .pipe(to5()) 31 | .pipe(gulp.dest(DEST_SERVER)); 32 | 33 | mkdirp.sync('public/tmp'); 34 | mkdirp.sync('log'); 35 | 36 | return merge(client, vendor, assets, assets_html, server); 37 | })); 38 | 39 | gulp.task('test:server', gulp.series('default', function() { 40 | var mocha = require('gulp-mocha'); 41 | 42 | return gulp.src('tests/mocha/test-server.js', {read: false}) 43 | .pipe(mocha({reporter: 'spec'})); 44 | }, 'clean')); 45 | 46 | gulp.task('test:client', gulp.series('default', function() { 47 | var casperJs = require('gulp-casperjs'); 48 | 49 | return gulp.src('tests/yadda/main_test.js') 50 | .pipe(casperJs()); //run casperjs test 51 | }, 'clean')); 52 | 53 | gulp.task('test', gulp.series('test:server', 'test:client')); 54 | -------------------------------------------------------------------------------- /tests/yadda/features/createMinecraftMapsClientSide.feature: -------------------------------------------------------------------------------- 1 | Feature: Create Minecraft map items client side 2 | Uploading an image and using the different steps 3 | Should create the correct canvas and send the correct data to the server 4 | Which is the main purpose of this web tool. 5 | 6 | Scenario: Creating a single map with the 1.8 colors 7 | 8 | Given I am on the client side version of the index page 9 | And the 181 colors are used 10 | When I upload "2013-10-18_00.28.30.png" 11 | Then I am able to split the image into 6 horizontal and 3 vertical parts 12 | 13 | When I select "1" horizontal and "1" vertical part 14 | Then the canvas should have the hash code "-1763876220" in step 3 15 | 16 | When I click on "reducecolors" 17 | Then the canvas should have the hash code "691888848" in step 4 18 | 19 | When I submit to create the map file on the server 20 | Then the map_item sent to the server should have the hash code "-110049332" 21 | And the x_center sent to the server should be '0' 22 | And the z_center sent to the server should be '0' 23 | And the dimension sent to the server should be '0' 24 | 25 | Scenario: Creating a single map with the 1.12 colors 26 | 27 | Given I am on the client side version of the index page 28 | And the 112 colors are used 29 | When I upload "2013-10-18_00.28.30.png" 30 | And I select "1" horizontal and "1" vertical part 31 | Then the canvas should have the hash code "-1763876220" in step 3 32 | 33 | When I click on "reducecolors" 34 | Then the canvas should have the hash code "1176144360" in step 4 35 | 36 | When I submit to create the map file on the server 37 | Then the map_item sent to the server should have the hash code "800503782" 38 | And the x_center sent to the server should be '0' 39 | And the z_center sent to the server should be '0' 40 | And the dimension sent to the server should be '0' -------------------------------------------------------------------------------- /src/client/settings.js: -------------------------------------------------------------------------------- 1 | document.getElementById("savesettings").addEventListener("click", savesettings, false); 2 | 3 | $(document).ready(function() { 4 | var colourSpace = Cookies.get('colourSpace') || 'laba'; 5 | var xcenter = Cookies.get('xcenter') || '0'; 6 | var zcenter = Cookies.get('zcenter') || '0'; 7 | var compatibility = Cookies.get('compatibility') || 'new'; 8 | var dim = Cookies.get('dimension') || '0'; 9 | var newColors = Cookies.get('newColors') || '181'; 10 | var dithering = Cookies.get('dithering') || 'no'; 11 | var interpolation = Cookies.get('interpolation') || 'standard'; 12 | var transparency = Cookies.get('transparency') || '50'; 13 | 14 | $('#colorSpace').val(colourSpace); 15 | $('#x_center').val(xcenter); 16 | $('#z_center').val(zcenter); 17 | $('#compatibility').val(compatibility); 18 | $('#dimension').val(dim); 19 | $('#newColors').val(newColors); 20 | $('#dithering').val(dithering); 21 | $('#interpolation').val(interpolation); 22 | $('#transparency').val(transparency); 23 | $('#transparency_label').val(transparency + '/255'); 24 | 25 | $('#transparency').on("input change", function() { 26 | $('#transparency_label').val($('#transparency').val() + '/255'); 27 | }); 28 | }); 29 | 30 | function savesettings(event) { 31 | var colourSpace = $('#colorSpace').val(); 32 | var xcenter = $('#x_center').val(); 33 | var zcenter = $('#z_center').val(); 34 | var compatibility = $('#compatibility').val(); 35 | var dim = $('#dimension').val(); 36 | var newColors = $('#newColors').val(); 37 | var dithering = $('#dithering').val(); 38 | var interpolation = $('#interpolation').val(); 39 | var transparency = $('#transparency').val(); 40 | Cookies.set('colourSpace', colourSpace); 41 | Cookies.set('xcenter', xcenter); 42 | Cookies.set('zcenter', zcenter); 43 | Cookies.set('compatibility', compatibility); 44 | Cookies.set('dimension', dim); 45 | Cookies.set('newColors', newColors); 46 | Cookies.set('dithering', dithering); 47 | Cookies.set('interpolation', interpolation); 48 | Cookies.set('transparency', transparency); 49 | } -------------------------------------------------------------------------------- /assets/css/main.css: -------------------------------------------------------------------------------- 1 | .step-1, .step-2, .step-3, .step-4, .step-5, .step-0-canvas, .step-0-image { 2 | border: 1px solid #DDD; 3 | -webkit-border-radius: 4px; 4 | -moz-border-radius: 4px; 5 | border-radius: 4px; 6 | text-align: center; 7 | padding: 15px; 8 | margin: 10px; 9 | } 10 | .hidden { 11 | display: none; 12 | } 13 | 14 | .fileupload { 15 | margin: 0 auto; 16 | } 17 | 18 | .jumbotron { 19 | background-image:url('../img/logo_bg.png'); 20 | color: #ddd; 21 | } 22 | 23 | /* centered columns styles */ 24 | .row-centered { 25 | text-align:center; 26 | } 27 | .col-centered { 28 | display:inline-block; 29 | float:none; 30 | /* reset the text-align */ 31 | text-align:left; 32 | /* inline-block space fix */ 33 | margin-right:-4px; 34 | } 35 | 36 | #original_img.pixelated { 37 | image-rendering:optimizeSpeed; /* Legal fallback */ 38 | image-rendering:-moz-crisp-edges; /* Firefox */ 39 | image-rendering:-o-crisp-edges; /* Opera */ 40 | image-rendering:-webkit-optimize-contrast; /* Safari */ 41 | image-rendering:optimize-contrast; /* CSS3 Proposed */ 42 | image-rendering:crisp-edges; /* CSS4 Proposed */ 43 | image-rendering:pixelated; /* CSS4 Proposed */ 44 | -ms-interpolation-mode:nearest-neighbor; /* IE8+ */ 45 | } 46 | 47 | /* Side notes for calling out things 48 | -------------------------------------------------- */ 49 | 50 | /* Base styles (regardless of theme) */ 51 | .bs-callout { 52 | margin: 20px 0; 53 | padding: 15px 30px 15px 15px; 54 | border-left: 5px solid #eee; 55 | } 56 | .bs-callout h4 { 57 | margin-top: 0; 58 | } 59 | .bs-callout p:last-child { 60 | margin-bottom: 0; 61 | } 62 | .bs-callout code, 63 | .bs-callout .highlight { 64 | background-color: #fff; 65 | } 66 | 67 | /* Themes for different contexts */ 68 | .bs-callout-danger { 69 | background-color: #fcf2f2; 70 | border-color: #dFb5b4; 71 | } 72 | .bs-callout-warning { 73 | background-color: #fefbed; 74 | border-color: #f1e7bc; 75 | } 76 | .bs-callout-info { 77 | background-color: #f0f7fd; 78 | border-color: #d0e3f0; 79 | } -------------------------------------------------------------------------------- /assets/html/faq.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | MC Map Item Tool 4 | 5 | 6 | 7 | 8 | 9 | 21 |
22 |

What do I do with the map file?

23 |

24 |

    25 |
  1. Create a map in minecraft
  2. 26 |
  3. Go to the save folder of your world
  4. 27 |
  5. Replace in the data folder there the created map_[i].dat with the downloaded one. ([i] is the number of the map)
  6. 28 |
  7. Load the world in minecraft and enjoy your map
  8. 29 |
30 |

31 |

How is the map file created?

32 |

mc-map-item-tool uses node-nbt to create a file in the nbt format (which is being used by Minecraft) from a Javascript object.

33 |

What technologies are being used?

34 |

We use here among other things the HTML5 File Api, Web Notifications, Canvas, Javascript (jquery and bootstrap for the layout, nodejs on the server, 35 | Colour.js to adjust the colors for Minecraft)

36 |

I have found an error or want to make a feature request

37 |

Just make a pull request on github or create an issue ticket there.

38 |

How does a map item made by this tool look in minecraft?

39 |

You can see some examples here.

40 |

Why does the tool ask me how many maps I already have in my world?

41 |

This number is used to give the downloadable map files the correct file name. If you want for example to replace map number 7 in your world you just have to input "7". When you use the split-image feature, all map files in the downloadable zip archive will get their number according to your input: If you input "7" and split the image into 4 parts the files will have the numbers 7, 8, 9 and 10.

42 |
43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/client/commandblock_worker.js: -------------------------------------------------------------------------------- 1 | onmessage = function (oEvent) { 2 | var direction = parseInt(oEvent.data.direction, 10); 3 | var mapnumber = parseInt(oEvent.data.mapnumber, 10); 4 | var dim_vertical = oEvent.data.dim_vertical; 5 | var count = oEvent.data.count; 6 | 7 | var command = create_commandblock_string(direction, mapnumber, dim_vertical, count); 8 | 9 | postMessage(command); 10 | }; 11 | 12 | function create_commandblock_string(direction, map_index, dim_vertical, count) { 13 | var text = 'summon MinecartCommandBlock ~ ~1 ~ '; 14 | var x, y, z; 15 | text+= '{Riding: {id: FallingSand, Riding:{id:MinecartCommandBlock,' + 16 | 'Riding: {id: FallingSand, Riding:{id:MinecartCommandBlock,'; 17 | var i, index; 18 | for (i = 0; i < count; i++) { 19 | text+= 'Riding: {id: FallingSand, Riding:{id:MinecartCommandBlock,'; 20 | } 21 | text+= 'Riding:{id:FallingSand,Block:minecraft:activator_rail,Time:1}'; 22 | 23 | text+= ',Command:kill @e[type=MinecartCommandBlock,r=1]}}'; 24 | 25 | for (i = 0; i < count; i++) { 26 | index = i + map_index; 27 | if (direction === 0) { 28 | // Towards negative z 29 | x = Math.floor(i / dim_vertical); 30 | y = dim_vertical - (i % dim_vertical) - 2; 31 | z = -2; 32 | } else if (direction == 1) { 33 | // Towards positive x 34 | x = 2; 35 | y = dim_vertical - (i % dim_vertical) - 2; 36 | z = Math.floor(i / dim_vertical); 37 | } else if (direction == 2) { 38 | // Towards positive z 39 | x = -Math.floor(i / dim_vertical); 40 | y = dim_vertical - (i % dim_vertical) - 2; 41 | z = 2; 42 | } else if (direction == 3) { 43 | // Towards negative x 44 | x = -2; 45 | y = dim_vertical - (i % dim_vertical) - 2; 46 | z = -Math.floor(i / dim_vertical); 47 | } 48 | 49 | 50 | text+= ',Command:"summon ItemFrame ~' + x + ' ~' + y + ' ~' + z + ' {Direction:' + 51 | direction + ',Item:{id:minecraft:filled_map, Damage:' + index + '}}"}}'; 52 | } 53 | 54 | if (direction === 0) { 55 | x1 = 0; 56 | y1 = dim_vertical - 2; 57 | z1 = -3; 58 | 59 | x2 = count / dim_vertical - 1; 60 | y2 = -1; 61 | z2 = -3; 62 | } else if (direction == 1) { 63 | x1 = 3; 64 | y1 = dim_vertical - 2; 65 | z1 = 0; 66 | 67 | x2 = 3; 68 | y2 = -1; 69 | z2 = count / dim_vertical - 1; 70 | } else if (direction == 2) { 71 | x1 = 0; 72 | y1 = dim_vertical - 2; 73 | z1 = 3; 74 | 75 | x2 = (count / dim_vertical - 1) * -1; 76 | y2 = -1; 77 | z2 = 3; 78 | } else if (direction == 3) { 79 | x1 = -3; 80 | y1 = dim_vertical - 2; 81 | z1 = 0; 82 | 83 | x2 = -3; 84 | y2 = -1; 85 | z2 = (count / dim_vertical - 1) * -1; 86 | } 87 | 88 | text+= ',Command:fill ~' + x1 + ' ~' + y1 + ' ~' + z1 + 89 | ' ~' + x2 + ' ~' + y2 + ' ~' + z2 + ' minecraft:sandstone}},}'; 90 | 91 | return text; 92 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ================== 2 | mc-map-item-tool is licensed under the MIT License 3 | ================== 4 | 5 | Copyright (c) 2012 Martin Kaistra 6 | 7 | Permission is hereby granted, free of charge, to any person 8 | obtaining a copy of this software and associated documentation 9 | files (the "Software"), to deal in the Software without restriction, 10 | including without limitation the rights to use, copy, modify, 11 | merge, publish, distribute, sublicense, and/or sell copies of 12 | the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall 16 | be included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 25 | OR OTHER DEALINGS IN THE SOFTWARE. 26 | 27 | =================== 28 | =================== 29 | External libraries: 30 | 31 | Colour.js: http://stevehanov.ca/blog/index.php?id=116 (Public Domain) 32 | --- 33 | Cookies.js: https://github.com/ScottHamper/Cookies 34 | 35 | Copyright (c) 2012 Scott Hamper 36 | 37 | Permission is hereby granted, free of charge, to any person obtaining a copy of 38 | this software and associated documentation files (the "Software"), to deal in 39 | the Software without restriction, including without limitation the rights to 40 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 41 | of the Software, and to permit persons to whom the Software is furnished to do 42 | so, subject to the following conditions: 43 | 44 | The above copyright notice and this permission notice shall be included in all 45 | copies or substantial portions of the Software. 46 | 47 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 48 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 49 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 50 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 51 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 52 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 53 | SOFTWARE. 54 | --- 55 | Bootstrap: http://twitter.github.com/bootstrap/ 56 | 57 | Copyright 2012 Twitter, Inc. 58 | 59 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License. You may obtain a copy of the License in the LICENSE file, or at: 60 | 61 | http://www.apache.org/licenses/LICENSE-2.0 62 | 63 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- /tests/yadda/main_steps.js: -------------------------------------------------------------------------------- 1 | var English = require('yadda').localisation.English; 2 | var Yadda = require('yadda'); 3 | var fs = require('fs'); 4 | 5 | var dictionary = new Yadda.Dictionary() 6 | .define('an_image_file', /(.*)/) 7 | .define('hashcode', /(.*)/) 8 | .define('element_id', /(.*)/) 9 | .define('data_item', '(x_center|z_center|dimension)') 10 | .define('value', /(.*)/); 11 | 12 | String.prototype.hashCode = function() { 13 | var hash = 0; 14 | if (this.length === 0) return hash; 15 | for (i = 0; i < this.length; i++) { 16 | char = this.charCodeAt(i); 17 | hash = ((hash << 5) - hash) + char; 18 | hash = hash & hash; // Convert to 32bit integer 19 | } 20 | return hash.toString(); 21 | }; 22 | 23 | module.exports.init = function() { 24 | return English.library(dictionary) 25 | .given("I am on the client side version of the index page", function() { 26 | casper.open("public/index.html"); 27 | casper.then(function() { 28 | casper.test.assertExists('#uploadimage'); 29 | }); 30 | }) 31 | .given("the default settings are used", function() { 32 | casper.evaluate(function() { 33 | phantom.clearCookies(); 34 | }); 35 | }) 36 | .given("the 181 colors are used", function() { 37 | casper.evaluate(function() { 38 | Cookies.set('newColors', '181'); 39 | }); 40 | }) 41 | .given("the 112 colors are used", function() { 42 | casper.evaluate(function() { 43 | Cookies.set('newColors', '112'); 44 | }); 45 | }) 46 | .when("I upload \"$an_image_file\"", function(an_image_file) { 47 | casper.fill('form', { 48 | 'img': fs.workingDirectory + "/tests/casperjs/testdata/" + an_image_file 49 | }, false); 50 | }) 51 | .then("I am able to split the image into $NUM horizontal and $NUM vertical parts", function(horizontal, vertical) { 52 | casper.waitUntilVisible('.step-2', function() { 53 | casper.test.assertElementCount('#number_horizontal option', parseInt(horizontal, 10)); 54 | casper.test.assertElementCount('#number_vertical option', parseInt(vertical, 10)); 55 | }); 56 | }) 57 | .when("I select $NUM horizontal and $NUM vertical part", function(horizontal, vertical) { 58 | casper.waitUntilVisible('.step-2', function() { 59 | casper.evaluate(function(horizontal, vertical) { 60 | $('#width_horizontal').val(horizontal).change(); 61 | $('#width_vertical').val(vertical).change(); 62 | }); 63 | 64 | casper.click("#selectnumberofparts"); 65 | }); 66 | }) 67 | .then("the canvas should have the hash code \"$hashcode\" in step $NUM", function(hashcode, step_num) { 68 | casper.waitUntilVisible('.step-' + step_num, function() { 69 | casper.scrollTo(0, 0); 70 | casper.test.assertEquals(casper.captureBase64('png', '#canvas').hashCode(), hashcode, 'canvas has correct content'); 71 | }); 72 | }) 73 | .when("I click on \"$element_id\"", function(element) { 74 | casper.click("#" + element); 75 | }) 76 | .when("I submit to create the map file on the server", function() { 77 | var old_function = casper.evaluate(function() { 78 | var old_function = $.post; 79 | $.post = function(url, data, callback) { 80 | window.casperTest_data = data; 81 | window.casperTest_url = url; 82 | callback('theFileName'); 83 | return {'error': function() {}}; 84 | }; 85 | $.post._oldfunction = old_function; 86 | return old_function; 87 | }); 88 | 89 | casper.click("#createfile"); 90 | }) 91 | .then("the map_item sent to the server should have the hash code \"$hashcode\"", function(hashcode) { 92 | var data = casper.evaluate(function() { 93 | return window.casperTest_data; 94 | }); 95 | casper.test.assertEquals(data.map_item.hashCode(), hashcode, 'correct map-item array sent to server'); 96 | }) 97 | .then("the $data_item sent to the server should be '$value'", function(data_item, value) { 98 | var data = casper.evaluate(function() { 99 | return window.casperTest_data; 100 | }); 101 | casper.test.assertEquals(data[data_item], value); 102 | }); 103 | }; -------------------------------------------------------------------------------- /tests/mocha/test-server.js: -------------------------------------------------------------------------------- 1 | process.env.NODE_ENV = 'test'; 2 | 3 | var http = require('http'); 4 | var crypto = require('crypto'); 5 | var querystring = require('querystring'); 6 | var fs = require('fs'); 7 | 8 | var chai = require('chai'); 9 | var handler = require('../../lib/server.js').handler; 10 | var tmpFiles = require('../../lib/server.js').tmpFiles; 11 | var spawn = require('child_process').spawn; 12 | var doPostRequest = require('./test-server-helper').doPostRequest; 13 | var doGetRequest = require('./test-server-helper').doGetRequest; 14 | 15 | var expect = chai.expect; 16 | 17 | describe('Server', function() { 18 | before(function(done) { 19 | var copyTestData = spawn('cp', [ 20 | 'tests/mocha/data/map_0.dat', 21 | 'tests/mocha/data/map_0_name.dat', 22 | 'tests/mocha/data/map_1_name.dat', 23 | 'tests/mocha/data/map_2_name.dat', 24 | 'tests/mocha/data/map_3_name.dat', 25 | 'public/tmp/']); 26 | this.server = http.createServer(handler).listen(3000, 'localhost'); 27 | copyTestData.on('close', function(code) { 28 | done(); 29 | }); 30 | }); 31 | 32 | it('should serve static files', function(done) { 33 | doGetRequest('/', function(res, body) { 34 | expect(body).to.contain('MC Map Item Tool'); 35 | done(); 36 | }); 37 | }); 38 | 39 | it('should create a single map file', function(done) { 40 | var mapitem = fs.readFileSync('tests/mocha/data/mapitem.json', {encoding: 'utf8'}); 41 | var map = { 42 | map_item: mapitem, 43 | x_center: "0", 44 | z_center: "0", 45 | compatibility: "new", 46 | dimension: "0", 47 | randomid: "" 48 | }; 49 | doPostRequest('/createfile', map, function(res, body) { 50 | expect(res.statusCode).to.equal(200); 51 | expect(body).to.equal('e77750173999e2bca7bb8af86596b1af92a47aa5'); 52 | done(); 53 | }); 54 | }); 55 | 56 | it('should create a zip file from multiple map files', function(done) { 57 | tmpFiles.addFile("map_0_name.dat"); 58 | tmpFiles.addFile("map_1_name.dat"); 59 | tmpFiles.addFile("map_2_name.dat"); 60 | tmpFiles.addFile("map_3_name.dat"); 61 | var mapfiles = [ 62 | "map_0_name", 63 | "map_1_name", 64 | "map_2_name", 65 | "map_3_name" 66 | ]; 67 | var postData = { 68 | mapfiles: JSON.stringify(mapfiles), 69 | zipname: "test_zip_name", 70 | mapnumber: "0" 71 | }; 72 | doPostRequest('/createzip', postData, function(res, body) { 73 | expect(res.statusCode).to.equal(200); 74 | expect(body).to.equal('test_zip_name'); 75 | done(); 76 | }); 77 | }); 78 | 79 | it('should serve map files', function(done) { 80 | doGetRequest('/tmp/map_0.dat', function(res, body) { 81 | var shasum = crypto.createHash('sha1'); 82 | shasum.update(body); 83 | expect(shasum.digest('hex')).to.equal('97a74755132eab3e0d1ea79a58632648813f808b'); 84 | done(); 85 | }); 86 | }); 87 | 88 | it('should handle zip creation when the number of maps is greater than the file handle limit', function(done) { 89 | this.timeout(0); 90 | tmpFiles.addFile("map_0_name.dat"); 91 | var mapfiles = []; 92 | for (var i = 0; i<1030; i++) { 93 | mapfiles.push("map_0_name"); 94 | } 95 | var postData = { 96 | mapfiles: JSON.stringify(mapfiles), 97 | zipname: "test_zip_name_1", 98 | mapnumber: "0" 99 | }; 100 | doPostRequest('/createzip', postData, function(res, body) { 101 | expect(res.statusCode).to.equal(200); 102 | expect(body).to.equal('test_zip_name_1'); 103 | done(); 104 | }); 105 | }); 106 | 107 | it('should handle irregular inputs and return a 400 error', function(done) { 108 | var mapitem = fs.readFileSync('tests/mocha/data/mapitem.json', {encoding: 'utf8'}); 109 | mapitem = JSON.parse(mapitem); 110 | mapitem[50] = 128; 111 | var map = { 112 | map_item: JSON.stringify(mapitem), 113 | x_center: "0", 114 | z_center: "0", 115 | dimension: "0", 116 | randomid: "" 117 | }; 118 | doPostRequest('/createfile', map, function(res, body) { 119 | expect(res.statusCode).to.equal(400); 120 | done(); 121 | }); 122 | }); 123 | 124 | after(function(done) { 125 | this.server.close(done); 126 | }); 127 | }); -------------------------------------------------------------------------------- /assets/html/commandblock.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | MC Map Item Tool 4 | 5 | 6 | 7 | 8 | 9 | 22 | 23 |
24 |
25 |
26 |
27 | 28 |
29 | 30 |
31 |
32 |
33 | 34 |
35 | 36 |
37 |
38 |
39 | 40 |
41 | 47 |
48 |
49 |
50 | 51 |
52 | 53 |
54 |
55 |
56 | 57 |
58 | 59 |
60 |
61 |
62 |
63 |

64 |
65 |
66 |
67 |
68 | 69 |
70 |

Get all maps into the world with one command (Minecraft 1.8 and newer)

71 |

This (still experimental) feature allows you to get the map items from the main 72 | tool into your minecraft world already placed on a wall in the correct order.

73 |

To use it, simply enter the data you used to create the map item files. Open your 74 | minecraft world, place a command block (/give @p minecraft:command_block) 2 blocks in front 75 | of where the bottom left corner of the item frame wall should be. Copy the command from 76 | the output text field and paste it into the command block. Place a button onto 77 | the command block, click it and watch the block do its magic.

78 |

If that explanation was to complicated, you can just make a new creative 79 | test world and try it out.

80 |

Please note, that if you do not understand what the command does, you should probably 81 | make a backup of your world if there are important things near the location of 82 | the command block that runs this command.

83 |
84 | 85 |
86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /assets/html/settings.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | MC Map Item Tool 4 | 5 | 6 | 7 | 8 | 9 | 10 | 22 |
23 |
24 |
25 |
26 | 27 |
28 | 34 |
35 |
36 |
37 | 38 |
39 | 46 |
47 |
48 |
49 | 50 |
51 | 55 |
56 |
57 |
58 | 59 |
60 | 64 |
65 |
66 |
67 | 68 |
69 |
70 | 71 |
72 |
73 | 74 |
75 |
76 |
77 |
78 | 79 |
80 | 81 |
82 |
83 |
84 | 85 |
86 | 87 |
88 |
89 |
90 | 91 |
92 | 96 |
97 |
98 |
99 | 100 |
101 | 106 |
107 |
108 |
109 |
110 | 111 |
112 |
113 |
114 |
115 |
116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /assets/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MC Map Item Tool 5 | 6 | 7 | 8 | 9 | 10 | 22 |
23 |
24 | 25 | Info: If you encounter problems, please file an issue on github or contact me via twitter 26 |
27 | 30 | 33 |
34 |

MC Map Item Tool

35 |

Your own image on a minecraft map item? Just use this easy five-step tool.

36 |
37 |
38 |
39 |
40 | 41 | 48 | 49 | 50 |
51 |
...
52 |
53 |
54 |

Step 2 - Select number of parts you want to split the image into

55 |

The more parts the longer the following steps will take. If you have a slow computer, consider lowering the amount of parts!

56 |
57 |
58 | 59 | 62 |
63 |
64 |
65 |
66 | 67 | 70 |
71 |
72 |

If you don't want to split your image into multiple maps, just leave the default value "1".

73 | 74 |
75 |
76 |
77 |
78 |

Step 3 - Adjust colors for minecraft

79 | 80 | 81 |
82 |
83 |
84 |
85 |

Step 4 - Let the server create a map file

86 |

How many maps does your world already have? (The created map will have this number as a filename. More information)

87 |
88 |
89 | 90 |
91 |
92 |
93 |
94 | 97 |
98 |
99 | 100 |
101 |
102 |
103 |
104 |

Step 5 - Download the file

105 | 106 |

and then replace the map file in the save folder (See also What do I do with the map file?)

107 |
108 |
109 |
110 |
111 |
112 | 113 |
114 |

Map item:

115 | 116 |

Previous  Next

117 |
118 |
119 |

All map parts together:

120 | 121 |
122 |
123 |
124 |
125 |

Step 1 - Select an image file

126 |
127 | 128 |
129 |
130 |
131 |
132 |

Original image:

133 | 134 |
135 |
136 |

Settings:

137 | 138 |
139 |
140 |
141 |
142 |
143 |
144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /src/server/server.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | require("babel-polyfill"); 4 | 5 | var zlib = require('zlib'); 6 | var url = require('url'); 7 | var fs = require('fs'); 8 | var http = require('http'); 9 | 10 | var nodeStatic = require('node-static'); 11 | var querystring = require('querystring'); 12 | var crypto = require('crypto'); 13 | var archiver = require('archiver'); 14 | var moment = require('moment'); 15 | var lazystream = require('lazystream'); 16 | var winston = require('winston'); 17 | 18 | var file = new (nodeStatic.Server)('./public'); 19 | var TAG = require('node-nbt').TAG; 20 | var NbtReader = require('node-nbt').NbtReader; 21 | var NbtWriter = require('node-nbt').NbtWriter; 22 | 23 | var logger = winston.createLogger({ 24 | level: 'info', 25 | format: winston.format.combine( 26 | winston.format.timestamp({ 27 | format: 'YYYY-MM-DD HH:mm:ss' 28 | }), 29 | winston.format.printf(function(info) { return `${info.timestamp} ${info.level}: ${info.message}`}) 30 | ), 31 | transports: [new winston.transports.File({ 32 | filename: './log/mc-map.log', 33 | maxsize: 99999, 34 | })] 35 | }); 36 | if (process.env.NODE_ENV != 'production') { 37 | logger.add(new winston.transports.Console()); 38 | } 39 | 40 | var TMP_DIR = './public/tmp/'; 41 | 42 | var tmpFiles = { 43 | addFile(hash) { 44 | this.files[hash] = (new Date()).getTime(); 45 | this.removeOldFiles(); 46 | }, 47 | removeOldFiles() { 48 | var time = (new Date()).getTime(); 49 | for (let hash in this.files) { 50 | if (this.files[hash] < time - (30 * 60 * 1000)) { 51 | deleteTmpFiles(hash); 52 | delete this.files[hash]; 53 | } 54 | } 55 | }, 56 | files: {} 57 | }; 58 | 59 | var app; 60 | 61 | function deleteTmpFiles (file) { 62 | fs.unlink(`${TMP_DIR}${file}`, function (err) { 63 | if (err) { 64 | let error = new Error('Error while deleting tmp files'); 65 | error.http_code = 500; 66 | error.fs_error = err; 67 | throw error; 68 | } else { 69 | logger.log('info', `Successfully deleted /tmp/${file}`); 70 | } 71 | }); 72 | } 73 | 74 | var handlers = { 75 | logReferer(req) { 76 | var referer = req.headers.referer; 77 | if (referer) { 78 | var host = req.headers['x-forwarded-host'] ? req.headers['x-forwarded-host'] : req.headers.host; 79 | if (referer.indexOf(host) !== 7) { 80 | // only log external referers 81 | logger.log('info', `Referer: ${referer}`); 82 | } 83 | } 84 | }, 85 | serveTmpFile(req, res) { 86 | var url_parts = url.parse(req.url, true); 87 | var {query, pathname} = url_parts; 88 | if (tmpFiles.files[pathname.substr(5)]) { 89 | try { 90 | logger.log('info', `Serve tmp file: ${pathname}`); 91 | 92 | let mapnumber = parseInt(query.mapnumber, 10) || 0; 93 | let downloadfilename = pathname.slice(-3) == 'dat' ? `map_${mapnumber}.dat` : 'map_items.zip'; 94 | file.serveFile(pathname, 200, 95 | {'Content-Disposition': `attachment; filename="${downloadfilename}"`}, req, res); 96 | } catch (e) { 97 | handlers.handleError(e, res); 98 | } 99 | } else { 100 | res.writeHead(404); 101 | res.end("File doesn't exist"); 102 | } 103 | }, 104 | createMapFile(req, res, body) { 105 | var map_item_array; 106 | var x_center; 107 | var z_center; 108 | var compatibility; 109 | var dimension; 110 | var randomid; 111 | try { 112 | let decodedBody = querystring.parse(body); 113 | logger.log('debug', 'decoded body', decodedBody); 114 | map_item_array = JSON.parse(decodedBody.map_item); 115 | x_center = parseInt(decodedBody.x_center, 10); 116 | z_center = parseInt(decodedBody.z_center, 10); 117 | compatibility = decodedBody.compatibility; 118 | dimension = parseInt(decodedBody.dimension, 10); 119 | let dimensionTag; 120 | if (compatibility == 'new') { 121 | const dims = ["minecraft:overworld", "minecraft:the_nether", "minecraft:the_end"]; 122 | dimensionTag = { name: 'dimension', type: TAG.STRING, val: dims[dimension] }; 123 | } 124 | else { 125 | dimensionTag = { name: 'dimension', type: TAG.BYTE, val: dimension }; 126 | } 127 | randomid = decodedBody.randomid; 128 | if (randomid !== "") { 129 | randomid+= "_"; 130 | } 131 | logger.log('debug', 'array length', map_item_array.length); 132 | if (map_item_array.length == 16384) { 133 | for (let element of map_item_array.values()) { 134 | if (element > 127) { 135 | let error = new Error('Illegal color value in map_item_array'); 136 | error.http_code = 400; 137 | throw error; 138 | } 139 | } 140 | } else { 141 | let error = new Error('Illegal length of map_item_array'); 142 | error.http_code = 400; 143 | throw error; 144 | } 145 | var map_file = { 146 | type: TAG.COMPOUND, 147 | name: '', 148 | val: [ 149 | { 150 | name: 'DataVersion', 151 | type: TAG.INT, 152 | val: 7856 153 | }, 154 | { 155 | name: 'data', 156 | type: TAG.COMPOUND, 157 | val: [ 158 | { 159 | name: 'scale', 160 | type: TAG.BYTE, 161 | val: 0 162 | }, 163 | dimensionTag, 164 | { 165 | name: 'trackingPosition', 166 | type: TAG.BYTE, 167 | val: 0 168 | }, 169 | { 170 | name: 'locked', 171 | type: TAG.BYTE, 172 | val: 1 173 | }, 174 | { 175 | name: 'height', 176 | type: TAG.SHORT, 177 | val: 128 178 | }, 179 | { 180 | name: 'width', 181 | type: TAG.SHORT, 182 | val: 128 183 | }, 184 | { 185 | name: 'xCenter', 186 | type: TAG.INT, 187 | val: x_center 188 | }, 189 | { 190 | name: 'zCenter', 191 | type: TAG.INT, 192 | val: z_center 193 | }, 194 | { 195 | name: 'colors', 196 | type: TAG.BYTEARRAY, 197 | val: map_item_array 198 | } 199 | ] 200 | } 201 | ] 202 | }; 203 | let nbtData = NbtWriter.writeTag(map_file); 204 | let shasum = crypto.createHash('sha1'); 205 | shasum.update(nbtData); 206 | let filename = randomid + shasum.digest('hex'); 207 | tmpFiles.addFile(`${filename}.dat`); 208 | zlib.gzip(nbtData, function(err, data) { 209 | if (err) { 210 | let error = new Error('Error while creating map file'); 211 | error.http_code = 500; 212 | error.zlib_error = err; 213 | throw error; 214 | } 215 | let writeStream = new lazystream.Writable(function () { 216 | return fs.createWriteStream(`${TMP_DIR}${filename}.dat`) 217 | .on('close', function () { 218 | winston.log('info', `Map file written to disk: ${filename}.dat`); 219 | res.setHeader('Content-Type', 'text/html'); 220 | res.writeHead(200); 221 | res.end(filename); 222 | }); 223 | }); 224 | writeStream.write(data); 225 | writeStream.end(); 226 | }); 227 | } catch (e) { 228 | handlers.handleError(e, res); 229 | } 230 | }, 231 | createZipFile(req, res, body) { 232 | try { 233 | let decodedBody = querystring.parse(body); 234 | let mapfiles = JSON.parse(decodedBody.mapfiles); 235 | let zipname = decodedBody.zipname; 236 | let mapnumber = parseInt(decodedBody.mapnumber, 10) || 0; 237 | tmpFiles.addFile(`${zipname}.zip`); 238 | let output = fs.createWriteStream(`${TMP_DIR}${zipname}.zip`); 239 | let archive = archiver('zip'); 240 | output.on('close', function() { 241 | logger.log('info', `Zip file written to disk: ${zipname}.zip`); 242 | res.setHeader('Content-Type', 'text/html'); 243 | res.writeHead(200); 244 | res.end(zipname); 245 | }); 246 | archive.on('error', function(err) { 247 | let error = new Error('Error while creating zip archive'); 248 | error.http_code = 500; 249 | error.archive_error = err; 250 | throw error; 251 | }); 252 | archive.pipe(output); 253 | let filenumber; 254 | for (let [index, element] of mapfiles.entries()) { 255 | if (!tmpFiles.files[`${element}.dat`]) { 256 | let error = new Error(`NotInTmpFilesException: ${element} is not in tmpFiles`); 257 | error.http_code = 500; 258 | throw error; 259 | } 260 | filenumber = mapnumber + index; 261 | archive.file(`${TMP_DIR}${element}.dat`, {name: `map_${filenumber}.dat`}); 262 | } 263 | archive.finalize(function(err, bytes) { 264 | if (err) { 265 | let error = new Error('Error while finalizing zip archive'); 266 | error.http_code = 500; 267 | error.archive_error = err; 268 | throw error; 269 | } 270 | logger.log('info', `Zip file finalized: ${bytes} total bytes`); 271 | }); 272 | } catch (e) { 273 | handlers.handleError(e, res); 274 | } 275 | }, 276 | handleError(err, res) { 277 | 278 | res.writeHead(err.http_code || 500); 279 | if (err.http_code == 400) { 280 | res.end("Bad request"); 281 | logger.log('info', 'Bad request', err.toString()); 282 | } else { 283 | res.end("Internal server error"); 284 | logger.log('info', 'Internal Server Error', err.toString()); 285 | } 286 | } 287 | }; 288 | 289 | function handler (req, res) { 290 | handlers.logReferer(req); 291 | 292 | var body=''; 293 | req.on('data', function (data) { 294 | body +=data; 295 | }); 296 | req.addListener('end', function () { 297 | if (req.method == 'GET' && req.url.substr(0, 4) == '/tmp') { 298 | handlers.serveTmpFile(req, res); 299 | } else if (req.method == 'POST' && req.url == '/createfile') { 300 | handlers.createMapFile(req, res, body); 301 | } else if (req.method == 'POST' && req.url == '/createzip') { 302 | handlers.createZipFile(req, res, body); 303 | } else { 304 | file.serve(req, res); 305 | } 306 | }); 307 | } 308 | 309 | function startup() { 310 | // on start delete all files in ./tmp 311 | fs.readdir('./public/tmp', function(err, files) { 312 | if (err) { 313 | throw err; 314 | } else { 315 | for (let file of files.values()) { 316 | deleteTmpFiles(file); 317 | } 318 | } 319 | }); 320 | 321 | app = http.createServer(handler); 322 | app.listen(process.env.PORT || 8080, process.env.HOST); 323 | logger.log('info', 'Started mc-map-item-tool server'); 324 | } 325 | 326 | process.on("SIGTERM", function() { 327 | logger.log('info', 'Received signal SIGTERM'); 328 | process.exit(); 329 | }); 330 | 331 | 332 | if (!module.parent) { 333 | startup(); 334 | } else { 335 | module.exports.handler = handler; 336 | module.exports.tmpFiles = tmpFiles; 337 | } 338 | -------------------------------------------------------------------------------- /vendor/js/Colour.js: -------------------------------------------------------------------------------- 1 | /** 2 | The Colour object allows conversion of colours between strings and several 3 | other colour spaces. 4 | 5 | The colour has two public members. It's type is the type of colour space. Its 6 | values are an array of numbers specifying the colour coordinates. These 7 | coordinates depend on the type of colour space used. 8 | 9 | @constructor 10 | @param {number} type 11 | @param {Array.} values 12 | */ 13 | function Colour(type, values) 14 | { 15 | this.type = type; 16 | this.values = values; 17 | 18 | if ( this.values.length < 4 ) { 19 | throw "Bad value"; 20 | } 21 | } 22 | 23 | // Here is an enumeration of colour spaces. 24 | 25 | // RGBA. All components are in the range 0..1 26 | Colour.RGBA = 0; 27 | 28 | // CIE XYZ, with added alpha value. 29 | Colour.XYZA = 1; 30 | 31 | // Hue/Saturation/Value. Hue is in the range 0...360 and the others are 0...1 32 | Colour.HSVA = 2; 33 | 34 | // CIE LAB 1976 colour space, with added alpha component. 35 | Colour.LABA = 3; 36 | 37 | Colour.LAST_COLOURSPACE = 3; 38 | 39 | /** 40 | Creates an RGBA colour object from the given string. If the string is not 41 | valid, a default colour of magenta is used. Valid strings are one of the 42 | following: 43 | 44 | 1. A standard CSS colour name (eg. "Blue"). The case does not matter. 45 | 46 | 2. A CSS hex string with 6 digits. Eg. #80ff00 47 | 48 | 3. An rgba value. Eg. rgba( 128, 255, 0, 1.0 ). Note the last component must 49 | be in the range 0..1 and the others are in the range 0..255. 50 | 51 | @param {string} colourString 52 | @return {Colour} 53 | */ 54 | Colour.fromString = function( colourString ) 55 | { 56 | if ( colourString.toLowerCase() in Colour.CssColours ) { 57 | colourString = Colour.CssColours[colourString.toLowerCase()]; 58 | } 59 | 60 | var hex6 = /\#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])/i; 61 | var rgbStr = /rgba\( *([0-9]+) *, *([0-9]+) *, *([0-9]+) *, *([0-9\.]+) *\)/; 62 | var r, g, b,a; 63 | 64 | var m = hex6.exec( colourString ); 65 | if ( m !== null ) { 66 | r = parseInt( m[1], 16 ) / 255; 67 | g = parseInt( m[2], 16 ) / 255; 68 | b = parseInt( m[3], 16 ) / 255; 69 | a = 1.0; 70 | } else { 71 | m = rgbStr.exec( colourString ); 72 | if ( m !== null ) { 73 | r = parseFloat(m[1])/255; 74 | g = parseFloat(m[2])/255; 75 | b = parseFloat(m[3])/255; 76 | a = parseFloat(m[4]); 77 | } else { 78 | // default colour 79 | r = 1.0; 80 | g = 0.0; 81 | b = 1.0; 82 | a = 1.0; 83 | } 84 | } 85 | 86 | return new Colour( Colour.RGBA, [r, g, b, a] ); 87 | }; 88 | 89 | Colour.prototype = { 90 | 91 | /** 92 | Converts the colour to a string. The string is formatted such that it can 93 | be used to set the fillStyle or strokeStyle of an HTML5 Canvas 2d context. 94 | 95 | @return {string} 96 | */ 97 | toString: function() 98 | { 99 | function toHex(val) 100 | { 101 | val = Math.round( val * 255 ); 102 | if ( val < 16 ) { 103 | return "0" + val.toString(16); 104 | } else { 105 | return val.toString(16); 106 | } 107 | } 108 | 109 | var clr = this.convertTo( Colour.RGBA ); 110 | 111 | if ( clr.values[3] === 1.0 ) { 112 | return "#" + 113 | toHex( clr.values[0] ) + 114 | toHex( clr.values[1] ) + 115 | toHex( clr.values[2] ); 116 | } else { 117 | return "rgba(" + 118 | Math.round(clr.values[0]*255) + "," + 119 | Math.round(clr.values[1]*255) + "," + 120 | Math.round(clr.values[2]*255) + "," + 121 | clr.values[3] + ")"; 122 | } 123 | }, 124 | 125 | /** 126 | Returns a new colour object, converting to the given colour space. 127 | 128 | @param {number} type 129 | @return {Colour} 130 | */ 131 | convertTo: function( type ) 132 | { 133 | return Colour.converters[this.type][type](this); 134 | }, 135 | 136 | /** 137 | Returns the distance between this colour and another, using the colour 138 | space of this colour. If the other colour is another colour space, it is 139 | converted before the calculation is done. 140 | */ 141 | distanceTo: function( colour ) 142 | { 143 | if ( colour.type !== this.type ) { 144 | colour = colour.convertTo( this.type ); 145 | } 146 | 147 | if ( this.type === Colour.HSVA ) { 148 | // Hue goes from 0 to 360, unlike other colour schemes, so it needs 149 | // to be scaled relative to the other values. It must also wrap 150 | // around. 151 | 152 | var a = this.values[0], b = colour.values[0]; 153 | var hueDiff; 154 | if ( a > b ) { 155 | hueDiff = Math.min( a - b, b - a + 360 ); 156 | } else { 157 | hueDiff = Math.min( b - a, a - b + 360 ); 158 | } 159 | 160 | hueDiff /= 360; 161 | 162 | return Math.pow( 163 | hueDiff * hueDiff + 164 | ( this.values[1] - colour.values[1] ) * 165 | ( this.values[1] - colour.values[1] ) + 166 | ( this.values[2] - colour.values[2] ) * 167 | ( this.values[2] - colour.values[2] ), 0.5 ); 168 | 169 | } else { 170 | return Math.pow( 171 | ( this.values[0] - colour.values[0] ) * 172 | ( this.values[0] - colour.values[0] ) + 173 | ( this.values[1] - colour.values[1] ) * 174 | ( this.values[1] - colour.values[1] ) + 175 | ( this.values[2] - colour.values[2] ) * 176 | ( this.values[2] - colour.values[2] ), 0.5 ); 177 | } 178 | } 179 | 180 | }; 181 | 182 | (function(){ 183 | 184 | var WHITE = {X: 0.9505, Y: 1.0000, Z: 1.0890}; // D65 185 | 186 | /** 187 | @param {Colour} clr 188 | @return {Colour} 189 | */ 190 | function convert_HSVA_RGBA( clr ) 191 | { 192 | var h = clr.values[0]; 193 | var s = clr.values[1]; 194 | var v = clr.values[2]; 195 | if ( h < 0 ) { h += 360; } 196 | var hi = Math.floor( h / 60 ) % 6; 197 | var f = h / 60 - Math.floor( h / 60 ); 198 | var p = v * (1 - s); 199 | var q = v * (1 - f * s); 200 | var t = v * (1 - ( 1 - f ) * s ); 201 | var r, g, b; 202 | switch( hi ) { 203 | case 0: 204 | r = v; 205 | g = t; 206 | b = p; 207 | break; 208 | case 1: 209 | r = q; 210 | g = v; 211 | b = p; 212 | break; 213 | case 2: 214 | r = p; 215 | g = v; 216 | b = t; 217 | break; 218 | case 3: 219 | r = p; 220 | g = q; 221 | b = v; 222 | break; 223 | case 4: 224 | r = t; 225 | g = p; 226 | b = v; 227 | break; 228 | case 5: 229 | r = v; 230 | g = p; 231 | b = q; 232 | break; 233 | } 234 | 235 | return new Colour( Colour.RGBA, [ r, g, b, clr.values[3] ] ); 236 | } 237 | 238 | /** 239 | @param {Colour} clr 240 | @return {Colour} 241 | */ 242 | function convert_RGBA_HSVA( clr ) 243 | { 244 | var h, s, v; 245 | var r = clr.values[0]; 246 | var g = clr.values[1]; 247 | var b = clr.values[2]; 248 | var max = Math.max( r, g, b ); 249 | var min = Math.min( r, g, b ); 250 | if ( max === min ) { 251 | h = 0; 252 | } else if ( max === r ) { 253 | h = ( 60 * (g - b) / ( max - min ) + 360 ) % 360; 254 | } else if ( max === g ) { 255 | h = 60 * ( b - r ) / ( max - min ) + 120; 256 | } else if ( max === b ) { 257 | h = 60 * ( r - g ) / ( max - min ) + 240; 258 | } 259 | 260 | if ( max === 0 ) { 261 | s = 0; 262 | } else { 263 | s = 1 - min / max; 264 | } 265 | 266 | v = max; 267 | 268 | return new Colour( Colour.HSVA, [ h, s, v, clr.values[3] ] ); 269 | } 270 | 271 | /** 272 | @param {Colour} clr 273 | @return {Colour} 274 | */ 275 | function convert_XYZA_LABA( clr ) 276 | { 277 | function f(t) 278 | { 279 | if ( t > ( 6.0 / 29.0 ) * ( 6.0 / 29.0 ) * (6.0 / 29.0 ) ) { 280 | return Math.pow( t, 1.0 / 3.0 ); 281 | } else { 282 | return ( 1.0 / 3.0 ) * 283 | ( 29.0 / 6.0 ) * ( 29.0 / 6.0 ) * t + 284 | 4.0 / 29.0; 285 | } 286 | } 287 | 288 | var X = f( clr.values[0] / WHITE.X ); 289 | var Y = f( clr.values[1] / WHITE.Y ); 290 | var Z = f( clr.values[2] / WHITE.Z ); 291 | 292 | return new Colour( Colour.LABA, 293 | [116 * Y - 16, 294 | 500 * ( X - Y ), 295 | 200 * ( Y - Z ), 296 | clr.values[3] ] ); 297 | } 298 | 299 | /** 300 | @param {Colour} clr 301 | @return {Colour} 302 | */ 303 | function convert_LABA_XYZA( clr ) 304 | { 305 | var fy = ( clr.values[0] + 16 ) / 116; 306 | var fx = fy + clr.values[1] / 500; 307 | var fz = fy - clr.values[2] / 200; 308 | 309 | var squiggle = 6.0 / 29; 310 | var X, Y, Z; 311 | 312 | if ( fy > squiggle ) { 313 | Y = WHITE.Y * fy * fy * fy; 314 | } else { 315 | Y = ( fy - 16.0 / 116 ) * 3 * squiggle * squiggle * WHITE.Y; 316 | } 317 | 318 | if ( fx > squiggle ) { 319 | X = WHITE.X * fx * fx * fx; 320 | } else { 321 | X = ( fx - 16.0 / 116 ) * 3 * squiggle * squiggle * WHITE.X; 322 | } 323 | 324 | if ( fz > squiggle ) { 325 | Z = WHITE.Z * fz * fz * fz; 326 | } else { 327 | Z = ( fz - 16.0 / 116 ) * 3 * squiggle * squiggle * WHITE.Z; 328 | } 329 | 330 | return new Colour( Colour.XYZA, [X, Y, Z, clr.values[3]] ); 331 | } 332 | 333 | /** 334 | @param {Colour} rgb 335 | @return {Colour} 336 | */ 337 | function convert_RGBA_XYZA( rgb ) 338 | { 339 | var temp = []; 340 | 341 | for ( var i = 0; i < 3; i++ ) { 342 | if ( rgb.values[i] <= 0.04045 ) { 343 | temp[i] = rgb.values[i] / 12.92; 344 | } else { 345 | temp[i] = Math.pow( (rgb.values[i]+0.055)/1.055, 2.4 ); 346 | } 347 | } 348 | 349 | return new Colour( Colour.XYZA, [ 350 | 0.4124*temp[0]+0.3576*temp[1]+0.1805*temp[2], 351 | 0.2126*temp[0]+0.7152*temp[1]+0.0722*temp[2], 352 | 0.0193*temp[0]+0.1192*temp[1]+0.9505*temp[2], 353 | rgb.values[3] ] ); 354 | } 355 | 356 | /** 357 | @param {Colour} xyz 358 | @return {Colour} 359 | */ 360 | function convert_XYZA_RGBA( xyz ) 361 | { 362 | var temp = []; 363 | var values = []; 364 | 365 | temp[0] = 3.2410 * xyz.values[0] - 1.5374 * xyz.values[1] - 0.4986 * xyz.values[2]; 366 | temp[1] = -0.9692 * xyz.values[0] + 1.8760 * xyz.values[1] + 0.0416 * xyz.values[2]; 367 | temp[2] = 0.0556 * xyz.values[0] - 0.2040 * xyz.values[1] + 1.0570 * xyz.values[2]; 368 | 369 | for ( var i = 0; i < 3; i++ ) { 370 | if ( temp[i] <= 0.0031308 ) { 371 | values[i] = 12.92 * temp[i]; 372 | } else { 373 | values[i] = 1.055 * Math.pow( temp[i], 1.0 / 2.4 ) - 0.055; 374 | } 375 | } 376 | 377 | values[3] = xyz.values[3]; 378 | 379 | return new Colour( Colour.RGBA, values ); 380 | } 381 | 382 | /** 383 | @param {Colour} clr 384 | @return {Colour} 385 | */ 386 | function convert_SAME( clr ) 387 | { 388 | return new Colour( clr.type, clr.values.concat() ); 389 | } 390 | 391 | /** 392 | @param {Colour} clr 393 | @return {Colour} 394 | */ 395 | function convert_RGBA_LABA( clr ) 396 | { 397 | return convert_XYZA_LABA( 398 | convert_RGBA_XYZA( clr ) ); 399 | } 400 | 401 | /** 402 | @param {Colour} clr 403 | @return {Colour} 404 | */ 405 | function convert_LABA_RGBA( clr ) 406 | { 407 | return convert_XYZA_RGBA( 408 | convert_LABA_XYZA( clr ) ); 409 | } 410 | 411 | /** 412 | @param {Colour} clr 413 | @return {Colour} 414 | */ 415 | function convert_XYZA_HSVA( clr ) 416 | { 417 | return convert_RGBA_HSVA( 418 | convert_XYZA_RGBA( clr ) ); 419 | } 420 | 421 | /** 422 | @param {Colour} clr 423 | @return {Colour} 424 | */ 425 | function convert_HSVA_XYZA( clr ) 426 | { 427 | return convert_RGBA_XYZA( 428 | convert_HSVA_RGBA( clr ) ); 429 | } 430 | 431 | /** 432 | @param {Colour} clr 433 | @return {Colour} 434 | */ 435 | function convert_HSVA_LABA( clr ) 436 | { 437 | return convert_RGBA_LABA( 438 | convert_HSVA_RGBA( clr ) ); 439 | } 440 | 441 | /** 442 | @param {Colour} clr 443 | @return {Colour} 444 | */ 445 | function convert_LABA_HSVA( clr ) 446 | { 447 | return convert_XYZA_HSVA( 448 | convert_LABA_XYZA( clr ) ); 449 | } 450 | 451 | Colour.converters = [ 452 | [ convert_SAME, 453 | convert_RGBA_XYZA, 454 | convert_RGBA_HSVA, 455 | convert_RGBA_LABA ], 456 | 457 | [ convert_XYZA_RGBA, 458 | convert_SAME, 459 | convert_XYZA_HSVA, 460 | convert_XYZA_LABA ], 461 | 462 | [ convert_HSVA_RGBA, 463 | convert_HSVA_XYZA, 464 | convert_SAME, 465 | convert_HSVA_LABA ], 466 | 467 | [ convert_LABA_RGBA, 468 | convert_LABA_XYZA, 469 | convert_LABA_HSVA, 470 | convert_SAME ] 471 | ]; 472 | }()); 473 | 474 | Colour.CssColours = { 475 | "aliceblue": "#f0f8ff", 476 | "antiquewhite": "#faebd7", 477 | "aqua": "#00ffff", 478 | "aquamarine": "#7fffd4", 479 | "azure": "#f0ffff", 480 | "beige": "#f5f5dc", 481 | "bisque": "#ffe4c4", 482 | "black": "#000000", 483 | "blanchedalmond": "#ffebcd", 484 | "blue": "#0000ff", 485 | "blueviolet": "#8a2be2", 486 | "brown": "#a52a2a", 487 | "burlywood": "#deb887", 488 | "cadetblue": "#5f9ea0", 489 | "chartreuse": "#7fff00", 490 | "chocolate": "#d2691e", 491 | "coral": "#ff7f50", 492 | "cornflowerblue": "#6495ed", 493 | "cornsilk": "#fff8dc", 494 | "crimson": "#dc143c", 495 | "cyan": "#00ffff", 496 | "darkblue": "#00008b", 497 | "darkcyan": "#008b8b", 498 | "darkgoldenrod": "#b8860b", 499 | "darkgray": "#a9a9a9", 500 | "darkgreen": "#006400", 501 | "darkkhaki": "#bdb76b", 502 | "darkmagenta": "#8b008b", 503 | "darkolivegreen": "#556b2f", 504 | "darkorange": "#ff8c00", 505 | "darkorchid": "#9932cc", 506 | "darkred": "#8b0000", 507 | "darksalmon": "#e9967a", 508 | "darkseagreen": "#8fbc8f", 509 | "darkslateblue": "#483d8b", 510 | "darkslategray": "#2f4f4f", 511 | "darkturquoise": "#00ced1", 512 | "darkviolet": "#9400d3", 513 | "deeppink": "#ff1493", 514 | "deepskyblue": "#00bfff", 515 | "dimgray": "#696969", 516 | "dodgerblue": "#1e90ff", 517 | "firebrick": "#b22222", 518 | "floralwhite": "#fffaf0", 519 | "forestgreen": "#228b22", 520 | "fuchsia": "#ff00ff", 521 | "gainsboro": "#dcdcdc", 522 | "ghostwhite": "#f8f8ff", 523 | "gold": "#ffd700", 524 | "goldenrod": "#daa520", 525 | "gray": "#808080", 526 | "green": "#008000", 527 | "greenyellow": "#adff2f", 528 | "honeydew": "#f0fff0", 529 | "hotpink": "#ff69b4", 530 | "indianred": "#cd5c5c", 531 | "indigo": "#4b0082", 532 | "ivory": "#fffff0", 533 | "khaki": "#f0e68c", 534 | "lavender": "#e6e6fa", 535 | "lavenderblush": "#fff0f5", 536 | "lawngreen": "#7cfc00", 537 | "lemonchiffon": "#fffacd", 538 | "lightblue": "#add8e6", 539 | "lightcoral": "#f08080", 540 | "lightcyan": "#e0ffff", 541 | "lightgoldenrodyellow": "#fafad2", 542 | "lightgreen": "#90ee90", 543 | "lightgrey": "#d3d3d3", 544 | "lightpink": "#ffb6c1", 545 | "lightsalmon": "#ffa07a", 546 | "lightseagreen": "#20b2aa", 547 | "lightskyblue": "#87cefa", 548 | "lightslategray": "#778899", 549 | "lightsteelblue": "#b0c4de", 550 | "lightyellow": "#ffffe0", 551 | "lime": "#00ff00", 552 | "limegreen": "#32cd32", 553 | "linen": "#faf0e6", 554 | "magenta": "#ff00ff", 555 | "maroon": "#800000", 556 | "mediumaquamarine": "#66cdaa", 557 | "mediumblue": "#0000cd", 558 | "mediumorchid": "#ba55d3", 559 | "mediumpurple": "#9370d8", 560 | "mediumseagreen": "#3cb371", 561 | "mediumslateblue": "#7b68ee", 562 | "mediumspringgreen": "#00fa9a", 563 | "mediumturquoise": "#48d1cc", 564 | "mediumvioletred": "#c71585", 565 | "midnightblue": "#191970", 566 | "mintcream": "#f5fffa", 567 | "mistyrose": "#ffe4e1", 568 | "moccasin": "#ffe4b5", 569 | "navajowhite": "#ffdead", 570 | "navy": "#000080", 571 | "oldlace": "#fdf5e6", 572 | "olive": "#808000", 573 | "olivedrab": "#6b8e23", 574 | "orange": "#ffa500", 575 | "orangered": "#ff4500", 576 | "orchid": "#da70d6", 577 | "palegoldenrod": "#eee8aa", 578 | "palegreen": "#98fb98", 579 | "paleturquoise": "#afeeee", 580 | "palevioletred": "#d87093", 581 | "papayawhip": "#ffefd5", 582 | "peachpuff": "#ffdab9", 583 | "peru": "#cd853f", 584 | "pink": "#ffc0cb", 585 | "plum": "#dda0dd", 586 | "powderblue": "#b0e0e6", 587 | "purple": "#800080", 588 | "red": "#ff0000", 589 | "rosybrown": "#bc8f8f", 590 | "royalblue": "#4169e1", 591 | "saddlebrown": "#8b4513", 592 | "salmon": "#fa8072", 593 | "sandybrown": "#f4a460", 594 | "seagreen": "#2e8b57", 595 | "seashell": "#fff5ee", 596 | "sienna": "#a0522d", 597 | "silver": "#c0c0c0", 598 | "skyblue": "#87ceeb", 599 | "slateblue": "#6a5acd", 600 | "slategray": "#708090", 601 | "snow": "#fffafa", 602 | "springgreen": "#00ff7f", 603 | "steelblue": "#4682b4", 604 | "tan": "#d2b48c", 605 | "teal": "#008080", 606 | "thistle": "#d8bfd8", 607 | "tomato": "#ff6347", 608 | "turquoise": "#40e0d0", 609 | "violet": "#ee82ee", 610 | "wheat": "#f5deb3", 611 | "white": "#ffffff", 612 | "whitesmoke": "#f5f5f5", 613 | "yellow": "#ffff00", 614 | "yellowgreen": "#9acd32" 615 | }; 616 | -------------------------------------------------------------------------------- /vendor/css/bootstrap-theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.2 (http://getbootstrap.com) 3 | * Copyright 2011-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary:disabled,.btn-primary[disabled]{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} -------------------------------------------------------------------------------- /src/client/main.js: -------------------------------------------------------------------------------- 1 | var ctx_full = document.getElementById('canvas_full').getContext('2d'), 2 | ctx = document.getElementById('canvas').getContext('2d'), 3 | canvas = document.getElementById('canvas'), 4 | canvas_full = document.getElementById('canvas_full'), 5 | img, 6 | original_img = document.getElementById('original_img'), 7 | url = window.URL || window.webkitURL, 8 | src, 9 | interpolation, 10 | selected_ratio, 11 | settings_string; 12 | 13 | function draw(ev) { 14 | var f = document.getElementById("uploadimage").files[0]; 15 | img = new Image(); 16 | src = url.createObjectURL(f); 17 | 18 | interpolation = Cookies.get('interpolation') || 'standard'; 19 | if (interpolation == 'nearest_neighbor') { 20 | $('#original_img').addClass('pixelated'); 21 | } 22 | 23 | // list all settings from Cookies in span#list_settings 24 | list_settings(); 25 | 26 | img.src = src; 27 | original_img.src = src; 28 | img.onload = function() { 29 | 30 | url.revokeObjectURL(src); 31 | 32 | // calculate possible numbers for next step 33 | var highest_number_vertical = img.height / 128; 34 | var highest_number_horizontal = img.width / 128; 35 | 36 | $('#number_vertical').html(''); 37 | $('#number_horizontal').html(''); 38 | 39 | var i = 0; 40 | for (i = 2; i <= highest_number_vertical; i++) { 41 | $('#number_vertical').append(''); 42 | } 43 | for (i = 2; i <= highest_number_horizontal; i++) { 44 | $('#number_horizontal').append(''); 45 | } 46 | 47 | $('.step-1').addClass('hidden'); 48 | 49 | $('.step-0-image').removeClass('hidden'); 50 | 51 | $('#title_hero').addClass('hidden'); 52 | $('#contact_alert').addClass('hidden'); 53 | 54 | $('#tabs a[href="#step1"]').click(function (e) { 55 | e.preventDefault(); 56 | go_back_2_to_1(); 57 | }); 58 | 59 | $('#tabs a[href="#step3"]').parent().addClass('disabled'); 60 | $('#tabs a[href="#step4"]').parent().addClass('disabled'); 61 | $('#tabs a[href="#step5"]').parent().addClass('disabled'); 62 | 63 | $('#tabs').removeClass('hidden'); 64 | $('#tabs a[href="#step2"]').tab('show'); 65 | }; 66 | } 67 | 68 | function selectnumber(ev) { 69 | map_parts_vertical = $('#number_vertical').val(); 70 | map_parts_horizontal = $('#number_horizontal').val(); 71 | 72 | var canvasCopy = document.createElement("canvas"); 73 | var copyContext = canvasCopy.getContext("2d"); 74 | var maxWidth = 128 * map_parts_horizontal, 75 | maxHeight = 128 * map_parts_vertical; 76 | 77 | var ratio = 1; 78 | var spaceW = 0; 79 | var spaceH = 0; 80 | 81 | if (img.width > img.height) { 82 | ratio = maxWidth / img.width; 83 | } else { 84 | ratio = maxHeight / img.height; 85 | } 86 | 87 | canvasCopy.width = img.width; 88 | canvasCopy.height = img.height; 89 | copyContext.drawImage(img, 0, 0); 90 | 91 | spaceH = (maxHeight - (img.height * ratio)) / 2; 92 | spaceW = (maxWidth - (img.width * ratio)) / 2; 93 | 94 | canvas_full.width = 128 * map_parts_horizontal; 95 | canvas_full.height = 128 * map_parts_vertical; 96 | 97 | canvas_full.style.width = canvas_full.width * 2; 98 | canvas_full.style.height = canvas_full.height * 2; 99 | 100 | if (interpolation == 'nearest_neighbor') { 101 | ctx_full.imageSmoothingEnabled = false; 102 | } else { 103 | ctx_full.imageSmoothingEnabled = true; 104 | } 105 | ctx_full.drawImage(canvasCopy, 0, 0, 106 | canvasCopy.width, canvasCopy.height, 107 | spaceW, spaceH, img.width * ratio, img.height * ratio); 108 | 109 | var canvas_full_scaled = document.getElementById('canvas_full_scaled'); 110 | var ctx_full_scaled = canvas_full_scaled.getContext('2d'); 111 | ctx_full_scaled.clearRect(0, 0, canvas_full_scaled.width, canvas_full_scaled.height); 112 | 113 | selected_ratio = map_parts_horizontal / map_parts_vertical; 114 | if (map_parts_horizontal >= map_parts_vertical) { 115 | ctx_full_scaled.drawImage(canvas_full, 0, 0, 256, 256 * (1/selected_ratio)); 116 | } else { 117 | ctx_full_scaled.drawImage(canvas_full, 0, 0, 256 * selected_ratio, 256); 118 | } 119 | 120 | // draw scaled version of ctx_full onto canvas#canvas_full_scaled 121 | // add part selection to span#list_settings 122 | 123 | settings_string += 'Map parts horizontal' + map_parts_horizontal + ''; 124 | settings_string += 'Map parts vertical' + map_parts_vertical + ''; 125 | $('#list_settings').html('' + settings_string + '
'); 126 | 127 | drawCanvas(0, 0); 128 | map_x = 0; 129 | map_y = 0; 130 | $('.step-0-canvas').removeClass('hidden'); 131 | 132 | $('#tabs a[href="#step2"]').click(function (e) { 133 | e.preventDefault(); 134 | go_back_3_to_2(); 135 | }); 136 | 137 | $('#tabs a[href="#step3"]').parent().removeClass('disabled'); 138 | 139 | $('#tabs a[href="#step3"]').tab('show'); 140 | } 141 | 142 | function drawCanvas(x, y) { 143 | $('.prev-map').removeClass('hidden'); 144 | $('.next-map').removeClass('hidden'); 145 | 146 | canvas.height = 128; 147 | canvas.width = 128; 148 | $(canvas).width(canvas.width * 2); 149 | $(canvas).height(canvas.height * 2); 150 | 151 | ctx.clearRect(0, 0, canvas.width, canvas.height); 152 | 153 | ctx.drawImage(canvas_full, 128 * x, 128 * y, 128, 128, 154 | 0, 0, 128, 128); 155 | ctx.scale(4, 4); 156 | if (x === 0 && y === 0) { 157 | $('.prev-map').addClass('hidden'); 158 | } 159 | if (x === map_parts_horizontal - 1 && y === map_parts_vertical - 1) { 160 | $('.next-map').addClass('hidden'); 161 | } 162 | } 163 | 164 | function prevMap(ev) { 165 | ev.preventDefault(); 166 | if (!(map_x === 0 && map_y === 0)) { 167 | if (map_x === 0) { 168 | map_y--; 169 | map_x = map_parts_horizontal - 1; 170 | } else { 171 | map_x--; 172 | } 173 | } 174 | drawCanvas(map_x, map_y); 175 | } 176 | 177 | function nextMap(ev) { 178 | ev.preventDefault(); 179 | if (!(map_x === map_parts_horizontal - 1 && map_y === map_parts_vertical - 1)) { 180 | if (map_x === map_parts_horizontal - 1) { 181 | map_y++; 182 | map_x = 0; 183 | } else { 184 | map_x++; 185 | } 186 | } 187 | drawCanvas(map_x, map_y); 188 | } 189 | 190 | function reducecolors(ev) { 191 | $('#reducecolors').addClass('hidden'); 192 | var ctx = document.getElementById('canvas_full').getContext('2d'); 193 | var pixelData = ctx.getImageData(0, 0, 128 * map_parts_horizontal, 128 * map_parts_vertical); 194 | 195 | var worker = new Worker("reduce_colors_worker.js"); 196 | 197 | worker.postMessage({pixelData: pixelData, 198 | new_colors: Cookies.get('newColors') || '181', 199 | colourSpace: Cookies.get('colourSpace') || 'laba', 200 | dithering: Cookies.get('dithering') || 'no', 201 | transparency: Cookies.get('transparency') || '50' 202 | }); 203 | 204 | var time_start = new Date(); 205 | var duration = 0; 206 | 207 | worker.onmessage = function(oEvent) { 208 | if (oEvent.data.step == 'finished') { 209 | ctx.putImageData(oEvent.data.pixelData, 0, 0); 210 | all_maps_data = oEvent.data.all_maps_data; 211 | 212 | // redraw scaled and now color reduced version of ctx_full onto canvas#canvas_full_scaled 213 | var ctx_full_scaled = document.getElementById('canvas_full_scaled').getContext('2d'); 214 | if (map_parts_horizontal >= map_parts_vertical) { 215 | ctx_full_scaled.drawImage(canvas_full, 0, 0, 256, 256 * (1/selected_ratio)); 216 | } else { 217 | ctx_full_scaled.drawImage(canvas_full, 0, 0, 256 * selected_ratio, 256); 218 | } 219 | 220 | drawCanvas(map_x, map_y); 221 | $('#reducecolors').removeClass('hidden'); 222 | 223 | $('#tabs a[href="#step2"]').off('click'); 224 | $('#tabs a[href="#step3"]').off('click'); 225 | $('#tabs a[href="#step2"]').click(function (e) { 226 | e.preventDefault(); 227 | go_back_4_to_3(); 228 | go_back_3_to_2(); 229 | }); 230 | $('#tabs a[href="#step3"]').click(function (e) { 231 | e.preventDefault(); 232 | go_back_4_to_3(); 233 | }); 234 | 235 | $('#tabs a[href="#step4"]').parent().removeClass('disabled'); 236 | 237 | $('#tabs a[href="#step4"]').tab('show'); 238 | duration = Math.abs(time_start - new Date()) / 1000; 239 | $('#reducecolors_time').parent().removeClass('hidden'); 240 | $('#reducecolors_time').html('Reducing colors took ' + duration + ' seconds.'); 241 | } else if (oEvent.data.step == 'percentage') { 242 | $('#reducecolors_progress').html(oEvent.data.percentage + '% complete.'); 243 | } else if (oEvent.data.step == 'debug') { 244 | console.log(oEvent.data.message); 245 | } 246 | }; 247 | 248 | } 249 | 250 | function createfile(ev) { 251 | $('#reducecolors_time').parent().addClass('hidden'); 252 | 253 | var time_start = new Date(); 254 | 255 | var xcenter = Cookies.get('xcenter') || '0'; 256 | var zcenter = Cookies.get('zcenter') || '0'; 257 | var compatibility = Cookies.get('compatibility') || 'new'; 258 | var dim = Cookies.get('dimension') || '0'; 259 | 260 | var mapnumber = parseInt($('#map_number').val(), 10) || 0; 261 | 262 | var randomid = ""; 263 | if (map_parts_horizontal > 1 || map_parts_vertical > 1) { 264 | randomid = makerandomid(); 265 | } 266 | 267 | var responses = []; 268 | var responses_count = 0; 269 | if (all_maps_data) { 270 | for (var i = 0; i < map_parts_horizontal; i++) { 271 | for (var j = 0; j < map_parts_vertical; j++) { 272 | map_item = []; 273 | var co; 274 | for (var k = 0; k < 128; k++) { 275 | for (var l = 0; l < 128; l++) { 276 | co = all_maps_data[((j * map_parts_horizontal * 128 * 128) + i * 128) + 277 | l + map_parts_horizontal * 128 * k]; 278 | if (co > 127) { 279 | co = co - 256; 280 | } 281 | map_item.push(co); 282 | } 283 | } 284 | (function() { 285 | var x = i; 286 | var y = j; 287 | $.post('createfile', { 288 | map_item: JSON.stringify(map_item), 289 | x_center: xcenter, 290 | z_center: zcenter, 291 | compatibility: compatibility, 292 | dimension: dim, 293 | randomid: randomid 294 | }, function(data) { 295 | responses[y + map_parts_vertical * x] = data; 296 | responses_count++; 297 | updateResponse('zip_file_part', {done_count: responses_count, map_count: map_parts_horizontal * map_parts_vertical}); 298 | if (responses_count === map_parts_horizontal * map_parts_vertical) { 299 | if (responses_count == 1) { 300 | updateResponse('single_file_finished', {filename: responses[0], mapnumber: mapnumber, time_start: time_start}); 301 | } else { 302 | $.post('createzip', { 303 | mapfiles: JSON.stringify(responses), 304 | zipname: randomid, 305 | mapnumber: mapnumber 306 | }, function(data) { 307 | updateResponse('zip_file_finished', {filename: data, time_start: time_start}); 308 | }); 309 | } 310 | } 311 | }).error(function() { 312 | updateResponse('error'); 313 | }); 314 | }()); 315 | } 316 | } 317 | } 318 | } 319 | 320 | function go_back_2_to_1() { 321 | window.location.reload(false); 322 | } 323 | 324 | function go_back_3_to_2() { 325 | $('.step-0-canvas').addClass('hidden'); 326 | $('#tabs a[href="#step2"]').tab('show'); 327 | $('#tabs a[href="#step3"]').parent().addClass('disabled'); 328 | list_settings(); 329 | } 330 | 331 | function go_back_4_to_3() { 332 | $('#reducecolors_time').parent().addClass('hidden'); 333 | $('#reducecolors_time').html(''); 334 | $('#reducecolors_progress').html(''); 335 | $('#tabs a[href="#step4"]').parent().addClass('disabled'); 336 | list_settings(); 337 | selectnumber(); 338 | } 339 | 340 | function go_back_5_to_4() { 341 | $('#ajaxreply').html(''); 342 | $('#ajaxreply_time').parent().addClass('hidden'); 343 | $('#ajaxreply_time').html(''); 344 | $('#tabs a[href="#step4"]').tab('show'); 345 | $('#tabs a[href="#step5"]').parent().addClass('disabled'); 346 | } 347 | 348 | function updateResponse(step, data) { 349 | var response_text, notification; 350 | 351 | if (step == 'single_file_finished') { 352 | response_text = 'Download' + " (map_" + data['mapnumber'] + ".dat)"; 354 | $('#ajaxreply').html(response_text); 355 | duration = Math.abs(data.time_start - new Date()) / 1000; 356 | $('#ajaxreply_time').parent().removeClass('hidden'); 357 | $('#ajaxreply_time').html('Creating map file took ' + duration + ' seconds.'); 358 | $('#tabs a[href="#step5"]').tab('show'); 359 | if ($('#notification').is(':checked') && Notification.permission === "granted") { 360 | notification = new Notification("MC Map Item Tool", { 361 | body: "Creating map file finished in " + duration + " seconds." 362 | }); 363 | } 364 | } else if (step == 'zip_file_finished') { 365 | console.log(data); 366 | response_text = 'Download' + " (Zip archive with map files)"; 367 | $('#ajaxreply').html(response_text); 368 | duration = Math.abs(data.time_start - new Date()) / 1000; 369 | $('#ajaxreply_time').parent().removeClass('hidden'); 370 | $('#ajaxreply_time').html('Creating map files took ' + duration + ' seconds.'); 371 | $('#tabs a[href="#step5"]').tab('show'); 372 | if ($('#notification').is(':checked') && Notification.permission === "granted") { 373 | notification = new Notification("MC Map Item Tool", { 374 | body: "Creating map files finished in " + duration + " seconds." 375 | }); 376 | } 377 | } else if (step == 'zip_file_part') { 378 | response_text = "Creating maps: " + data['done_count'] + " of " + data['map_count'] + " done."; 379 | $('#ajaxreply').html(response_text); 380 | $('#tabs a[href="#step5"]').tab('show'); 381 | } else if (step == 'error') { 382 | response_text = "The server returned an error. If you think, this is a malfunction, please report it (via github, twitter, ..)."; 383 | $('#ajaxreply').html(response_text); 384 | $('#instruction').addClass('hidden'); 385 | $('#tabs a[href="#step5"]').tab('show'); 386 | if ($('#notification').is(':checked') && Notification.permission === "granted") { 387 | notification = new Notification("MC Map Item Tool", { 388 | body: response_text 389 | }); 390 | } 391 | } 392 | $('#tabs a[href="#step2"]').off('click'); 393 | $('#tabs a[href="#step3"]').off('click'); 394 | $('#tabs a[href="#step4"]').off('click'); 395 | $('#tabs a[href="#step2"]').click(function (e) { 396 | e.preventDefault(); 397 | go_back_5_to_4(); 398 | go_back_4_to_3(); 399 | go_back_3_to_2(); 400 | }); 401 | $('#tabs a[href="#step3"]').click(function (e) { 402 | e.preventDefault(); 403 | go_back_5_to_4(); 404 | go_back_4_to_3(); 405 | }); 406 | $('#tabs a[href="#step4"]').click(function (e) { 407 | e.preventDefault(); 408 | go_back_5_to_4(); 409 | }); 410 | 411 | $('#tabs a[href="#step5"]').parent().removeClass('disabled'); 412 | } 413 | 414 | function list_settings() { 415 | var colorSchemeToText = { 416 | 'no': 'Old colors', 417 | 'yes': 'Version 1.7.2 (2013)', 418 | '181': 'Version 1.8.1 (2014)', 419 | '17w06a': 'Snapshot 17w06a', 420 | '112': 'Version 1.12 (2017)' 421 | }; 422 | var compatibilityToText = { 423 | 'new': 'New (1.16 and later)', 424 | 'legacy': 'Legacy (1.15 and earlier)' 425 | }; 426 | var dimensionToText = { 427 | '0': 'Overworld', 428 | '1': 'Nether', 429 | '2': 'End' 430 | }; 431 | var ditheringToText = { 432 | 'no': 'No dithering', 433 | 'floydsteinberg': 'Floyd-Steinberg', 434 | }; 435 | var interpolationToText = { 436 | 'standard': 'Standard', 437 | 'nearest_neighbor': 'Nearest Neighbor' 438 | }; 439 | var sett_colorSpace = Cookies.get('colourSpace') || 'laba'; 440 | var sett_colorScheme = colorSchemeToText[Cookies.get('newColors') || 'yes']; 441 | var sett_dithering = ditheringToText[Cookies.get('dithering') || 'no']; 442 | var sett_interpolation = interpolationToText[Cookies.get('interpolation') || 'standard']; 443 | var sett_xCenter = Cookies.get('xcenter') || '0'; 444 | var sett_zCenter = Cookies.get('zcenter') || '0'; 445 | var sett_compatibility = compatibilityToText[Cookies.get('compatibility') || 'new']; 446 | var sett_dimension = dimensionToText[Cookies.get('dimension') || '0']; 447 | 448 | settings_string = 'Color space' + sett_colorSpace + ''; 449 | settings_string += 'Color scheme' + sett_colorScheme + ''; 450 | settings_string += 'Dithering' + sett_dithering + ''; 451 | settings_string += 'Interpolation' + sett_interpolation + ''; 452 | settings_string += 'X Center' + sett_xCenter + ''; 453 | settings_string += 'Z Center' + sett_zCenter + ''; 454 | settings_string += 'Compatibility' + sett_compatibility + ''; 455 | settings_string += 'Dimension' + sett_dimension + ''; 456 | $('#list_settings').html('' + settings_string + '
'); 457 | } 458 | 459 | 460 | function makerandomid() { 461 | var text = ""; 462 | var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 463 | 464 | for (var i = 0; i < 10; i++) 465 | text += possible.charAt(Math.floor(Math.random() * possible.length)); 466 | 467 | return text; 468 | } 469 | 470 | var map_item; 471 | var map_parts_vertical; 472 | var map_parts_horizontal; 473 | 474 | var all_maps_data; 475 | 476 | var map_x; 477 | var map_y; 478 | 479 | document.getElementById("uploadimage").addEventListener("change", draw, false); 480 | document.getElementById("selectnumberofparts").addEventListener("click", selectnumber, false); 481 | document.getElementById("reducecolors").addEventListener("click", reducecolors, false); 482 | document.getElementById("createfile").addEventListener("click", createfile, false); 483 | 484 | document.getElementById("prevmap").addEventListener("click", prevMap, false); 485 | document.getElementById("nextmap").addEventListener("click", nextMap, false); 486 | 487 | $(document).ready(function() { 488 | // console.log('dom ready'); 489 | $('.step-0-image').addClass('hidden'); 490 | $('.step-0-canvas').addClass('hidden'); 491 | $('#reducecolors_time').parent().addClass('hidden'); 492 | $('#ajaxreply_time').parent().addClass('hidden'); 493 | $('#tabs').addClass('hidden'); 494 | if (!("Notification" in window)) { 495 | // This browser does not support notifications 496 | $('.notification-form-div').addClass('hidden'); 497 | } else { 498 | $('#notification').change(function() { 499 | if(this.checked) { 500 | if (Notification.permission !== 'denied') { 501 | Notification.requestPermission(); 502 | } 503 | } 504 | }); 505 | } 506 | }); -------------------------------------------------------------------------------- /vendor/css/bootstrap-theme.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.2 (http://getbootstrap.com) 3 | * Copyright 2011-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | .btn-default, 8 | .btn-primary, 9 | .btn-success, 10 | .btn-info, 11 | .btn-warning, 12 | .btn-danger { 13 | text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); 14 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); 15 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); 16 | } 17 | .btn-default:active, 18 | .btn-primary:active, 19 | .btn-success:active, 20 | .btn-info:active, 21 | .btn-warning:active, 22 | .btn-danger:active, 23 | .btn-default.active, 24 | .btn-primary.active, 25 | .btn-success.active, 26 | .btn-info.active, 27 | .btn-warning.active, 28 | .btn-danger.active { 29 | -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); 30 | box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); 31 | } 32 | .btn-default .badge, 33 | .btn-primary .badge, 34 | .btn-success .badge, 35 | .btn-info .badge, 36 | .btn-warning .badge, 37 | .btn-danger .badge { 38 | text-shadow: none; 39 | } 40 | .btn:active, 41 | .btn.active { 42 | background-image: none; 43 | } 44 | .btn-default { 45 | text-shadow: 0 1px 0 #fff; 46 | background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); 47 | background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); 48 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); 49 | background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); 50 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); 51 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 52 | background-repeat: repeat-x; 53 | border-color: #dbdbdb; 54 | border-color: #ccc; 55 | } 56 | .btn-default:hover, 57 | .btn-default:focus { 58 | background-color: #e0e0e0; 59 | background-position: 0 -15px; 60 | } 61 | .btn-default:active, 62 | .btn-default.active { 63 | background-color: #e0e0e0; 64 | border-color: #dbdbdb; 65 | } 66 | .btn-default.disabled, 67 | .btn-default:disabled, 68 | .btn-default[disabled] { 69 | background-color: #e0e0e0; 70 | background-image: none; 71 | } 72 | .btn-primary { 73 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); 74 | background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); 75 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); 76 | background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); 77 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); 78 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 79 | background-repeat: repeat-x; 80 | border-color: #245580; 81 | } 82 | .btn-primary:hover, 83 | .btn-primary:focus { 84 | background-color: #265a88; 85 | background-position: 0 -15px; 86 | } 87 | .btn-primary:active, 88 | .btn-primary.active { 89 | background-color: #265a88; 90 | border-color: #245580; 91 | } 92 | .btn-primary.disabled, 93 | .btn-primary:disabled, 94 | .btn-primary[disabled] { 95 | background-color: #265a88; 96 | background-image: none; 97 | } 98 | .btn-success { 99 | background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); 100 | background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); 101 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); 102 | background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); 103 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); 104 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 105 | background-repeat: repeat-x; 106 | border-color: #3e8f3e; 107 | } 108 | .btn-success:hover, 109 | .btn-success:focus { 110 | background-color: #419641; 111 | background-position: 0 -15px; 112 | } 113 | .btn-success:active, 114 | .btn-success.active { 115 | background-color: #419641; 116 | border-color: #3e8f3e; 117 | } 118 | .btn-success.disabled, 119 | .btn-success:disabled, 120 | .btn-success[disabled] { 121 | background-color: #419641; 122 | background-image: none; 123 | } 124 | .btn-info { 125 | background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); 126 | background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); 127 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); 128 | background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); 129 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); 130 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 131 | background-repeat: repeat-x; 132 | border-color: #28a4c9; 133 | } 134 | .btn-info:hover, 135 | .btn-info:focus { 136 | background-color: #2aabd2; 137 | background-position: 0 -15px; 138 | } 139 | .btn-info:active, 140 | .btn-info.active { 141 | background-color: #2aabd2; 142 | border-color: #28a4c9; 143 | } 144 | .btn-info.disabled, 145 | .btn-info:disabled, 146 | .btn-info[disabled] { 147 | background-color: #2aabd2; 148 | background-image: none; 149 | } 150 | .btn-warning { 151 | background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); 152 | background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); 153 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); 154 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); 155 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); 156 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 157 | background-repeat: repeat-x; 158 | border-color: #e38d13; 159 | } 160 | .btn-warning:hover, 161 | .btn-warning:focus { 162 | background-color: #eb9316; 163 | background-position: 0 -15px; 164 | } 165 | .btn-warning:active, 166 | .btn-warning.active { 167 | background-color: #eb9316; 168 | border-color: #e38d13; 169 | } 170 | .btn-warning.disabled, 171 | .btn-warning:disabled, 172 | .btn-warning[disabled] { 173 | background-color: #eb9316; 174 | background-image: none; 175 | } 176 | .btn-danger { 177 | background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); 178 | background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); 179 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); 180 | background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); 181 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); 182 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 183 | background-repeat: repeat-x; 184 | border-color: #b92c28; 185 | } 186 | .btn-danger:hover, 187 | .btn-danger:focus { 188 | background-color: #c12e2a; 189 | background-position: 0 -15px; 190 | } 191 | .btn-danger:active, 192 | .btn-danger.active { 193 | background-color: #c12e2a; 194 | border-color: #b92c28; 195 | } 196 | .btn-danger.disabled, 197 | .btn-danger:disabled, 198 | .btn-danger[disabled] { 199 | background-color: #c12e2a; 200 | background-image: none; 201 | } 202 | .thumbnail, 203 | .img-thumbnail { 204 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 205 | box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 206 | } 207 | .dropdown-menu > li > a:hover, 208 | .dropdown-menu > li > a:focus { 209 | background-color: #e8e8e8; 210 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 211 | background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 212 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); 213 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); 214 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); 215 | background-repeat: repeat-x; 216 | } 217 | .dropdown-menu > .active > a, 218 | .dropdown-menu > .active > a:hover, 219 | .dropdown-menu > .active > a:focus { 220 | background-color: #2e6da4; 221 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 222 | background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 223 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); 224 | background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); 225 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); 226 | background-repeat: repeat-x; 227 | } 228 | .navbar-default { 229 | background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); 230 | background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); 231 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); 232 | background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); 233 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); 234 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 235 | background-repeat: repeat-x; 236 | border-radius: 4px; 237 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); 238 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); 239 | } 240 | .navbar-default .navbar-nav > .open > a, 241 | .navbar-default .navbar-nav > .active > a { 242 | background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); 243 | background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); 244 | background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); 245 | background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); 246 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); 247 | background-repeat: repeat-x; 248 | -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); 249 | box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); 250 | } 251 | .navbar-brand, 252 | .navbar-nav > li > a { 253 | text-shadow: 0 1px 0 rgba(255, 255, 255, .25); 254 | } 255 | .navbar-inverse { 256 | background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); 257 | background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); 258 | background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); 259 | background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); 260 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); 261 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 262 | background-repeat: repeat-x; 263 | } 264 | .navbar-inverse .navbar-nav > .open > a, 265 | .navbar-inverse .navbar-nav > .active > a { 266 | background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); 267 | background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); 268 | background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); 269 | background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); 270 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); 271 | background-repeat: repeat-x; 272 | -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); 273 | box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); 274 | } 275 | .navbar-inverse .navbar-brand, 276 | .navbar-inverse .navbar-nav > li > a { 277 | text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); 278 | } 279 | .navbar-static-top, 280 | .navbar-fixed-top, 281 | .navbar-fixed-bottom { 282 | border-radius: 0; 283 | } 284 | @media (max-width: 767px) { 285 | .navbar .navbar-nav .open .dropdown-menu > .active > a, 286 | .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, 287 | .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { 288 | color: #fff; 289 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 290 | background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 291 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); 292 | background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); 293 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); 294 | background-repeat: repeat-x; 295 | } 296 | } 297 | .alert { 298 | text-shadow: 0 1px 0 rgba(255, 255, 255, .2); 299 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); 300 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); 301 | } 302 | .alert-success { 303 | background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); 304 | background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); 305 | background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); 306 | background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); 307 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); 308 | background-repeat: repeat-x; 309 | border-color: #b2dba1; 310 | } 311 | .alert-info { 312 | background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); 313 | background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); 314 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); 315 | background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); 316 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); 317 | background-repeat: repeat-x; 318 | border-color: #9acfea; 319 | } 320 | .alert-warning { 321 | background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); 322 | background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); 323 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); 324 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); 325 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); 326 | background-repeat: repeat-x; 327 | border-color: #f5e79e; 328 | } 329 | .alert-danger { 330 | background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); 331 | background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); 332 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); 333 | background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); 334 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); 335 | background-repeat: repeat-x; 336 | border-color: #dca7a7; 337 | } 338 | .progress { 339 | background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); 340 | background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); 341 | background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); 342 | background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); 343 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); 344 | background-repeat: repeat-x; 345 | } 346 | .progress-bar { 347 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); 348 | background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); 349 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); 350 | background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); 351 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); 352 | background-repeat: repeat-x; 353 | } 354 | .progress-bar-success { 355 | background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); 356 | background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); 357 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); 358 | background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); 359 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); 360 | background-repeat: repeat-x; 361 | } 362 | .progress-bar-info { 363 | background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); 364 | background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); 365 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); 366 | background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); 367 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); 368 | background-repeat: repeat-x; 369 | } 370 | .progress-bar-warning { 371 | background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); 372 | background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); 373 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); 374 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); 375 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); 376 | background-repeat: repeat-x; 377 | } 378 | .progress-bar-danger { 379 | background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); 380 | background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); 381 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); 382 | background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); 383 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); 384 | background-repeat: repeat-x; 385 | } 386 | .progress-bar-striped { 387 | background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); 388 | background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); 389 | background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); 390 | } 391 | .list-group { 392 | border-radius: 4px; 393 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 394 | box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 395 | } 396 | .list-group-item.active, 397 | .list-group-item.active:hover, 398 | .list-group-item.active:focus { 399 | text-shadow: 0 -1px 0 #286090; 400 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); 401 | background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); 402 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); 403 | background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); 404 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); 405 | background-repeat: repeat-x; 406 | border-color: #2b669a; 407 | } 408 | .list-group-item.active .badge, 409 | .list-group-item.active:hover .badge, 410 | .list-group-item.active:focus .badge { 411 | text-shadow: none; 412 | } 413 | .panel { 414 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); 415 | box-shadow: 0 1px 2px rgba(0, 0, 0, .05); 416 | } 417 | .panel-default > .panel-heading { 418 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 419 | background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 420 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); 421 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); 422 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); 423 | background-repeat: repeat-x; 424 | } 425 | .panel-primary > .panel-heading { 426 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 427 | background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 428 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); 429 | background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); 430 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); 431 | background-repeat: repeat-x; 432 | } 433 | .panel-success > .panel-heading { 434 | background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); 435 | background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); 436 | background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); 437 | background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); 438 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); 439 | background-repeat: repeat-x; 440 | } 441 | .panel-info > .panel-heading { 442 | background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); 443 | background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); 444 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); 445 | background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); 446 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); 447 | background-repeat: repeat-x; 448 | } 449 | .panel-warning > .panel-heading { 450 | background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); 451 | background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); 452 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); 453 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); 454 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); 455 | background-repeat: repeat-x; 456 | } 457 | .panel-danger > .panel-heading { 458 | background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); 459 | background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); 460 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); 461 | background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); 462 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); 463 | background-repeat: repeat-x; 464 | } 465 | .well { 466 | background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); 467 | background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); 468 | background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); 469 | background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); 470 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); 471 | background-repeat: repeat-x; 472 | border-color: #dcdcdc; 473 | -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); 474 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); 475 | } 476 | /*# sourceMappingURL=bootstrap-theme.css.map */ 477 | -------------------------------------------------------------------------------- /vendor/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.2 (http://getbootstrap.com) 3 | * Copyright 2011-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.2",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.2",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.2",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a(this.options.trigger).filter('[href="#'+b.id+'"], [data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.2",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0,trigger:'[data-toggle="collapse"]'},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":a.extend({},e.data(),{trigger:this});c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.2",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('