diff --git a/.gitignore b/.gitignore
index 25a5c4a..7ad3959 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,7 @@
# Studio
/minecraftcodex/studio/static/css/*.css
/minecraftcodex/studio/static/js/*.js
+/minecraftcodex/studio/static/lib/*.css
# Utils
/utils/miner/classes
diff --git a/minecraftcodex/studio/static/fonts/Flat-UI-Icons.dev.svg b/minecraftcodex/studio/static/fonts/Flat-UI-Icons.dev.svg
new file mode 100755
index 0000000..7b10907
--- /dev/null
+++ b/minecraftcodex/studio/static/fonts/Flat-UI-Icons.dev.svg
@@ -0,0 +1,140 @@
+
+
+
\ No newline at end of file
diff --git a/minecraftcodex/studio/static/fonts/Flat-UI-Icons.eot b/minecraftcodex/studio/static/fonts/Flat-UI-Icons.eot
new file mode 100755
index 0000000..656ca08
Binary files /dev/null and b/minecraftcodex/studio/static/fonts/Flat-UI-Icons.eot differ
diff --git a/minecraftcodex/studio/static/fonts/Flat-UI-Icons.svg b/minecraftcodex/studio/static/fonts/Flat-UI-Icons.svg
new file mode 100755
index 0000000..91087b3
--- /dev/null
+++ b/minecraftcodex/studio/static/fonts/Flat-UI-Icons.svg
@@ -0,0 +1,140 @@
+
+
+
\ No newline at end of file
diff --git a/minecraftcodex/studio/static/fonts/Flat-UI-Icons.ttf b/minecraftcodex/studio/static/fonts/Flat-UI-Icons.ttf
new file mode 100755
index 0000000..73f7f4a
Binary files /dev/null and b/minecraftcodex/studio/static/fonts/Flat-UI-Icons.ttf differ
diff --git a/minecraftcodex/studio/static/fonts/Flat-UI-Icons.woff b/minecraftcodex/studio/static/fonts/Flat-UI-Icons.woff
new file mode 100755
index 0000000..7b8f80f
Binary files /dev/null and b/minecraftcodex/studio/static/fonts/Flat-UI-Icons.woff differ
diff --git a/minecraftcodex/studio/static/fonts/icomoon-session.json b/minecraftcodex/studio/static/fonts/icomoon-session.json
new file mode 100755
index 0000000..1bab5d3
--- /dev/null
+++ b/minecraftcodex/studio/static/fonts/icomoon-session.json
@@ -0,0 +1 @@
+{"share":"6", "iconsVersion":"1.5", "icomoon":{"selected":[{"idx":"783","unicode":"e02c"},{"idx":"782","unicode":"e02d"},{"idx":"780","unicode":"e02f"},{"idx":"868","unicode":"e006"},{"idx":"867","unicode":"e007"},{"idx":"866","unicode":"e008"},{"idx":"865","unicode":"e009"},{"idx":"864","unicode":"e00a"},{"idx":"863","unicode":"e00b"},{"idx":"862","unicode":"e00c"},{"idx":"861","unicode":"e00d"},{"idx":"860","unicode":"e00e"},{"idx":"859","unicode":"e00f"},{"idx":"858","unicode":"e010"},{"idx":"857","unicode":"e011"},{"idx":"856","unicode":"e012"},{"idx":"855","unicode":"e013"},{"idx":"847","unicode":"e01c"},{"idx":"846","unicode":"e01d"},{"idx":"797","unicode":"e01e"},{"idx":"796","unicode":"e01f"},{"idx":"792","unicode":"e024"},{"idx":"893","unicode":"e02b"},{"idx":"892","unicode":"e032"},{"idx":"891","unicode":"e033"},{"idx":"890","unicode":"e034"},{"idx":"793","unicode":"e022"},{"idx":"953","unicode":"e03b"},{"idx":"954","unicode":"e03c"},{"idx":"929","unicode":"e000"}],"customIcons":[{"metadata":{"id":"iconic","name":"Iconic","link":"http://somerandomdude.com/work/iconic/","grid":"16","author":"P.J. Onori","authorLink":"http://somerandomdude.com","license":"CC BY-SA 3.0","licenseLink":"http://creativecommons.org/licenses/by-sa/3.0/us/","defaultunicode":false},"svgs":["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""]},{"metadata":{"id":"meteocons","name":"Meteocons","link":"http://www.alessioatzeni.com/meteocons/","grid":"16","author":"Alessio Atzeni","authorLink":"http://www.alessioatzeni.com/","license":"Arbitrary","licenseLink":"http://www.alessioatzeni.com/meteocons/#about","defaultunicode":false},"svgs":["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""]},{"metadata":{"id":"broccolidry","name":"Broccolidry","link":"http://dribbble.com/shots/587469-Free-16px-Broccolidryiconsaniconsetitisfullof-icons","grid":"16","author":"Visual Idiot","authorLink":"http://idiot.vc/","license":"Aribitrary","licenseLink":"http://licence.visualidiot.com/","defaultunicode":false},"svgs":["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""]},{"metadata":{"id":"icomoon","name":"IcoMoon - Free","link":"http://keyamoon.com/icomoon/","grid":"16","author":"Keyamoon","authorLink":"http://keyamoon.com/","license":"CC BY 3.0","licenseLink":"http://creativecommons.org/licenses/by/3.0/","defaultunicode":false},"svgs":["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""]},{"metadata":{"id":"linecons","name":"Linecons","link":"http://designmodo.com/linecons-free/","grid":"32","author":"Sergey Shmidt","authorLink":"http://shmidt.in/","license":"CC BY-SA 3.0","licenseLink":"http://creativecommons.org/licenses/by-sa/3.0/","defaultunicode":false},"svgs":["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""]},"","","","","","","","","","","","","","","","","","","","","","","","","","",{"metadata":{"id":"Flat-UI-Icons","name":"Flat UI Icons","link":"http://designmodo.com/flat","grid":"16","author":"Sergey Shmidt","authorLink":"http://designmodo.com","license":"Attribution-NonCommercial-NoDerivs 3.0 Unported","licenseLink":"http://creativecommons.org/licenses/by-nc-nd/3.0/","defaultunicode":true},"svgs":["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""]},"","",""],"IDs":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,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,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,780,782,783,792,796,797,846,847,855,856,857,858,859,860,861,862,863,864,865,866,867,868,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,793,953,954],"user":{"email":"keyamoon@gmail.com","newsletter":true,"secret":"29769e48fe4bab8807b024a41d770900e18015c1af12cf4ad63d2d19009e6a90aead0d2885d7a32787d7336b442a44662cdfddfa2a2b0c74445becb1f50a8998","uid":4}},"inputCache":"{\"baseline\":\"6.25\",\"emSize\":\"512\",\"prev_size\":\"16\",\"hdr-imported\":\"checked\",\"iconAlignment\":\"0\",\"showGrid\":true,\"fi_name\":\"Flat UI Icons\",\"fi_id\":\"Flat-UI-Icons\",\"fi_link\":\"http://designmodo.com/flat\",\"fi_author\":\"Sergey Shmidt\",\"fi_authorLink\":\"http://designmodo.com\",\"fi_license\":\"Attribution-NonCommercial-NoDerivs 3.0 Unported\",\"fi_licenseLink\":\"http://creativecommons.org/licenses/by-nc-nd/3.0/\",\"include_metadata\":true,\"base64\":false,\"img-height\":\"32\",\"img-color\":\"000000\",\"include_png\":\"checked\",\"fi_class\":\"fui-\",\"showCloudLinks\":false,\"sprites-cols\":\"16\",\"ligatures\":false,\"include_sprites\":false,\"hdr-iconic\":false,\"hdr-meteocons\":false,\"hdr-broccolidry\":false,\"hdr-icomoon\":false,\"hdr-linecons\":false,\"whitespace\":\"50\",\"glyph_widths\":\"100\",\"manualMetrics\":false,\"designGrid\":\"\",\"hdr-Flat-UI-Icons\":true}"}
\ No newline at end of file
diff --git a/minecraftcodex/studio/static/lib/flatui/js/application.js b/minecraftcodex/studio/static/lib/flatui/js/application.js
new file mode 100755
index 0000000..7e92868
--- /dev/null
+++ b/minecraftcodex/studio/static/lib/flatui/js/application.js
@@ -0,0 +1,68 @@
+// Some general UI pack related JS
+// Extend JS String with repeat method
+String.prototype.repeat = function(num) {
+ return new Array(num + 1).join(this);
+};
+
+(function($) {
+
+ // Add segments to a slider
+ $.fn.addSliderSegments = function (amount) {
+ return this.each(function () {
+ var segmentGap = 100 / (amount - 1) + "%"
+ , segment = "
";
+ $(this).prepend(segment.repeat(amount - 2));
+ });
+ };
+
+ $(function() {
+
+ // Todo list
+ $(".todo li").click(function() {
+ $(this).toggleClass("todo-done");
+ });
+
+ // Custom Select
+ $("select[name='herolist']").selectpicker({style: 'btn-primary', menuStyle: 'dropdown-inverse'});
+
+ // Tooltips
+ $("[data-toggle=tooltip]").tooltip("show");
+
+ // Tags Input
+ $(".tagsinput").tagsInput();
+
+ // jQuery UI Sliders
+ var $slider = $("#slider");
+ if ($slider.length) {
+ $slider.slider({
+ min: 1,
+ max: 5,
+ value: 2,
+ orientation: "horizontal",
+ range: "min"
+ }).addSliderSegments($slider.slider("option").max);
+ }
+
+ // Placeholders for input/textarea
+ $("input, textarea").placeholder();
+
+ // Make pagination demo work
+ $(".pagination a").on('click', function() {
+ $(this).parent().siblings("li").removeClass("active").end().addClass("active");
+ });
+
+ $(".btn-group a").on('click', function() {
+ $(this).siblings().removeClass("active").end().addClass("active");
+ });
+
+ // Disable link clicks to prevent page scrolling
+ $('a[href="#fakelink"]').on('click', function (e) {
+ e.preventDefault();
+ });
+
+ // Switch
+ $("[data-toggle='switch']").wrap('').parent().bootstrapSwitch();
+
+ });
+
+})(jQuery);
\ No newline at end of file
diff --git a/minecraftcodex/studio/static/lib/flatui/js/bootstrap-select.js b/minecraftcodex/studio/static/lib/flatui/js/bootstrap-select.js
new file mode 100755
index 0000000..db38f79
--- /dev/null
+++ b/minecraftcodex/studio/static/lib/flatui/js/bootstrap-select.js
@@ -0,0 +1,413 @@
+!function($) {
+ var Selectpicker = function(element, options, e) {
+ if (e ) {
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ this.$element = $(element);
+ this.$newElement = null;
+ this.button = null;
+
+ //Merge defaults, options and data-attributes to make our options
+ this.options = $.extend({}, $.fn.selectpicker.defaults, this.$element.data(), typeof options == 'object' && options);
+
+ //If we have no title yet, check the attribute 'title' (this is missed by jq as its not a data-attribute
+ if(this.options.title==null)
+ this.options.title = this.$element.attr('title');
+
+ //Expose public methods
+ this.val = Selectpicker.prototype.val;
+ this.render = Selectpicker.prototype.render;
+ this.init();
+ };
+
+ Selectpicker.prototype = {
+
+ constructor: Selectpicker,
+
+ init: function (e) {
+ var _this = this;
+ this.$element.hide();
+ this.multiple = this.$element.prop('multiple');
+
+
+ var classList = this.$element.attr('class') !== undefined ? this.$element.attr('class').split(/\s+/) : '';
+ var id = this.$element.attr('id');
+ this.$element.after( this.createView() );
+ this.$newElement = this.$element.next('.select');
+ var select = this.$newElement;
+ var menu = this.$newElement.find('.dropdown-menu');
+ var menuArrow = this.$newElement.find('.dropdown-arrow');
+ var menuA = menu.find('li > a');
+ var liHeight = select.addClass('open').find('.dropdown-menu li > a').outerHeight();
+ select.removeClass('open');
+ var divHeight = menu.find('li .divider').outerHeight(true);
+ var selectOffset_top = this.$newElement.offset().top;
+ var size = 0;
+ var menuHeight = 0;
+ var selectHeight = this.$newElement.outerHeight();
+ this.button = this.$newElement.find('> button');
+ if (id !== undefined) {
+ this.button.attr('id', id);
+ $('label[for="' + id + '"]').click(function(){ select.find('button#'+id).focus(); })
+ }
+ for (var i = 0; i < classList.length; i++) {
+ if(classList[i] != 'selectpicker') {
+ this.$newElement.addClass(classList[i]);
+ }
+ }
+ //If we are multiple, then add the show-tick class by default
+ if(this.multiple) {
+ this.$newElement.addClass('select-multiple');
+ }
+ this.button.addClass(this.options.style);
+ menu.addClass(this.options.menuStyle);
+ menuArrow.addClass(function() {
+ if (_this.options.menuStyle) {
+ return _this.options.menuStyle.replace('dropdown-', 'dropdown-arrow-');
+ }
+ });
+ this.checkDisabled();
+ this.checkTabIndex();
+ this.clickListener();
+ var menuPadding = parseInt(menu.css('padding-top')) + parseInt(menu.css('padding-bottom')) + parseInt(menu.css('border-top-width')) + parseInt(menu.css('border-bottom-width'));
+ if (this.options.size == 'auto') {
+ function getSize() {
+ var selectOffset_top_scroll = selectOffset_top - $(window).scrollTop();
+ var windowHeight = window.innerHeight;
+ var menuExtras = menuPadding + parseInt(menu.css('margin-top')) + parseInt(menu.css('margin-bottom')) + 2;
+ var selectOffset_bot = windowHeight - selectOffset_top_scroll - selectHeight - menuExtras;
+ menuHeight = selectOffset_bot;
+ if (select.hasClass('dropup')) {
+ menuHeight = selectOffset_top_scroll - menuExtras;
+ }
+ menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'auto', 'min-height' : 'auto'});
+ //menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'auto', 'min-height' : liHeight*3 + 'px'});
+ }
+ getSize();
+ $(window).resize(getSize);
+ $(window).scroll(getSize);
+ this.$element.bind('DOMNodeInserted', getSize);
+ } else if (this.options.size && this.options.size != 'auto' && menu.find('li').length > this.options.size) {
+ var optIndex = menu.find("li > *").filter(':not(.divider)').slice(0,this.options.size).last().parent().index();
+ var divLength = menu.find("li").slice(0,optIndex + 1).find('.divider').length;
+ menuHeight = liHeight*this.options.size + divLength*divHeight + menuPadding;
+ menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'scroll'});
+ }
+
+ //Listen for updates to the DOM and re render...
+ this.$element.bind('DOMNodeInserted', $.proxy(this.reloadLi, this));
+
+ this.render();
+ },
+
+ createDropdown: function() {
+ var drop =
+ "" +
+ "" +
+ "" +
+ "" +
+ "
";
+
+ return $(drop);
+ },
+
+
+ createView: function() {
+ var $drop = this.createDropdown();
+ var $li = this.createLi();
+ $drop.find('ul').append($li);
+ return $drop;
+ },
+
+ reloadLi: function() {
+ //Remove all children.
+ this.destroyLi();
+ //Re build
+ $li = this.createLi();
+ this.$newElement.find('ul').append( $li );
+ //render view
+ this.render();
+ },
+
+ destroyLi:function() {
+ this.$newElement.find('li').remove();
+ },
+
+ createLi: function() {
+
+ var _this = this;
+ var _li = [];
+ var _liA = [];
+ var _liHtml = '';
+
+ this.$element.find('option').each(function(){
+ _li.push($(this).text());
+ });
+
+ this.$element.find('option').each(function(index) {
+ //Get the class and text for the option
+ var optionClass = $(this).attr("class") !== undefined ? $(this).attr("class") : '';
+ var text = $(this).text();
+ var subtext = $(this).data('subtext') !== undefined ? ''+$(this).data('subtext')+'' : '';
+
+ //Append any subtext to the main text.
+ text+=subtext;
+
+ if ($(this).parent().is('optgroup') && $(this).data('divider') != true) {
+ if ($(this).index() == 0) {
+ //Get the opt group label
+ var label = $(this).parent().attr('label');
+ var labelSubtext = $(this).parent().data('subtext') !== undefined ? ''+$(this).parent().data('subtext')+'' : '';
+ label += labelSubtext;
+
+ if ($(this)[0].index != 0) {
+ _liA.push(
+ ''+
+ ''+label+''+
+ _this.createA(text, "opt " + optionClass )
+ );
+ } else {
+ _liA.push(
+ ''+label+''+
+ _this.createA(text, "opt " + optionClass ));
+ }
+ } else {
+ _liA.push( _this.createA(text, "opt " + optionClass ) );
+ }
+ } else if ($(this).data('divider') == true) {
+ _liA.push('');
+ } else {
+ _liA.push( _this.createA(text, optionClass ) );
+ }
+ });
+
+ if (_li.length > 0) {
+ for (var i = 0; i < _li.length; i++) {
+ var $option = this.$element.find('option').eq(i);
+ _liHtml += "" + _liA[i] + "";
+ }
+ }
+
+ //If we dont have a selected item, and we dont have a title, select the first element so something is set in the button
+ if(this.$element.find('option:selected').length==0 && !_this.options.title) {
+ this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');
+ }
+
+ return $(_liHtml);
+ },
+
+ createA:function(test, classes) {
+ return '' +
+ '' + test + '' +
+ '';
+
+ },
+
+ render:function() {
+ var _this = this;
+
+ //Set width of select
+ if (this.options.width == 'auto') {
+ var ulWidth = this.$newElement.find('.dropdown-menu').css('width');
+ this.$newElement.css('width',ulWidth);
+ } else if (this.options.width && this.options.width != 'auto') {
+ this.$newElement.css('width',this.options.width);
+ }
+
+ //Update the LI to match the SELECT
+ this.$element.find('option').each(function(index) {
+ _this.setDisabled(index, $(this).is(':disabled') || $(this).parent().is(':disabled') );
+ _this.setSelected(index, $(this).is(':selected') );
+ });
+
+
+
+ var selectedItems = this.$element.find('option:selected').map(function(index,value) {
+ if($(this).attr('title')!=undefined) {
+ return $(this).attr('title');
+ } else {
+ return $(this).text();
+ }
+ }).toArray();
+
+ //Convert all the values into a comma delimited string
+ var title = selectedItems.join(", ");
+
+ //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..
+ if(_this.multiple && _this.options.selectedTextFormat.indexOf('count') > -1) {
+ var max = _this.options.selectedTextFormat.split(">");
+ if( (max.length>1 && selectedItems.length > max[1]) || (max.length==1 && selectedItems.length>=2)) {
+ title = selectedItems.length +' of ' + this.$element.find('option').length + ' selected';
+ }
+ }
+
+ //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text
+ if(!title) {
+ title = _this.options.title != undefined ? _this.options.title : _this.options.noneSelectedText;
+ }
+
+ this.$element.next('.select').find('.filter-option').html( title );
+ },
+
+
+
+ setSelected:function(index, selected) {
+ if(selected) {
+ this.$newElement.find('li').eq(index).addClass('selected');
+ } else {
+ this.$newElement.find('li').eq(index).removeClass('selected');
+ }
+ },
+
+ setDisabled:function(index, disabled) {
+ if(disabled) {
+ this.$newElement.find('li').eq(index).addClass('disabled');
+ } else {
+ this.$newElement.find('li').eq(index).removeClass('disabled');
+ }
+ },
+
+ checkDisabled: function() {
+ if (this.$element.is(':disabled')) {
+ this.button.addClass('disabled');
+ this.button.click(function(e) {
+ e.preventDefault();
+ });
+ }
+ },
+
+ checkTabIndex: function() {
+ if (this.$element.is('[tabindex]')) {
+ var tabindex = this.$element.attr("tabindex");
+ this.button.attr('tabindex', tabindex);
+ }
+ },
+
+ clickListener: function() {
+ var _this = this;
+
+ $('body').on('touchstart.dropdown', '.dropdown-menu', function (e) { e.stopPropagation(); });
+
+
+
+ this.$newElement.on('click', 'li a', function(e){
+ var clickedIndex = $(this).parent().index(),
+ $this = $(this).parent(),
+ $select = $this.parents('.select');
+
+
+ //Dont close on multi choice menu
+ if(_this.multiple) {
+ e.stopPropagation();
+ }
+
+ e.preventDefault();
+
+ //Dont run if we have been disabled
+ if ($select.prev('select').not(':disabled') && !$(this).parent().hasClass('disabled')){
+ //Deselect all others if not multi select box
+ if (!_this.multiple) {
+ $select.prev('select').find('option').removeAttr('selected');
+ $select.prev('select').find('option').eq(clickedIndex).prop('selected', true).attr('selected', 'selected');
+ }
+ //Else toggle the one we have chosen if we are multi selet.
+ else {
+ var selected = $select.prev('select').find('option').eq(clickedIndex).prop('selected');
+
+ if(selected) {
+ $select.prev('select').find('option').eq(clickedIndex).removeAttr('selected');
+ } else {
+ $select.prev('select').find('option').eq(clickedIndex).prop('selected', true).attr('selected', 'selected');
+ }
+ }
+
+
+ $select.find('.filter-option').html($this.text());
+ $select.find('button').focus();
+
+ // Trigger select 'change'
+ $select.prev('select').trigger('change');
+ }
+
+ });
+
+ this.$newElement.on('click', 'li.disabled a, li dt, li .divider', function(e) {
+ e.preventDefault();
+ e.stopPropagation();
+ $select = $(this).parent().parents('.select');
+ $select.find('button').focus();
+ });
+
+ this.$element.on('change', function(e) {
+ _this.render();
+ });
+ },
+
+ val:function(value) {
+
+ if(value!=undefined) {
+ this.$element.val( value );
+
+ this.$element.trigger('change');
+ return this.$element;
+ } else {
+ return this.$element.val();
+ }
+ }
+
+ };
+
+ $.fn.selectpicker = function(option, event) {
+ //get the args of the outer function..
+ var args = arguments;
+ var value;
+ var chain = this.each(function () {
+ var $this = $(this),
+ data = $this.data('selectpicker'),
+ options = typeof option == 'object' && option;
+
+ if (!data) {
+ $this.data('selectpicker', (data = new Selectpicker(this, options, event)));
+ } else {
+ for(var i in option) {
+ data[i]=option[i];
+ }
+ }
+
+ if (typeof option == 'string') {
+ //Copy the value of option, as once we shift the arguments
+ //it also shifts the value of option.
+ property = option;
+ if(data[property] instanceof Function) {
+ [].shift.apply(args);
+ value = data[property].apply(data, args);
+ } else {
+ value = data[property];
+ }
+ }
+ });
+
+ if(value!=undefined) {
+ return value;
+ } else {
+ return chain;
+ }
+ };
+
+ $.fn.selectpicker.defaults = {
+ style: null,
+ size: 'auto',
+ title: null,
+ selectedTextFormat : 'values',
+ noneSelectedText : 'Nothing selected',
+ width: null,
+ menuStyle: null,
+ toggleSize: null
+ }
+
+}(window.jQuery);
diff --git a/minecraftcodex/studio/static/lib/flatui/js/bootstrap-switch.js b/minecraftcodex/studio/static/lib/flatui/js/bootstrap-switch.js
new file mode 100755
index 0000000..b5c8074
--- /dev/null
+++ b/minecraftcodex/studio/static/lib/flatui/js/bootstrap-switch.js
@@ -0,0 +1,251 @@
+/* ============================================================
+ * bootstrapSwitch v1.3 by Larentis Mattia @spiritualGuru
+ * http://www.larentis.eu/switch/
+ * ============================================================
+ * Licensed under the Apache License, Version 2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * ============================================================ */
+
+!function ($) {
+ "use strict";
+
+ $.fn['bootstrapSwitch'] = function (method) {
+ var methods = {
+ init: function () {
+ return this.each(function () {
+ var $element = $(this)
+ , $div
+ , $switchLeft
+ , $switchRight
+ , $label
+ , myClasses = ""
+ , classes = $element.attr('class')
+ , color
+ , moving
+ , onLabel = "ON"
+ , offLabel = "OFF"
+ , icon = false;
+
+ $.each(['switch-mini', 'switch-small', 'switch-large'], function (i, el) {
+ if (classes.indexOf(el) >= 0)
+ myClasses = el;
+ });
+
+ $element.addClass('has-switch');
+
+ if ($element.data('on') !== undefined)
+ color = "switch-" + $element.data('on');
+
+ if ($element.data('on-label') !== undefined)
+ onLabel = $element.data('on-label');
+
+ if ($element.data('off-label') !== undefined)
+ offLabel = $element.data('off-label');
+
+ if ($element.data('icon') !== undefined)
+ icon = $element.data('icon');
+
+ $switchLeft = $('')
+ .addClass("switch-left")
+ .addClass(myClasses)
+ .addClass(color)
+ .html(onLabel);
+
+ color = '';
+ if ($element.data('off') !== undefined)
+ color = "switch-" + $element.data('off');
+
+ $switchRight = $('')
+ .addClass("switch-right")
+ .addClass(myClasses)
+ .addClass(color)
+ .html(offLabel);
+
+ $label = $('