commit e33b80ed7aa2a3aaaedc942bf1545f2c22a34a56 Author: ale Date: Fri Apr 5 22:48:34 2019 +0200 initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..e7af771 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# JQAB +## JQuery Alpaca Builder + +``` +cd form-builder && docker-compose up -d --build +``` + +And then connect to [jqab](http://jqab:8080/index.html) + +### License MIT \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a775ed3 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +version: '2' + +services: + jqab: + build: ./jqab + container_name: jqab + hostname: jqab + entrypoint: + - node + - index + expose: + - 8080 + networks: + - net + +networks: + net: \ No newline at end of file diff --git a/web/Dockerfile b/web/Dockerfile new file mode 100644 index 0000000..68a4db8 --- /dev/null +++ b/web/Dockerfile @@ -0,0 +1,4 @@ +FROM node:8-slim +ADD . /web +WORKDIR /web +RUN yarn \ No newline at end of file diff --git a/web/index.js b/web/index.js new file mode 100644 index 0000000..7d8eee2 --- /dev/null +++ b/web/index.js @@ -0,0 +1,10 @@ +'use strict' +const finalhandler = require('finalhandler'), + http = require('http'), + serveStatic = require('serve-static'), + serve = serveStatic(__dirname + '/public', { 'index': ['index.html'] }), + server = http.createServer(function onRequest(req, res) { + serve(req, res, finalhandler(req, res)) + }).listen(8080, () => { + console.log(`Serving on ${server.address().address}:${server.address().port}`) + }) diff --git a/web/package.json b/web/package.json new file mode 100644 index 0000000..32aaee1 --- /dev/null +++ b/web/package.json @@ -0,0 +1,33 @@ +{ + "name": "jqab", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "private": true, + "scripts": { + "install": "cp node_modules/jquery/dist/jquery.min.js node_modules/bootstrap/dist/js/bootstrap.js node_modules/handlebars/dist/handlebars.min.js node_modules/alpaca/dist/alpaca/bootstrap/alpaca.min.js node_modules/js-beautify/js/lib/beautify.js node_modules/js-beautify/js/lib/beautify-css.js node_modules/js-beautify/js/lib/beautify-html.js node_modules/typeahead.js/dist/bloodhound.min.js node_modules/typeahead.js/dist/typeahead.bundle.min.js node_modules/datatables.net/js/jquery.dataTables.js node_modules/datatables.net-bs/js/dataTables.bootstrap.js node_modules/datatables.net-rowreorder/js/dataTables.rowReorder.js node_modules/ckeditor/ckeditor.js node_modules/blueimp-file-upload/js/vendor/jquery.ui.widget.js node_modules/blueimp-file-upload/js/jquery.iframe-transport.js node_modules/blueimp-file-upload/js/jquery.fileupload.js node_modules/blueimp-file-upload/js/jquery.fileupload-process.js node_modules/blueimp-file-upload/js/jquery.fileupload-ui.js node_modules/handsontable/dist/handsontable.full.js node_modules/moment/min/moment-with-locales.min.js node_modules/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js node_modules/bootstrap-multiselect/dist/js/bootstrap-multiselect.js node_modules/jquery-price-format/jquery.priceformat.min.js node_modules/ace-builds/src-min-noconflict/ace.js node_modules/jquery-ui-dist/jquery-ui.js node_modules/ace-builds/src-min-noconflict/mode-json.js node_modules/ace-builds/src-min-noconflict/mode-javascript.js node_modules/ace-builds/src-min-noconflict/worker-json.js node_modules/ace-builds/src-min-noconflict/worker-javascript.js public/js && cp node_modules/bootstrap/dist/css/bootstrap.css node_modules/bootstrap/dist/css/bootstrap-theme.css node_modules/alpaca/dist/alpaca/bootstrap/alpaca.min.css node_modules/js-beautify/js/lib/beautify-css.js node_modules/datatables.net-bs/css/dataTables.bootstrap.css node_modules/blueimp-file-upload/css/jquery.fileupload.css node_modules/blueimp-file-upload/css/jquery.fileupload-ui.css node_modules/handsontable/dist/handsontable.full.css node_modules/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.css node_modules/bootstrap-multiselect/dist/css/bootstrap-multiselect.css public/css" + }, + "dependencies": { + "ace-builds": "^1.4.3", + "alpaca": "^1.5.24", + "blueimp-file-upload": "^9.28.0", + "bootstrap": "^3.4.1", + "bootstrap-multiselect": "^0.9.13-1", + "ckeditor": "^4.11.3", + "datatables.net": "^1.10.19", + "datatables.net-bs": "^1.10.19", + "datatables.net-rowreorder": "^1.2.5", + "eonasdan-bootstrap-datetimepicker": "^4.17.47", + "finalhandler": "^1.1.1", + "handlebars": "^4.1.1", + "handsontable": "^7.0.0", + "jquery": "^3.3.1", + "jquery-price-format": "^0.0.1", + "jquery-ui-dist": "^1.12.1", + "js-beautify": "^1.9.1", + "moment": "^2.24.0", + "moment-timezone": "^0.4.0", + "serve-static": "^1.13.2", + "typeahead.js": "^0.11.1" + } +} diff --git a/web/public/css/form-builder.css b/web/public/css/form-builder.css new file mode 100644 index 0000000..ba21c0e --- /dev/null +++ b/web/public/css/form-builder.css @@ -0,0 +1,93 @@ +body +{ + padding-top: 70px; +} + +.row +{ + padding-top: 20px; +} + +#schema +{ + width: 99%; + height: 400px; + border: 1px #aaa solid; +} + +#options +{ + width: 99%; + height: 400px; + border: 1px #aaa solid; +} + +#data +{ + width: 99%; + height: 400px; + border: 1px #aaa solid; +} + +#codeDiv +{ + width: 99%; + height: 400px; + border: 1px #aaa solid; +} + +.form-element +{ + padding: 5px; + border: 1px #ccc solid; + box-shadow: #ccc 2px 2px; + margin: 10px; + border-radius: 4px; + background-color: #eee; +} + +.form-element-title +{ + font-weight: 600; +} + +.dropzone +{ + clear: both; + margin: 0px; + padding: 0px; +} + +.dropzone-highlight +{ + margin-top: 4px; + height: 20px; + border: 1px #888 dashed; +} + +.dropzone-hover +{ + height: 100px; + border: 1px #888 dashed; + background-color: #eee; +} + +.modal-header +{ + background-color: #f5f5f5; + border-top-left-radius: 6px; + border-top-right-radius: 6px; +} + +.ui-hover-state +{ + background-color: #aaa !important; + opacity: 0.1 !important; +} + +.dashed +{ + border: 1px #ccc dashed; + padding: 10px; +} + diff --git a/web/public/index.html b/web/public/index.html new file mode 100644 index 0000000..ece256b --- /dev/null +++ b/web/public/index.html @@ -0,0 +1,218 @@ + + + + JQAB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+ +
+ +
+
+
+
+
+
+
+ + diff --git a/web/public/js/form-builder.js b/web/public/js/form-builder.js new file mode 100644 index 0000000..d67a95e --- /dev/null +++ b/web/public/js/form-builder.js @@ -0,0 +1,1101 @@ +var setup = function() +{ + //Alpaca.logLevel = Alpaca.DEBUG; + + var MODAL_VIEW = "bootstrap-edit-horizontal"; + //var MODAL_VIEW = "bootstrap-edit"; + + var MODAL_TEMPLATE = ' \ + \ + '; + + var schema = { + "type": "object", + "properties": { + "email": { + "type": "string", + "required": false + }, + "password": { + "type": "string", + "required": false, + "pattern": {} + }, + "file": { + "type": "string", + "required": false + }, + "check": { + "type": "boolean", + "required": false, + "default": true + } + } + }; + var options = { + "fields": { + "email": { + "type": "text", + "label": "Email Address" + }, + "password": { + "type": "password", + "label": "Password" + }, + "file": { + "type": "file", + "label": "File Upload" + }, + "check": { + "type": "checkbox", + "rightLabel": "Sign me up for the News Letter!", + "label": "Newsletter" + } + } + }; + var data = { + "email": "Joe Smith", + "password": "MyPassword" + }; + + var setupEditor = function(id, json) + { + var text = ""; + if (json) + { + text = JSON.stringify(json, null, " "); + } + + var editor = ace.edit(id); + editor.setTheme("ace/theme/textmate"); + if (json) + { + editor.getSession().setMode("ace/mode/json"); + } + else + { + editor.getSession().setMode("ace/mode/javascript"); + } + editor.renderer.setHScrollBarAlwaysVisible(false); + editor.setShowPrintMargin(false); + editor.setValue(text); + + setTimeout(function() { + editor.clearSelection(); + editor.gotoLine(0,0); + }, 100); + + return editor; + }; + + var editor1 = setupEditor("schema", schema); + var editor2 = setupEditor("options", options); + var editor3 = setupEditor("data", data); + var editor4 = setupEditor("codeDiv"); + + var mainViewField = null; + var mainPreviewField = null; + var mainDesignerField = null; + + var doRefresh = function(el, buildInteractionLayers, disableErrorHandling, cb) + { + try + { + schema = JSON.parse(editor1.getValue()); + } + catch (e) + { + } + + try + { + options = JSON.parse(editor2.getValue()); + } + catch (e) + { + } + + try + { + data = JSON.parse(editor3.getValue()); + } + catch (e) + { + } + + if (schema) + { + var config = { + "schema": schema + }; + if (options) + { + config.options = options; + } + if (data) + { + config.data = data; + } + if (!config.options) { + config.options = {}; + } + config.options.focus = false; + config.postRender = function(form) { + + if (buildInteractionLayers) + { + // cover every control with an interaction layer + form.getFieldEl().find(".alpaca-container-item").each(function(iCount) { + + var $el = $(this); + var alpacaFieldId = $el.children().first().attr("data-alpaca-field-id"); + + //iCount++; + $el.attr("icount", iCount); + + var width = $el.outerWidth() - 22; + var height = $el.outerHeight() + 25; + + // cover div + var cover = $("
"); + $(cover).addClass("cover"); + $(cover).attr("alpaca-ref-id", alpacaFieldId); + $(cover).css({ + "position": "absolute", + "margin-top": "-" + height + "px", + "margin-left": "-10px", + "width": width, + "height": height + 10, + "opacity": 0, + "background-color": "white", + "z-index": 900 + }); + $(cover).attr("icount-ref", iCount); + $el.append(cover); + + // interaction div + var interaction = $("
"); + var buttonGroup = $("
"); + //var schemaButton = $(""); + var schemaButton = $(''); + buttonGroup.append(schemaButton); + //var optionsButton = $(""); + var optionsButton = $(''); + buttonGroup.append(optionsButton); + //var removeButton = $(""); + var removeButton = $(''); + buttonGroup.append(removeButton); + interaction.append(buttonGroup); + interaction.append("
"); + $(interaction).addClass("interaction"); + $(interaction).attr("alpaca-ref-id", alpacaFieldId); + $(interaction).css({ + "position": "absolute", + "margin-top": "-" + height + "px", + "margin-left": "-10px", + "width": width, + "height": height + 10, + "opacity": 1, + "z-index": 901 + }); + $(interaction).attr("icount-ref", iCount); + $el.append(interaction); + $(buttonGroup).css({ + "margin-top": 5 + (($(interaction).height() / 2) - ($(buttonGroup).height() / 2)), + "margin-right": "16px" + }); + $(schemaButton).off().click(function(e) { + + e.preventDefault(); + e.stopPropagation(); + + var alpacaId = $(this).attr("alpaca-ref-id"); + + editSchema(alpacaId); + }); + $(optionsButton).off().click(function(e) { + + e.preventDefault(); + e.stopPropagation(); + + var alpacaId = $(this).attr("alpaca-ref-id"); + + editOptions(alpacaId); + }); + $(removeButton).off().click(function(e) { + + e.preventDefault(); + e.stopPropagation(); + + var alpacaId = $(this).attr("alpaca-ref-id"); + removeField(alpacaId); + }); + + // when hover, highlight + $(interaction).hover(function(e) { + var iCount = $(interaction).attr("icount-ref"); + $(".cover[icount-ref='" + iCount + "']").addClass("ui-hover-state"); + }, function(e) { + var iCount = $(interaction).attr("icount-ref"); + $(".cover[icount-ref='" + iCount + "']").removeClass("ui-hover-state"); + }); + }); + + // add dashed + form.getFieldEl().find(".alpaca-container").addClass("dashed"); + form.getFieldEl().find(".alpaca-container-item").addClass("dashed"); + + // for every container, add a "first" drop zone element + // this covers empty containers as well as 0th index insertions + form.getFieldEl().find(".alpaca-container").each(function() { + var containerEl = this; + + // first insertion point + $(this).prepend("
"); + + // all others + $(containerEl).children(".alpaca-container-item").each(function() { + $(this).after("
"); + }); + + }); + + form.getFieldEl().find(".dropzone").droppable({ + "tolerance": "touch", + "drop": function( event, ui ) { + + var draggable = $(ui.draggable); + + if (draggable.hasClass("form-element")) + { + var dataType = draggable.attr("data-type"); + var fieldType = draggable.attr("data-field-type"); + + // based on where the drop occurred, figure out the previous and next Alpaca fields surrounding + // the drop target + + // previous + var previousField = null; + var previousFieldKey = null; + var previousItemContainer = $(event.target).prev(); + if (previousItemContainer) + { + var previousAlpacaId = $(previousItemContainer).children().first().attr("data-alpaca-field-id"); + previousField = Alpaca.fieldInstances[previousAlpacaId]; + + previousFieldKey = $(previousItemContainer).attr("data-alpaca-container-item-name"); + } + + // next + var nextField = null; + var nextFieldKey = null; + var nextItemContainer = $(event.target).next(); + if (nextItemContainer) + { + var nextAlpacaId = $(nextItemContainer).children().first().attr("data-alpaca-field-id"); + nextField = Alpaca.fieldInstances[nextAlpacaId]; + + nextFieldKey = $(nextItemContainer).attr("data-alpaca-container-item-name"); + } + + // parent field + var parentFieldAlpacaId = $(event.target).parent().parent().attr("data-alpaca-field-id"); + var parentField = Alpaca.fieldInstances[parentFieldAlpacaId]; + + // now do the insertion + insertField(schema, options, data, dataType, fieldType, parentField, previousField, previousFieldKey, nextField, nextFieldKey); + } + else if (draggable.hasClass("interaction")) + { + var draggedIndex = $(draggable).attr("icount-ref"); + + // next + var nextItemContainer = $(event.target).next(); + var nextItemContainerIndex = $(nextItemContainer).attr("data-alpaca-container-item-index"); + var nextItemAlpacaId = $(nextItemContainer).children().first().attr("data-alpaca-field-id"); + var nextField = Alpaca.fieldInstances[nextItemAlpacaId]; + + form.moveItem(draggedIndex, nextItemContainerIndex, false, function() { + + var top = findTop(nextField); + + regenerate(top); + }); + } + + }, + "over": function (event, ui ) { + $(event.target).addClass("dropzone-hover"); + }, + "out": function (event, ui) { + $(event.target).removeClass("dropzone-hover"); + } + }); + + // init any in-place draggables + form.getFieldEl().find(".interaction").draggable({ + "appendTo": "body", + "helper": function() { + var iCount = $(this).attr("icount-ref"); + var clone = $(".alpaca-container-item[icount='" + iCount + "']").clone(); + return clone; + }, + "cursorAt": { + "top": 100 + }, + "zIndex": 300, + "refreshPositions": true, + "start": function(event, ui) { + $(".dropzone").addClass("dropzone-highlight"); + }, + "stop": function(event, ui) { + $(".dropzone").removeClass("dropzone-highlight"); + } + }); + } + + cb(null, form); + }; + config.error = function(err) + { + Alpaca.defaultErrorCallback(err); + + cb(err); + }; + + if (disableErrorHandling) + { + Alpaca.defaultErrorCallback = function(error) { + console.log("Alpaca encountered an error while previewing form -> " + error.message); + }; + } + else + { + Alpaca.defaultErrorCallback = Alpaca.DEFAULT_ERROR_CALLBACK; + } + + $(el).alpaca(config); + } + }; + + var removeFunctionFields = function(schema, options) + { + if (schema) + { + if (schema.properties) + { + var badKeys = []; + + for (var k in schema.properties) + { + if (schema.properties[k].type === "function") + { + badKeys.push(k); + } + else + { + removeFunctionFields(schema.properties[k], (options && options.fields ? options.fields[k] : null)); + } + } + + for (var i = 0; i < badKeys.length; i++) + { + delete schema.properties[badKeys[i]]; + + if (options && options.fields) { + delete options.fields[badKeys[i]]; + } + } + } + } + }; + + var editSchema = function(alpacaFieldId, callback) + { + var field = Alpaca.fieldInstances[alpacaFieldId]; + + var fieldSchemaSchema = field.getSchemaOfSchema(); + var fieldSchemaOptions = field.getOptionsForSchema(); + removeFunctionFields(fieldSchemaSchema, fieldSchemaOptions); + var fieldData = field.schema; + + delete fieldSchemaSchema.title; + delete fieldSchemaSchema.description; + if (fieldSchemaSchema.properties) + { + delete fieldSchemaSchema.properties.title; + delete fieldSchemaSchema.properties.description; + delete fieldSchemaSchema.properties.dependencies; + } + var fieldConfig = { + schema: fieldSchemaSchema + }; + if (fieldSchemaOptions) + { + fieldConfig.options = fieldSchemaOptions; + } + if (fieldData) + { + fieldConfig.data = fieldData; + } + fieldConfig.view = { + "parent": MODAL_VIEW, + "displayReadonly": false + }; + fieldConfig.postRender = function(control) + { + var modal = $(MODAL_TEMPLATE.trim()); + modal.find(".modal-title").append(field.getTitle()); + modal.find(".modal-body").append(control.getFieldEl()); + + modal.find('.modal-footer').append(""); + modal.find('.modal-footer').append(""); + + $(modal).modal({ + "keyboard": true + }); + + $(modal).find(".okay").click(function() { + + field.schema = control.getValue(); + + var top = findTop(field); + regenerate(top); + + if (callback) + { + callback(); + } + }); + + control.getFieldEl().find("p.help-block").css({ + "display": "none" + }); + }; + + var x = $("
"); + $(x).find(".fieldForm").alpaca(fieldConfig); + }; + + var editOptions = function(alpacaFieldId, callback) + { + var field = Alpaca.fieldInstances[alpacaFieldId]; + + var fieldOptionsSchema = field.getSchemaOfOptions(); + var fieldOptionsOptions = field.getOptionsForOptions(); + removeFunctionFields(fieldOptionsSchema, fieldOptionsOptions); + var fieldOptionsData = field.options; + + delete fieldOptionsSchema.title; + delete fieldOptionsSchema.description; + if (fieldOptionsSchema.properties) + { + delete fieldOptionsSchema.properties.title; + delete fieldOptionsSchema.properties.description; + delete fieldOptionsSchema.properties.dependencies; + delete fieldOptionsSchema.properties.readonly; + } + if (fieldOptionsOptions.fields) + { + delete fieldOptionsOptions.fields.title; + delete fieldOptionsOptions.fields.description; + delete fieldOptionsOptions.fields.dependencies; + delete fieldOptionsOptions.fields.readonly; + } + + var fieldConfig = { + schema: fieldOptionsSchema + }; + if (fieldOptionsOptions) + { + fieldConfig.options = fieldOptionsOptions; + } + if (fieldOptionsData) + { + fieldConfig.data = fieldOptionsData; + } + fieldConfig.view = { + "parent": MODAL_VIEW, + "displayReadonly": false + }; + fieldConfig.postRender = function(control) + { + var modal = $(MODAL_TEMPLATE.trim()); + modal.find(".modal-title").append(field.getTitle()); + modal.find(".modal-body").append(control.getFieldEl()); + + modal.find('.modal-footer').append(""); + modal.find('.modal-footer').append(""); + + $(modal).modal({ + "keyboard": true + }); + + $(modal).find(".okay").click(function() { + + field.options = control.getValue(); + + var top = findTop(field); + regenerate(top); + + if (callback) + { + callback(); + } + }); + + control.getFieldEl().find("p.help-block").css({ + "display": "none" + }); + }; + + var x = $("
"); + $(x).find(".fieldForm").alpaca(fieldConfig); + }; + + var refreshView = function(callback) + { + if (mainViewField) + { + mainViewField.getFieldEl().replaceWith("
"); + mainViewField.destroy(); + mainViewField = null; + } + + doRefresh($("#viewDiv"), false, false, function(err, form) { + + if (!err) + { + mainViewField = form; + } + + if (callback) + { + callback(); + } + + }); + }; + + var refreshPreview = function(callback) + { + if (mainPreviewField) + { + mainPreviewField.getFieldEl().replaceWith("
"); + mainPreviewField.destroy(); + mainPreviewField = null; + } + + doRefresh($("#previewDiv"), false, false, function(err, form) { + + if (!err) + { + mainPreviewField = form; + } + + if (callback) + { + callback(); + } + + }); + }; + + var refreshDesigner = function(callback) + { + $(".dropzone").remove(); + $(".interaction").remove(); + $(".cover").remove(); + + if (mainDesignerField) + { + mainDesignerField.getFieldEl().replaceWith("
"); + mainDesignerField.destroy(); + mainDesignerField = null; + } + + doRefresh($("#designerDiv"), true, false, function(err, form) { + + if (!err) + { + mainDesignerField = form; + } + + if (callback) + { + callback(); + } + + }); + }; + + var refreshCode = function(callback) + { + var json = { + "schema": schema + }; + if (options) { + json.options = options; + } + if (data) { + json.data = data; + } + var code = "$('#div').alpaca(" + JSON.stringify(json, null, " ") + ");"; + + editor4.setValue(code); + editor4.clearSelection(); + editor4.gotoLine(0,0); + + if (callback) + { + callback(); + } + }; + + var refresh = function(callback) + { + var current = $("UL.nav.nav-tabs LI.active A.tab-item"); + $(current).click(); + }; + + var rtChange = false; + editor1.on("change", function() { + rtChange = true; + }); + editor2.on("change", function() { + rtChange = true; + }); + editor3.on("change", function() { + rtChange = true; + }); + + // background "thread" to detect changes and update the preview div + var rtProcessing = false; + var rtFunction = function() { + + if (rtChange && !rtProcessing) + { + rtProcessing = true; + if (mainPreviewField) + { + mainPreviewField.getFieldEl().replaceWith("
"); + mainPreviewField.destroy(); + mainPreviewField = null; + } + doRefresh($("#previewDiv"), false, true, function(err, form) { + + if (!err) + { + mainPreviewField = form; + } + + rtChange = false; + rtProcessing = false; + }); + } + + setTimeout(rtFunction, 1000); + + }; + rtFunction(); + + var isCoreField = function(type) + { + var cores = ["any", "array", "checkbox", "file", "hidden", "number", "object", "radio", "select", "text", "textarea"]; + + var isCore = false; + for (var i = 0; i < cores.length; i++) + { + if (cores[i] == type) + { + isCore = true; + } + } + + return isCore; + }; + + // types + var types = [{ + "type": "string", + "title": "String", + "description": "A textual property" + }, { + "type": "number", + "title": "Number", + "description": "A numerical property" + }, { + "type": "boolean", + "title": "Boolean", + "description": "A true/false property" + }, { + "type": "object", + "title": "Object", + "description": "A collection of keyed sub-properties" + }, { + "type": "array", + "title": "Array", + "description": "An array of sub-properties" + }]; + for (var i = 0; i < types.length; i++) + { + var title = types[i].title; + var type = types[i].type; + var description = types[i].description; + + var div = $("
"); + $(div).append("
" + title + " (" + type + ")
"); + $(div).append("
" + description + "
"); + + $("#types").append(div); + } + + var afterAlpacaInit = function() + { + // show all fields + for (var type in Alpaca.fieldClassRegistry) + { + var instance = new Alpaca.fieldClassRegistry[type](); + + var schemaSchema = instance.getSchemaOfSchema(); + var schemaOptions = instance.getOptionsForSchema(); + var optionsSchema = instance.getSchemaOfOptions(); + var optionsOptions = instance.getOptionsForOptions(); + var title = instance.getTitle(); + var description = instance.getDescription(); + var type = instance.getType(); + var fieldType = instance.getFieldType(); + + var div = $("
"); + $(div).append("
" + title + " (" + fieldType + ")
"); + $(div).append("
" + description + "
"); + + var isCore = isCoreField(fieldType); + if (isCore) + { + $("#basic").append(div); + } + else + { + $("#advanced").append(div); + } + + // init all of the draggable form elements + $(".form-element").draggable({ + "appendTo": "body", + "helper": "clone", + "zIndex": 300, + "refreshPositions": true, + "start": function(event, ui) { + $(".dropzone").addClass("dropzone-highlight"); + }, + "stop": function(event, ui) { + $(".dropzone").removeClass("dropzone-highlight"); + } + }); + } + }; + + // lil hack to force compile + $("
").alpaca({ + "data": "test", + "postRender": function(control) + { + afterAlpacaInit(); + } + }); + + + $(".tab-item-source").click(function() { + + // we have to monkey around a bit with ACE Editor to get it to refresh + editor1.setValue(editor1.getValue()); + editor1.clearSelection(); + editor2.setValue(editor2.getValue()); + editor2.clearSelection(); + editor3.setValue(editor3.getValue()); + editor3.clearSelection(); + + setTimeout(function() { + refreshPreview(); + }, 50); + }); + $(".tab-item-view").click(function() { + setTimeout(function() { + refreshView(); + }, 50); + }); + $(".tab-item-designer").click(function() { + setTimeout(function() { + refreshDesigner(); + }, 50); + }); + $(".tab-item-code").click(function() { + setTimeout(function() { + refreshCode(); + }, 50); + }); + + $(".tab-source-schema").click(function() { + // we have to monkey around a bit with ACE Editor to get it to refresh + editor1.setValue(editor1.getValue()); + editor1.clearSelection(); + }); + + $(".tab-source-options").click(function() { + // we have to monkey around a bit with ACE Editor to get it to refresh + editor2.setValue(editor2.getValue()); + editor2.clearSelection(); + }); + + $(".tab-source-data").click(function() { + // we have to monkey around a bit with ACE Editor to get it to refresh + editor3.setValue(editor3.getValue()); + editor3.clearSelection(); + }); + + var insertField = function(schema, options, data, dataType, fieldType, parentField, previousField, previousFieldKey, nextField, nextFieldKey) + { + var itemSchema = { + "type": dataType + }; + var itemOptions = {}; + if (fieldType) + { + itemOptions.type = fieldType; + } + itemOptions.label = "New "; + if (fieldType) + { + itemOptions.label += fieldType; + } + else if (dataType) + { + itemOptions.label += dataType; + } + var itemData = null; + + var itemKey = null; + if (parentField.getType() === "array") + { + itemKey = 0; + if (previousFieldKey) + { + itemKey = previousFieldKey + 1; + } + } + else if (parentField.getType() === "object") + { + itemKey = "new" + new Date().getTime(); + } + + var insertAfterId = null; + if (previousField) + { + insertAfterId = previousField.id; + } + + parentField.addItem(itemKey, itemSchema, itemOptions, itemData, insertAfterId, function() { + + var top = findTop(parentField); + + regenerate(top); + }); + + }; + + var assembleSchema = function(field, schema) + { + // copy any properties from this field's schema into our schema object + for (var k in field.schema) + { + if (field.schema.hasOwnProperty(k) && typeof(field.schema[k]) !== "function") + { + schema[k] = field.schema[k]; + } + } + // a few that we handle by hand + schema.type = field.getType(); + // reset properties, we handle that one at a time + delete schema.properties; + schema.properties = {}; + if (field.children) + { + for (var i = 0; i < field.children.length; i++) + { + var childField = field.children[i]; + var propertyId = childField.propertyId; + + schema.properties[propertyId] = {}; + assembleSchema(childField, schema.properties[propertyId]); + } + } + }; + + var assembleOptions = function(field, options) + { + // copy any properties from this field's options into our options object + for (var k in field.options) + { + if (field.options.hasOwnProperty(k) && typeof(field.options[k]) !== "function") + { + options[k] = field.options[k]; + } + } + // a few that we handle by hand + options.type = field.getFieldType(); + // reset fields, we handle that one at a time + delete options.fields; + options.fields = {}; + if (field.children) + { + for (var i = 0; i < field.children.length; i++) + { + var childField = field.children[i]; + var propertyId = childField.propertyId; + + options.fields[propertyId] = {}; + assembleOptions(childField, options.fields[propertyId]); + } + } + }; + + var findTop = function(field) + { + // now get the top control + var top = field; + while (top.parent) + { + top = top.parent; + } + + return top; + }; + + var regenerate = function(top) + { + // walk the control tree and re-assemble the schema, options + data + var _schema = {}; + assembleSchema(top, _schema); + var _options = {}; + assembleOptions(top, _options); + // data is easy + var _data = top.getValue(); + if (!_data) { + _data = {}; + } + + editor1.setValue(JSON.stringify(_schema, null, " ")); + editor2.setValue(JSON.stringify(_options, null, " ")); + editor3.setValue(JSON.stringify(_data, null, " ")); + + setTimeout(function() { + refresh(); + }, 100); + }; + + var removeField = function(alpacaId) + { + var field = Alpaca.fieldInstances[alpacaId]; + + var parentField = field.parent; + parentField.removeItem(field.propertyId, function() { + var top = findTop(field); + regenerate(top); + }); + }; + + $(".tab-item-source").click(); + + + // load button + $(".load-button").off().click(function() { + + if (!localStorage) + { + alert("Your browser must support HTML5 local storage in order to use this feature"); + return; + } + + var configString = localStorage.getItem("alpacaDesignerConfig"); + if (!configString) + { + return; + } + + try + { + var config = JSON.parse(configString); + if (!config.schema) { + config.schema = {}; + } + if (!config.options) { + config.options = {}; + } + if (!config.data) { + config.data = {}; + } + + editor1.setValue(JSON.stringify(config.schema, null, " ")); + editor2.setValue(JSON.stringify(config.options, null, " ")); + editor3.setValue(JSON.stringify(config.data, null, " ")); + + //alert("Your form was loaded from HTML5 local storage"); + } + catch (e) + { + // bad value + } + + }); + + // save button + $(".save-button").off().click(function() { + + if (!localStorage) + { + alert("Your browser must support HTML5 local storage in order to use this feature"); + return; + } + + var config = {}; + if (schema) + { + config.schema = schema; + } + if (options) + { + config.options = options; + } + if (data) + { + config.data = data; + } + var configString = JSON.stringify(config); + + localStorage.setItem("alpacaDesignerConfig", configString); + + //alert("Your form was saved in HTML5 local storage"); + }); +}; + +$(document).ready(function() { + + // wait a bit to allow ACE to load + setTimeout(function() { + setup(); + }, 200); +}); diff --git a/web/yarn.lock b/web/yarn.lock new file mode 100644 index 0000000..eec88c9 --- /dev/null +++ b/web/yarn.lock @@ -0,0 +1,579 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@handsontable/formulajs@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@handsontable/formulajs/-/formulajs-2.0.0.tgz#3e41fedbb51a195dd5b8c2694afe171ec08f3a02" + integrity sha1-PkH+27UaGV3VuMJpSv4XHsCPOgI= + dependencies: + bessel "^0.2.0" + jStat "^1.7.0" + +"@types/pikaday@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@types/pikaday/-/pikaday-1.6.0.tgz#46c1d67a9ef706284ac2b72bf31bf381a56bf3c0" + integrity sha512-cnKjF7i6oA1ADxQdSWHcEStLZeiH8qbf6l7B9O88PhLgnmbUMM62ali0/PaDtINm6ezpNcqtERWL6Y+pAgHKQQ== + dependencies: + moment ">=2.14.0" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +ace-builds@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.4.3.tgz#789c5e72226c01d9bbe1095c8aeea37afb57f41b" + integrity sha512-T+e4DQRQR8ReNPOUryXWdXRX1NBTb9rB1y42IhnH4mmFe0NIIpAQVu8BQ9tgU2K3EGaPFZeG7E87OOjaXDP8PQ== + +alpaca@^1.5.24: + version "1.5.24" + resolved "https://registry.yarnpkg.com/alpaca/-/alpaca-1.5.24.tgz#80969be521fed103c11c61e34ed61b703c2d79ec" + integrity sha512-U7qF6wdND/2FL3N8RZsgbCKP3azdY16gjuI4VFIrgCAZYzEgD8tvfyWbtqP/sHiXa3vnleNNqvicZ6K9r1AxMw== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +bessel@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bessel/-/bessel-0.2.0.tgz#13cb39cd29233219ec2da725e0ba0c66fb46b6f2" + integrity sha1-E8s5zSkjMhnsLacl4LoMZvtGtvI= + dependencies: + voc "" + +bignumber.js@^8.0.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-8.1.1.tgz#4b072ae5aea9c20f6730e4e5d529df1271c4d885" + integrity sha512-QD46ppGintwPGuL1KqmwhR0O+N2cZUg8JG/VzwI2e28sM9TqHjQB10lI4QAaMHVbLzwVLLAwEglpKPViWX+5NQ== + +blueimp-canvas-to-blob@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/blueimp-canvas-to-blob/-/blueimp-canvas-to-blob-3.5.0.tgz#5679ac32f6a2835821f0c3ad661719ff85a9236b" + integrity sha1-VnmsMvaig1gh8MOtZhcZ/4WpI2s= + +blueimp-file-upload@^9.28.0: + version "9.28.0" + resolved "https://registry.yarnpkg.com/blueimp-file-upload/-/blueimp-file-upload-9.28.0.tgz#e11a7eac367d2b3fc0f1cd9d1717299686bd98b4" + integrity sha512-Qvb5/CFlmIZ2cBoItpU2zQhUIvtZsSk9tV+X632uyrDpdpvdaJxDR9Wo8i7aUhfnbO1dbLuS5/auaA04Vk+XHw== + optionalDependencies: + blueimp-canvas-to-blob "3.5.0" + blueimp-load-image "2.12.2" + blueimp-tmpl "3.6.0" + +blueimp-load-image@2.12.2: + version "2.12.2" + resolved "https://registry.yarnpkg.com/blueimp-load-image/-/blueimp-load-image-2.12.2.tgz#6a17598aab858d4fbf01543e0631141b51057c87" + integrity sha1-ahdZiquFjU+/AVQ+BjEUG1EFfIc= + +blueimp-tmpl@3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/blueimp-tmpl/-/blueimp-tmpl-3.6.0.tgz#a4910975d042e2bc03ba77f0e62d04f1548a524c" + integrity sha1-pJEJddBC4rwDunfw5i0E8VSKUkw= + +bootstrap-multiselect@^0.9.13-1: + version "0.9.13-1" + resolved "https://registry.yarnpkg.com/bootstrap-multiselect/-/bootstrap-multiselect-0.9.13-1.tgz#2c57cee260b18d7f01a4edd9d65f25df0425fd2a" + integrity sha1-LFfO4mCxjX8BpO3Z1l8l3wQl/So= + +bootstrap@^3.3, bootstrap@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-3.4.1.tgz#c3a347d419e289ad11f4033e3c4132b87c081d72" + integrity sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +ckeditor@^4.11.3: + version "4.11.3" + resolved "https://registry.yarnpkg.com/ckeditor/-/ckeditor-4.11.3.tgz#91f66d7ddb5bff3874514fe539779686874ed655" + integrity sha512-v6G+v16WAcukKuQH6m+trA9RCOQntFM2nxPO/GFiLYsdD/5IbZAZ2n7GwMxQmxDXpx4AixpnMWF+yAE1t9wq6Q== + +commander@^2.19.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + +commander@~2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +config-chain@^1.1.12: + version "1.1.12" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" + integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +datatables.net-bs@^1.10.19: + version "1.10.19" + resolved "https://registry.yarnpkg.com/datatables.net-bs/-/datatables.net-bs-1.10.19.tgz#08763b4e4d0cef1a427d019dc15e717c7ed67a4d" + integrity sha512-5gxoI2n+duZP06+4xVC2TtH6zcY369/TRKTZ1DdSgDcDUl4OYQsrXCuaLJmbVzna/5Y5lrMmK7CxgvYgIynICA== + dependencies: + datatables.net "1.10.19" + jquery ">=1.7" + +datatables.net-rowreorder@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/datatables.net-rowreorder/-/datatables.net-rowreorder-1.2.5.tgz#2582f02fb08b9e11744d6a9dc9cdda9953f6f611" + integrity sha512-FHFnEkOpbMk2BJCnRqi4A7lGE3VdiyHEnLRGVEieYH/7ohmJxgrhxHdWratXK4IMs8OvKw51epFeaAaMmXNlZQ== + dependencies: + datatables.net "^1.10.15" + jquery ">=1.7" + +datatables.net@1.10.19, datatables.net@^1.10.15, datatables.net@^1.10.19: + version "1.10.19" + resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-1.10.19.tgz#97a1ed41c85e62d61040603481b59790a172dd1f" + integrity sha512-+ljXcI6Pj3PTGy5pesp3E5Dr3x3AV45EZe0o1r0gKENN2gafBKXodVnk2ypKwl2tTmivjxbkiqoWnipTefyBTA== + dependencies: + jquery ">=1.7" + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +editorconfig@^0.15.2: + version "0.15.3" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" + integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== + dependencies: + commander "^2.19.0" + lru-cache "^4.1.5" + semver "^5.6.0" + sigmund "^1.0.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +eonasdan-bootstrap-datetimepicker@^4.17.47: + version "4.17.47" + resolved "https://registry.yarnpkg.com/eonasdan-bootstrap-datetimepicker/-/eonasdan-bootstrap-datetimepicker-4.17.47.tgz#7a49970044065276e7965efd16f822735219e735" + integrity sha1-ekmXAEQGUnbnll79Fvgic1IZ5zU= + dependencies: + bootstrap "^3.3" + jquery "^1.8.3 || ^2.0 || ^3.0" + moment "^2.10" + moment-timezone "^0.4.0" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +finalhandler@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.4.0" + unpipe "~1.0.0" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +glob@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +handlebars@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.1.tgz#6e4e41c18ebe7719ae4d38e5aca3d32fa3dd23d3" + integrity sha512-3Zhi6C0euYZL5sM0Zcy7lInLXKQ+YLcF/olbN010mzGQ4XVm50JeyBnMqofHh696GrciGruC7kCcApPDJvVgwA== + dependencies: + neo-async "^2.6.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +handsontable@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/handsontable/-/handsontable-7.0.0.tgz#654c441eb837f4049b45af3cf37bc5b75eaec4bf" + integrity sha512-j6AozjIwpTHV+tgyejlAZnSQiRFRyxptEAIyon9pBNKqpIjj2CFeqh+IZjPUvOCcOdKhkXFJIXoObcMIuAu1bA== + dependencies: + "@types/pikaday" "1.6.0" + hot-formula-parser "^3.0.0" + moment "2.20.1" + numbro "^2.0.6" + pikaday "1.5.1" + +hot-formula-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hot-formula-parser/-/hot-formula-parser-3.0.0.tgz#4019db8d565b84293ad7d1e46fcc1a4f894bb72e" + integrity sha512-CHLTrsrv29it5XPcHalNO8ClcJGHefwf599MePlG5dYzxxtbPqx/qt8CkrqvxQeNA5XtkAUcxU62OFv0z2L49A== + dependencies: + "@handsontable/formulajs" "^2.0.0" + tiny-emitter "^2.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +jStat@^1.7.0: + version "1.7.1" + resolved "https://registry.yarnpkg.com/jStat/-/jStat-1.7.1.tgz#e636dd87d72b305c060dfcc901de1732d15130c1" + integrity sha512-toueem/U5hyHM6pqe6OZOL/5P8MrY7Ss1K8Brg+TcfX+RAjDU/sbwy72fwzmLPQ5ykdBe1UEoWQHc7OSNWMUDQ== + +jquery-price-format@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/jquery-price-format/-/jquery-price-format-0.0.1.tgz#a452fd18445d3058c51c36113353cfb4f49322e7" + integrity sha1-pFL9GERdMFjFHDYRM1PPtPSTIuc= + +jquery-ui-dist@^1.12.1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/jquery-ui-dist/-/jquery-ui-dist-1.12.1.tgz#5c0815d3cc6f90ff5faaf5b268a6e23b4ca904fa" + integrity sha1-XAgV08xvkP9fqvWyaKbiO0ypBPo= + +jquery@>=1.7, "jquery@^1.8.3 || ^2.0 || ^3.0", jquery@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca" + integrity sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg== + +js-beautify@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.9.1.tgz#6f9ef915f5d8d92b9f907606fce63795884c8040" + integrity sha512-oxxvVZdOdUfzk8IOLBF2XUZvl2GoBEfA+b0of4u2EBY/46NlXasi8JdFvazA5lCrf9/lQhTjyVy2QCUW7iq0MQ== + dependencies: + config-chain "^1.1.12" + editorconfig "^0.15.2" + glob "^7.1.3" + mkdirp "~0.5.0" + nopt "~4.0.1" + +lru-cache@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +mkdirp@~0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +moment-timezone@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.4.1.tgz#81f598c3ad5e22cdad796b67ecd8d88d0f5baa06" + integrity sha1-gfWYw61eIs2teWtn7NjYjQ9bqgY= + dependencies: + moment ">= 2.6.0" + +moment@2.20.1: + version "2.20.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd" + integrity sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg== + +moment@2.x, "moment@>= 2.6.0", moment@>=2.14.0, moment@^2.10, moment@^2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +neo-async@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.0.tgz#b9d15e4d71c6762908654b5183ed38b753340835" + integrity sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA== + +nopt@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + +numbro@^2.0.6: + version "2.1.2" + resolved "https://registry.yarnpkg.com/numbro/-/numbro-2.1.2.tgz#2d51104f09b5d69aef7e15bb565d7795e47ecfd6" + integrity sha512-7w833BxZmKGLE9HI0aREtNVRVH6WTYUUlWf4qgA5gKNhPQ4F/MRZ14sc0v8eoLORprk9ZTVwYaLwj8N3Zgxwiw== + dependencies: + bignumber.js "^8.0.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-tmpdir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +pikaday@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pikaday/-/pikaday-1.5.1.tgz#0a48549bc1a14ea1d08c44074d761bc2f2bfcfd3" + integrity sha1-CkhUm8GhTqHQjEQHTXYbwvK/z9M= + optionalDependencies: + moment "2.x" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= + +semver@^5.6.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + +serve-static@^1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +sigmund@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + +source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== + +tiny-emitter@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" + integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== + +typeahead.js@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/typeahead.js/-/typeahead.js-0.11.1.tgz#4e64e671b22310a8606f4aec805924ba84b015b8" + integrity sha1-TmTmcbIjEKhgb0rsgFkkuoSwFbg= + dependencies: + jquery ">=1.7" + +uglify-js@^3.1.4: + version "3.5.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.5.3.tgz#d490bb5347f23025f0c1bc0dee901d98e4d6b063" + integrity sha512-rIQPT2UMDnk4jRX+w4WO84/pebU2jiLsjgIyrCktYgSvx28enOE3iYQMr+BD1rHiitWnDmpu0cY/LfIEpKcjcw== + dependencies: + commander "~2.19.0" + source-map "~0.6.1" + +unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +voc@: + version "1.1.0" + resolved "https://registry.yarnpkg.com/voc/-/voc-1.1.0.tgz#d1a08aeff66646bf17cdba2e47c935a7a9b0218b" + integrity sha512-fthgd8OJLqq8vPcLjElTk6Rcl2e3v5ekcXauImaqEnQqd5yUWKg1+ZOBgS2KTWuVKcuvZMQq4TDptiT1uYddUA== + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=