var Workbench = (function () { 'use strict';

function recompute ( state, newState, oldState, isInitial ) {
	if ( isInitial || ( 'autoscale' in newState && differs( state.autoscale, oldState.autoscale ) ) ) {
		state.autoscaleValue = newState.autoscaleValue = template.computed.autoscaleValue( state.autoscale );
	}

	if ( isInitial || ( 'loadedComposition' in newState && differs( state.loadedComposition, oldState.loadedComposition ) ) ) {
		state.displaySavedComposition = newState.displaySavedComposition = template.computed.displaySavedComposition( state.loadedComposition );
	}

	if ( isInitial || ( 'displaySavedComposition' in newState && differs( state.displaySavedComposition, oldState.displaySavedComposition ) ) || ( 'autoscaleValue' in newState && differs( state.autoscaleValue, oldState.autoscaleValue ) ) ) {
		state.compositionOptions = newState.compositionOptions = template.computed.compositionOptions( state.displaySavedComposition, state.autoscaleValue );
	}

	if ( isInitial || ( 'displaySavedComposition' in newState && differs( state.displaySavedComposition, oldState.displaySavedComposition ) ) || ( 'height' in newState && differs( state.height, oldState.height ) ) || ( 'width' in newState && differs( state.width, oldState.width ) ) || ( 'autoscaleValue' in newState && differs( state.autoscaleValue, oldState.autoscaleValue ) ) ) {
		state.embedCode = newState.embedCode = template.computed.embedCode( state.displaySavedComposition, state.height, state.width, state.autoscaleValue );
	}
}

var template = (function () {
var copyFrom = function (textarea) {
  textarea.select();

  try {
    var successful = document.execCommand('copy');
    console.log('Copied!');
  } catch (err) {
    console.log(textarea.value);
    return console.error('Oops, unable to copy', err);
  }
};

return {
  data: function data() {
    return {
      width: 400,
      height: 400,
      loadedComposition: 'new',
      autoscale: true,
      widget: {
        name: '',
      },
    };
  },

  computed: {
    autoscaleValue: function (autoscale) { return (autoscale ? 'on' : 'off'); },
    displaySavedComposition: function (loadedComposition) { return loadedComposition === 'new' ? false : loadedComposition; },
    compositionOptions: function (displaySavedComposition, autoscaleValue) { return displaySavedComposition
        ? [
            displaySavedComposition,
            { edit_mode: true, autoscale: autoscaleValue } ]
        : [{ widget_id: 'widget', edit_mode: true, autoscale: autoscaleValue }]; },

    embedCode: function (displaySavedComposition, height, width, autoscaleValue) { return displaySavedComposition &&
      ("\n      <script>\n        window.widgeticOptions = {\n          domain: 'local.widgetic.com:8082',\n          secure: false,\n        }\n      </script >\n      <script async src=\"http://local.widgetic.com:8082/modules/@widgetic/sdk/lib/sdk.dev.js\"></script >\n      <a href=\"#\" class=\"widgetic-composition\" data-autoscale=\"" + autoscaleValue + "\" data-id=\"" + displaySavedComposition + "\" data-width=\"" + width + "\" data-height=\"" + height + "\" data-brand=\"bottom-right\">\n    "); },
  },

  events: {
    drag: function drag(node, callback) {
      var self = this;
      function onmousedown(event) {
        self.set({ dragging: true });
        var rect = node.getBoundingClientRect();
        var offsetX = event.offsetX;
        var offsetY = event.offsetY;

        function drop() {
          self.set({ dragging: false });
          document.body.removeEventListener('mouseup', drop, false);
          document.body.removeEventListener('mousemove', drag, false);
        }

        function drag(event) {
          var x =
            event.pageX - (offsetX + rect.left + document.body.scrollLeft);
          var y =
            event.pageY - (offsetY + rect.top + document.body.scrollTop);
          callback({ x: x, y: y });
        }

        document.body.addEventListener('mouseup', drop, false);
        document.body.addEventListener('mousemove', drag, false);
      }

      node.addEventListener('mousedown', onmousedown, false);

      return {
        teardown: function teardown() {
          node.removeEventListener('mousedown', onmousedown, false);
        },
      };
    },
  },

  oncreate: function oncreate() {
    var this$1 = this;

    // init Widgetic SDK
    Widgetic.init('bogus', 'bogus');
    Widgetic.auth.token('bogus');

    // persist settings across reloads
    try {
      this.set(JSON.parse(localStorage.wkbncSettings));
    } catch (e) {}

    var persistSettings = function (_) {
      var ref = this$1.get();
      var width = ref.width;
      var height = ref.height;
      var autoscale = ref.autoscale;
      var widget = ref.widget;
      localStorage.wkbncSettings = JSON.stringify({
        width: width,
        height: height,
        autoscale: autoscale,
        widget: widget,
      });
    };
    window.addEventListener('unload', persistSettings);
    this.disposeUnload = function (_) { return window.removeEventListener('unload', persistSettings); };

    // display the widget
    this.observe('compositionOptions', function (compositionOptions) {
      var composition = this$1.get('composition');
      composition && composition.close();
      this$1.set({
        composition: Widgetic.UI.composition(
          this$1.refs.widgetArea,
          compositionOptions[0],
          compositionOptions[1]
        ),
      });
    });

    // create the editor
    this.observe('composition', function (composition) {
      var editor = this$1.get('editor');
      editor && editor.close();
      editor = Widgetic.UI.editor(this$1.refs.editorArea, composition);
      this$1.set({ editor: editor });
      return editor.on('composition:save', function (savedComposition) {
        this$1.refreshCompositions();
      });
    });

    Widgetic.api('widgets/widget').then(function (data) { return this$1.set({ widget: data }); });
    this.refreshCompositions();
  },

  methods: {
    refreshCompositions: function refreshCompositions() {
      var this$1 = this;

      Widgetic.api('compositions').then(function (data) { return this$1.set({ compositions: data }); }
      );
    },

    copyEmbedCode: function copyEmbedCode(event) {
      event.preventDefault();
      copyFrom(this.refs.embedCodeOutput);
    },

    copyPreset: function copyPreset(event) {
      event.preventDefault();

      var preset = JSON.parse(
        JSON.stringify(
          this.get('editor')
            ._iframe.contentWindow.require('core/models/composition')
            .first()
            .getSkin()
        )
      );
      delete preset.uses;
      delete preset.metas;
      delete preset.widget_id;
      delete preset.user_id;

      this.set({
        preset: JSON.stringify(
          Object.assign({ id: preset.id }, preset),
          null,
          '\t'
        ),
      });

      copyFrom(this.refs.presetOutput);
    },

    resetWorkbench: function resetWorkbench() {
      this.disposeUnload();
      localStorage.clear();
      window.location.reload();
    },

    openStandalone: function openStandalone() {
      window.open(this.get('composition')._iframe.src);
    },
  },
};
}());

function add_css () {
	var style = createElement( 'style' );
	style.id = "svelte-4144732467-style";
	style.textContent = "\n[svelte-4144732467].workbench, [svelte-4144732467] .workbench {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n}\n\nh1[svelte-4144732467], [svelte-4144732467] h1 {\n  color: #ec574d;\n  font-size: 16px;\n}\n\na[svelte-4144732467], [svelte-4144732467] a {\n  color: #ec574d;\n}\n\n[svelte-4144732467].resize-corner, [svelte-4144732467] .resize-corner {\n  position: absolute !important;\n  right: -30px;\n  bottom: -30px;\n  width: 30px;\n  height: 30px;\n  background: rgba(0,0,0,0.5);\n  cursor: hand;\n  cursor: -webkit-grab;\n  cursor: grab;\n  user-select: none;\n}\n\n[svelte-4144732467].dragging .resize-corner, [svelte-4144732467] .dragging .resize-corner {\n  cursor: move;\n}\n\n[svelte-4144732467].dragging, [svelte-4144732467] .dragging {\n  -webkit-touch-callout: none;\n    -webkit-user-select: none;\n     -khtml-user-select: none;\n       -moz-user-select: none;\n        -ms-user-select: none;\n            user-select: none;\n  cursor: move;\n}\n\n[svelte-4144732467].dragging iframe, [svelte-4144732467] .dragging iframe {\n  pointer-events: none;\n}\n\n[svelte-4144732467].full-editor, [svelte-4144732467] .full-editor {\n  min-height: 600px;\n}\n\n[svelte-4144732467].workbench-controls, [svelte-4144732467] .workbench-controls {\n  list-style: none;\n  margin: 40px auto;\n  width: 200px;\n  padding: 20px;\n  background: #fff;\n  box-shadow: 0 1px 2px 0 rgba(0,0,0,0.1),0 0 3px 0 rgba(0,0,0,0.1);\n}\n\n[svelte-4144732467].workbench-controls li, [svelte-4144732467] .workbench-controls li {\n  margin: 5px 0;\n}\n\n[svelte-4144732467].workbench-controls input, [svelte-4144732467] .workbench-controls input {\n  border: none;\n}\n\n[svelte-4144732467].workbench-controls_control--disabled, [svelte-4144732467] .workbench-controls_control--disabled {\n  text-decoration: line-through;\n}\n\n[svelte-4144732467].workbench-area, [svelte-4144732467] .workbench-area {\n  position: relative;\n  margin: 25px;\n  text-align: left;\n}\n\n[svelte-4144732467].widget-area, [svelte-4144732467] .widget-area {\n  vertical-align: top;\n  display: inline-block;\n  position: relative;\n}\n\n[svelte-4144732467].widget-area iframe, [svelte-4144732467] .widget-area iframe {\n  vertical-align: top;\n}\n\n[svelte-4144732467].editor-area, [svelte-4144732467] .editor-area {\n  position: absolute;\n  top: 0;\n  right: 0;\n}\n\ninput[svelte-4144732467], [svelte-4144732467] input {\n  color: #ec574d;\n}\n\ninput[svelte-4144732467][type=\"number\"], [svelte-4144732467] input[type=\"number\"] {\n  float: right;\n}\n\n\ntextarea[svelte-4144732467], [svelte-4144732467] textarea {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 0;\n  height: 0;\n  opacity: 0;\n}\n";
	appendNode( style, document.head );
}

function create_main_fragment ( state, component ) {
	var div, div_class_value, ul, h1, text_value, text, li, a, text_1, li_1, textarea, textarea_updating = false, a_1, text_2, if_block_anchor, if_block_1_anchor, li_2, a_2, text_3, li_3, label, text_4, input, input_updating = false, li_4, label_1, text_5, input_1, input_1_updating = false, li_5, label_2, text_6, input_2, input_2_updating = false, text_7, div_1, div_2, text_8, div_3, div_3_style_value, div_4, drag_handler;

	function click_handler ( event ) {
		component.resetWorkbench();
	}

	function textarea_input_handler () {
		textarea_updating = true;
		component._set({ preset: textarea.value });
		textarea_updating = false;
	}

	function click_handler_1 ( event ) {
		component.copyPreset(event);
	}

	var if_block = (state.compositions && state.compositions.length) && create_if_block( state, component );

	var if_block_1 = (state.embedCode) && create_if_block_1( state, component );

	function click_handler_2 ( event ) {
		component.openStandalone();
	}

	function input_input_handler () {
		input_updating = true;
		component._set({ width: toNumber( input.value ) });
		input_updating = false;
	}

	function input_1_input_handler () {
		input_1_updating = true;
		component._set({ height: toNumber( input_1.value ) });
		input_1_updating = false;
	}

	function input_2_change_handler () {
		input_2_updating = true;
		component._set({ autoscale: input_2.checked });
		input_2_updating = false;
	}

	function mousedown_handler ( event ) {
		var state = component.get();
		component.set({startWidth: state.width, startHeight: state.height});
	}

	return {
		create: function () {
			div = createElement( 'div' );
			ul = createElement( 'ul' );
			h1 = createElement( 'h1' );
			text = createText( text_value = state.widget.name );
			li = createElement( 'li' );
			a = createElement( 'a' );
			text_1 = createText( "Reset Workbench" );
			li_1 = createElement( 'li' );
			textarea = createElement( 'textarea' );
			a_1 = createElement( 'a' );
			text_2 = createText( "Copy Preset" );
			if ( if_block ) { if_block.create(); }
			if_block_anchor = createComment();
			if ( if_block_1 ) { if_block_1.create(); }
			if_block_1_anchor = createComment();
			li_2 = createElement( 'li' );
			a_2 = createElement( 'a' );
			text_3 = createText( "Open Standalone Page" );
			li_3 = createElement( 'li' );
			label = createElement( 'label' );
			text_4 = createText( "Width" );
			input = createElement( 'input' );
			li_4 = createElement( 'li' );
			label_1 = createElement( 'label' );
			text_5 = createText( "Height" );
			input_1 = createElement( 'input' );
			li_5 = createElement( 'li' );
			label_2 = createElement( 'label' );
			text_6 = createText( "Autoscale" );
			input_2 = createElement( 'input' );
			text_7 = createText( "\n  " );
			div_1 = createElement( 'div' );
			div_2 = createElement( 'div' );
			text_8 = createText( "\n    " );
			div_3 = createElement( 'div' );
			div_4 = createElement( 'div' );
			this.hydrate();
		},

		hydrate: function ( nodes ) {
			setAttribute( div, 'svelte-4144732467', '' );
			div.className = div_class_value = "workbench " + ( state.dragging ? 'dragging' : '' );
			ul.className = "workbench-controls";
			a.href = "#";
			addListener( a, 'click', click_handler );

			addListener( textarea, 'input', textarea_input_handler );

			a_1.href = "#";
			addListener( a_1, 'click', click_handler_1 );
			a_2.href = "#";
			addListener( a_2, 'click', click_handler_2 );
			input.type = "number";

			addListener( input, 'input', input_input_handler );

			input_1.type = "number";

			addListener( input_1, 'input', input_1_input_handler );

			input_2.type = "checkbox";

			addListener( input_2, 'change', input_2_change_handler );

			div_1.className = "workbench-area";
			div_2.className = "editor-area";
			div_3.className = "widget-area";
			div_3.style.cssText = div_3_style_value = "width: " + ( state.width ) + "px; height: " + ( state.height ) + "px;";
			div_4.className = "resize-corner";
			addListener( div_4, 'mousedown', mousedown_handler );

			drag_handler = template.events.drag.call( component, div_4, function ( event ) {
				var state = component.get();
				component.set({width: state.startWidth + event.x, height: state.startHeight + event.y});
			});
		},

		mount: function ( target, anchor ) {
			insertNode( div, target, anchor );
			appendNode( ul, div );
			appendNode( h1, ul );
			appendNode( text, h1 );
			appendNode( li, ul );
			appendNode( a, li );
			appendNode( text_1, a );
			appendNode( li_1, ul );
			appendNode( textarea, li_1 );
			component.refs.presetOutput = textarea;

			textarea.value = state.preset;

			appendNode( a_1, li_1 );
			appendNode( text_2, a_1 );
			if ( if_block ) { if_block.mount( ul, null ); }
			appendNode( if_block_anchor, ul );
			if ( if_block_1 ) { if_block_1.mount( ul, null ); }
			appendNode( if_block_1_anchor, ul );
			appendNode( li_2, ul );
			appendNode( a_2, li_2 );
			appendNode( text_3, a_2 );
			appendNode( li_3, ul );
			appendNode( label, li_3 );
			appendNode( text_4, label );
			appendNode( input, label );

			input.value = state.width;

			appendNode( li_4, ul );
			appendNode( label_1, li_4 );
			appendNode( text_5, label_1 );
			appendNode( input_1, label_1 );

			input_1.value = state.height;

			appendNode( li_5, ul );
			appendNode( label_2, li_5 );
			appendNode( text_6, label_2 );
			appendNode( input_2, label_2 );

			input_2.checked = state.autoscale;

			appendNode( text_7, div );
			appendNode( div_1, div );
			appendNode( div_2, div_1 );
			component.refs.editorArea = div_2;
			appendNode( text_8, div_1 );
			appendNode( div_3, div_1 );
			component.refs.widgetArea = div_3;
			appendNode( div_4, div_3 );
		},

		update: function ( changed, state ) {
			if ( div_class_value !== ( div_class_value = "workbench " + ( state.dragging ? 'dragging' : '' ) ) ) {
				div.className = div_class_value;
			}

			if ( text_value !== ( text_value = state.widget.name ) ) {
				text.data = text_value;
			}

			if ( !textarea_updating ) {
				textarea.value = state.preset;
			}

			if ( state.compositions && state.compositions.length ) {
				if ( if_block ) {
					if_block.update( changed, state );
				} else {
					if_block = create_if_block( state, component );
					if_block.create();
					if_block.mount( ul, if_block_anchor );
				}
			} else if ( if_block ) {
				if_block.unmount();
				if_block.destroy();
				if_block = null;
			}

			if ( state.embedCode ) {
				if ( if_block_1 ) {
					if_block_1.update( changed, state );
				} else {
					if_block_1 = create_if_block_1( state, component );
					if_block_1.create();
					if_block_1.mount( ul, if_block_1_anchor );
				}
			} else if ( if_block_1 ) {
				if_block_1.unmount();
				if_block_1.destroy();
				if_block_1 = null;
			}

			if ( !input_updating ) {
				input.value = state.width;
			}

			if ( !input_1_updating ) {
				input_1.value = state.height;
			}

			if ( !input_2_updating ) {
				input_2.checked = state.autoscale;
			}

			if ( div_3_style_value !== ( div_3_style_value = "width: " + ( state.width ) + "px; height: " + ( state.height ) + "px;" ) ) {
				div_3.style.cssText = div_3_style_value;
			}
		},

		unmount: function () {
			detachNode( div );
			if ( component.refs.presetOutput === textarea ) { component.refs.presetOutput = null; }
			if ( if_block ) { if_block.unmount(); }
			if ( if_block_1 ) { if_block_1.unmount(); }
			if ( component.refs.editorArea === div_2 ) { component.refs.editorArea = null; }
			if ( component.refs.widgetArea === div_3 ) { component.refs.widgetArea = null; }
		},

		destroy: function () {
			removeListener( a, 'click', click_handler );
			removeListener( textarea, 'input', textarea_input_handler );
			removeListener( a_1, 'click', click_handler_1 );
			if ( if_block ) { if_block.destroy(); }
			if ( if_block_1 ) { if_block_1.destroy(); }
			removeListener( a_2, 'click', click_handler_2 );
			removeListener( input, 'input', input_input_handler );
			removeListener( input_1, 'input', input_1_input_handler );
			removeListener( input_2, 'change', input_2_change_handler );
			removeListener( div_4, 'mousedown', mousedown_handler );
			drag_handler.teardown();
		}
	};
}

function create_each_block ( state, each_block_value, composition, composition_index, component ) {
	var option, option_value_value, text_value, text;

	return {
		create: function () {
			option = createElement( 'option' );
			text = createText( text_value = composition.id );
			this.hydrate();
		},

		hydrate: function ( nodes ) {
			option.__value = option_value_value = composition.id;
			option.value = option.__value;
		},

		mount: function ( target, anchor ) {
			insertNode( option, target, anchor );
			appendNode( text, option );
		},

		update: function ( changed, state, each_block_value, composition, composition_index ) {
			if ( option_value_value !== ( option_value_value = composition.id ) ) {
				option.__value = option_value_value;
			}

			option.value = option.__value;

			if ( text_value !== ( text_value = composition.id ) ) {
				text.data = text_value;
			}
		},

		unmount: function () {
			detachNode( option );
		},

		destroy: noop
	};
}

function create_if_block ( state, component ) {
	var li, label, text, select, option, text_1, each_block_anchor, select_1, select_updating = false;

	var each_block_value = state.compositions;

	var each_block_iterations = [];

	for ( var i = 0; i < each_block_value.length; i += 1 ) {
		each_block_iterations[i] = create_each_block( state, each_block_value, each_block_value[i], i, component );
	}

	function select_change_handler () {
		select_updating = true;
		var selectedOption = select.querySelector(':checked') || select.options[0];
		component._set({ loadedComposition: selectedOption && selectedOption.__value });
		select_updating = false;
	}

	return {
		create: function () {
			li = createElement( 'li' );
			label = createElement( 'label' );
			text = createText( "Load Composition\n        " );
			select = createElement( 'select' );
			option = createElement( 'option' );
			text_1 = createText( "New" );

			for ( var i = 0; i < each_block_iterations.length; i += 1 ) {
				each_block_iterations[i].create();
			}

			each_block_anchor = createComment();
			select_1 = createElement( 'select' );
			this.hydrate();
		},

		hydrate: function ( nodes ) {
			option.__value = "new";
			option.value = option.__value;

			if ( !('loadedComposition' in state) ) { component._bindings.push( select_change_handler ); }

			addListener( select, 'change', select_change_handler );
		},

		mount: function ( target, anchor ) {
			insertNode( li, target, anchor );
			appendNode( label, li );
			appendNode( text, label );
			appendNode( select, label );
			appendNode( option, select );
			appendNode( text_1, option );

			for ( var i = 0; i < each_block_iterations.length; i += 1 ) {
				each_block_iterations[i].mount( select, null );
			}

			appendNode( each_block_anchor, select );
			appendNode( select_1, select );

			var value = state.loadedComposition;
			for ( var i = 0; i < select.options.length; i += 1 ) {
				var option_1 = select.options[i];

				if ( option_1.__value === value ) {
					option_1.selected = true;
					break;
				}
			}
		},

		update: function ( changed, state ) {
			var each_block_value = state.compositions;

			if ( 'compositions' in changed ) {
				for ( var i = 0; i < each_block_value.length; i += 1 ) {
					if ( each_block_iterations[i] ) {
						each_block_iterations[i].update( changed, state, each_block_value, each_block_value[i], i );
					} else {
						each_block_iterations[i] = create_each_block( state, each_block_value, each_block_value[i], i, component );
						each_block_iterations[i].create();
						each_block_iterations[i].mount( select, each_block_anchor );
					}
				}

				for ( ; i < each_block_iterations.length; i += 1 ) {
					each_block_iterations[i].unmount();
					each_block_iterations[i].destroy();
				}
				each_block_iterations.length = each_block_value.length;
			}

			if ( !select_updating ) {
				var value = state.loadedComposition;
				for ( var i = 0; i < select.options.length; i += 1 ) {
					var option_1 = select.options[i];

					if ( option_1.__value === value ) {
						option_1.selected = true;
						break;
					}
				}
			}
		},

		unmount: function () {
			detachNode( li );

			for ( var i = 0; i < each_block_iterations.length; i += 1 ) {
				each_block_iterations[i].unmount();
			}
		},

		destroy: function () {
			destroyEach( each_block_iterations, false, 0 );

			removeListener( select, 'change', select_change_handler );
		}
	};
}

function create_if_block_1 ( state, component ) {
	var li, textarea, textarea_updating = false, a, text;

	function textarea_input_handler () {
		textarea_updating = true;
		component._set({ embedCode: textarea.value });
		textarea_updating = false;
	}

	function click_handler ( event ) {
		component.copyEmbedCode(event);
	}

	return {
		create: function () {
			li = createElement( 'li' );
			textarea = createElement( 'textarea' );
			a = createElement( 'a' );
			text = createText( "Copy Embed Code" );
			this.hydrate();
		},

		hydrate: function ( nodes ) {
			addListener( textarea, 'input', textarea_input_handler );

			a.href = "#";
			addListener( a, 'click', click_handler );
		},

		mount: function ( target, anchor ) {
			insertNode( li, target, anchor );
			appendNode( textarea, li );
			component.refs.embedCodeOutput = textarea;

			textarea.value = state.embedCode;

			appendNode( a, li );
			appendNode( text, a );
		},

		update: function ( changed, state ) {
			if ( !textarea_updating ) {
				textarea.value = state.embedCode;
			}
		},

		unmount: function () {
			detachNode( li );
			if ( component.refs.embedCodeOutput === textarea ) { component.refs.embedCodeOutput = null; }
		},

		destroy: function () {
			removeListener( textarea, 'input', textarea_input_handler );
			removeListener( a, 'click', click_handler );
		}
	};
}

function Workbench ( options ) {
	var this$1 = this;

	options = options || {};
	this.refs = {};
	this._state = assign( template.data(), options.data );
	recompute( this._state, this._state, {}, true );

	this._observers = {
		pre: Object.create( null ),
		post: Object.create( null )
	};

	this._handlers = Object.create( null );

	this._root = options._root || this;
	this._yield = options._yield;

	this._torndown = false;
	if ( !document.getElementById( "svelte-4144732467-style" ) ) { add_css(); }
	this._bindings = [];

	this._fragment = create_main_fragment( this._state, this );

	if ( options.target ) {
		this._fragment.create();
		this._fragment.mount( options.target, null );
	}

	while ( this._bindings.length ) { this$1._bindings.pop()(); }

	if ( options._root ) {
		options._root._renderHooks.push( template.oncreate.bind( this ) );
	} else {
		template.oncreate.call( this );
	}
}

assign( Workbench.prototype, template.methods, {
 	get: get,
 	fire: fire,
 	observe: observe,
 	on: on,
 	set: set,
 	_flush: _flush
 });

Workbench.prototype._set = function _set ( newState ) {
	var this$1 = this;

	var oldState = this._state;
	this._state = assign( {}, oldState, newState );
	recompute( this._state, newState, oldState, false )
	dispatchObservers( this, this._observers.pre, newState, oldState );
	this._fragment.update( newState, this._state );
	dispatchObservers( this, this._observers.post, newState, oldState );
	while ( this._bindings.length ) { this$1._bindings.pop()(); }
};

Workbench.prototype.teardown = Workbench.prototype.destroy = function destroy ( detach ) {
	this.fire( 'destroy' );

	if ( detach !== false ) { this._fragment.unmount(); }
	this._fragment.destroy();
	this._fragment = null;

	this._state = {};
	this._torndown = true;
};

function createElement(name) {
	return document.createElement(name);
}

function insertNode(node, target, anchor) {
	target.insertBefore(node, anchor);
}

function setAttribute(node, attribute, value) {
	node.setAttribute(attribute, value);
}

function detachNode(node) {
	node.parentNode.removeChild(node);
}

function appendNode(node, target) {
	target.appendChild(node);
}

function createText(data) {
	return document.createTextNode(data);
}

function addListener(node, event, handler) {
	node.addEventListener(event, handler, false);
}

function removeListener(node, event, handler) {
	node.removeEventListener(event, handler, false);
}

function destroyEach(iterations, detach, start) {
	for (var i = start; i < iterations.length; i += 1) {
		if (iterations[i]) { iterations[i].destroy(detach); }
	}
}

function createComment() {
	return document.createComment('');
}

function toNumber(value) {
	return value === '' ? undefined : +value;
}

function differs(a, b) {
	return a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}

function assign(target) {
	var arguments$1 = arguments;

	var k,
		source,
		i = 1,
		len = arguments.length;
	for (; i < len; i++) {
		source = arguments$1[i];
		for (k in source) { target[k] = source[k]; }
	}

	return target;
}

function dispatchObservers(component, group, newState, oldState) {
	for (var key in group) {
		if (!(key in newState)) { continue; }

		var newValue = newState[key];
		var oldValue = oldState[key];

		if (differs(newValue, oldValue)) {
			var callbacks = group[key];
			if (!callbacks) { continue; }

			for (var i = 0; i < callbacks.length; i += 1) {
				var callback = callbacks[i];
				if (callback.__calling) { continue; }

				callback.__calling = true;
				callback.call(component, newValue, oldValue);
				callback.__calling = false;
			}
		}
	}
}

function noop() {}

function get(key) {
	return key ? this._state[key] : this._state;
}

function fire(eventName, data) {
	var this$1 = this;

	var handlers =
		eventName in this._handlers && this._handlers[eventName].slice();
	if (!handlers) { return; }

	for (var i = 0; i < handlers.length; i += 1) {
		handlers[i].call(this$1, data);
	}
}

function observe(key, callback, options) {
	var group = options && options.defer
		? this._observers.post
		: this._observers.pre;

	(group[key] || (group[key] = [])).push(callback);

	if (!options || options.init !== false) {
		callback.__calling = true;
		callback.call(this, this._state[key]);
		callback.__calling = false;
	}

	return {
		cancel: function() {
			var index = group[key].indexOf(callback);
			if (~index) { group[key].splice(index, 1); }
		}
	};
}

function on(eventName, handler) {
	if (eventName === 'teardown') { return this.on('destroy', handler); }

	var handlers = this._handlers[eventName] || (this._handlers[eventName] = []);
	handlers.push(handler);

	return {
		cancel: function() {
			var index = handlers.indexOf(handler);
			if (~index) { handlers.splice(index, 1); }
		}
	};
}

function set(newState) {
	this._set(assign({}, newState));
	this._root._flush();
}

function _flush() {
	var this$1 = this;

	if (!this._renderHooks) { return; }

	while (this._renderHooks.length) {
		this$1._renderHooks.pop()();
	}
}

return Workbench;

}());
