-- No property for this plugin --<\/div>');\n }\n }\n else {\n this.dom_fill('html', '
-- No property for selection --<\/div>');\n }\n },\n\n _refresh_property_coords: function (binder) {\n var fields = {\n x: {\n type: 'number',\n value: binder.left\n },\n y: {\n type: 'number',\n value: binder.top\n }\n };\n\n if (binder.hasOwnProperty('z')) {\n fields.z = {\n type: 'number',\n value: 0\n };\n }\n\n this.element_coords = this.element_add('wemplate_form_fields_line', {\n html: '',\n dom_parent: this.dom_html,\n label: 'Position',\n fields: fields\n });\n\n \/\/ x\n this.bind_dom(this.element_coords.fields.x.dom, 'change', 'input_position_x_change', 'active');\n this.bind_dom(this.element_coords.fields.x.dom, 'keyup', 'input_position_x_change', 'active');\n \/\/ y\n this.bind_dom(this.element_coords.fields.y.dom, 'change', 'input_position_y_change', 'active');\n this.bind_dom(this.element_coords.fields.y.dom, 'keyup', 'input_position_y_change', 'active');\n \/\/ z\n if (binder.hasOwnProperty('z')) {\n this.bind_dom(this.element_coords.fields.z.dom, 'change', 'input_position_z_change', 'active');\n this.bind_dom(this.element_coords.fields.z.dom, 'keyup', 'input_position_z_change', 'active');\n }\n },\n\n _refresh_property_sizes: function (binder) {\n var fields = {\n size_x: {\n type: 'number',\n value: binder.width\n },\n size_y: {\n type: 'number',\n value: binder.height\n }\n };\n\n if (binder.hasOwnProperty('depth')) {\n fields.size_z = {\n type: 'number',\n value: binder.depth\n };\n }\n\n this.element_sizes = this.element_add('wemplate_form_fields_line', {\n html: '',\n dom_parent: this.dom_html,\n label: 'Size',\n fields: fields\n });\n \/\/ x\n this.bind_dom(this.element_sizes.fields.size_x.dom, 'change', 'input_width_change', 'active');\n this.bind_dom(this.element_sizes.fields.size_x.dom, 'keyup', 'input_width_change', 'active');\n \/\/ y\n this.bind_dom(this.element_sizes.fields.size_y.dom, 'change', 'input_height_change', 'active');\n this.bind_dom(this.element_sizes.fields.size_y.dom, 'keyup', 'input_height_change', 'active');\n \/\/ z\n if (binder.hasOwnProperty('depth')) {\n this.bind_dom(this.element_sizes.fields.size_z.dom, 'change', 'input_depth_change', 'active');\n this.bind_dom(this.element_sizes.fields.size_z.dom, 'keyup', 'input_depth_change', 'active');\n }\n },\n\n _refresh_property_rotations: function (binder) {\n \/\/ rotation\n this.element_rotation = this.element_add('wemplate_form_fields_line', {\n html: '',\n dom_parent: this.dom_html,\n label: 'Rotation',\n fields: {\n h: {\n type: 'number',\n value: binder.rotate_h\n },\n p: {\n type: 'number',\n value: binder.rotate_p\n },\n b: {\n type: 'number',\n value: binder.rotate_b\n }\n }\n });\n \/\/ x\n this.bind_dom(this.element_rotation.fields.h.dom, 'change', 'input_cube_rotate_change', 'active');\n this.bind_dom(this.element_rotation.fields.h.dom, 'keyup', 'input_cube_rotate_change', 'active');\n \/\/ y\n this.bind_dom(this.element_rotation.fields.p.dom, 'change', 'input_cube_rotate_change', 'active');\n this.bind_dom(this.element_rotation.fields.p.dom, 'keyup', 'input_cube_rotate_change', 'active');\n \/\/ z\n this.bind_dom(this.element_rotation.fields.b.dom, 'change', 'input_cube_rotate_change', 'active');\n this.bind_dom(this.element_rotation.fields.b.dom, 'keyup', 'input_cube_rotate_change', 'active');\n },\n\n refresh_properties_cube: function (binder) {\n this._refresh_property_coords(binder);\n this._refresh_property_sizes(binder);\n this._refresh_property_rotations(binder);\n },\n\n refresh_properties_clip: function (binder) {\n this._refresh_property_coords(binder);\n this._refresh_property_sizes(binder);\n\n \/\/ BACKGROUND\n \/\/ label\n var background = this.w.welements.css_rgb_to_hex(binder.style_get('background-color')).toUpperCase(),\n color = this.w.welements.css_rgb_to_hex(binder.style_get('color')),\n dom;\n\n \/\/ label\n dom = this.w.document.createElement('label');\n dom.classList.add('label-sprite');\n dom.setAttribute('for', 'input-background');\n dom.appendChild(this.w.document.createTextNode('background\\u00A0:'));\n this.dom_html.appendChild(dom);\n \/\/ input\n dom = this.w.document.createElement('input');\n dom.setAttribute('id', 'we-input-background');\n dom.setAttribute('type', 'color');\n dom.value = background;\n this.dom_html.appendChild(dom);\n this.bind_dom(dom, 'change', 'background.change', 'active');\n\n \/\/ COLOR\n \/\/ br\n this.dom_html.appendChild(this.w.document.createElement('br'));\n \/\/ label\n dom = this.w.document.createElement('label');\n dom.classList.add('label-sprite');\n dom.setAttribute('for', 'input-color');\n dom.appendChild(this.w.document.createTextNode('color\\u00A0:'));\n this.dom_html.appendChild(dom);\n \/\/ input\n dom = this.w.document.createElement('input');\n dom.setAttribute('id', 'we-input-background');\n dom.setAttribute('type', 'color');\n dom.value = color;\n this.dom_html.appendChild(dom);\n this.bind_dom(dom, 'change', 'color.change', 'active');\n\n \/\/ HTML\n \/\/ br\n this.dom_html.appendChild(this.w.document.createElement('br'));\n \/\/ label\n dom = this.w.document.createElement('label');\n dom.classList.add('label-sprite');\n dom.setAttribute('for', 'input-html');\n dom.appendChild(this.w.document.createTextNode('html\\u00A0:'));\n this.dom_html.appendChild(dom);\n \/\/ br\n this.dom_html.appendChild(this.w.document.createElement('br'));\n \/\/ textarea\n dom = this.w.document.createElement('textarea');\n dom.setAttribute('id', 'we-input-html');\n dom.value = (this.element_target.dom_html !== null) ? this.element_target.dom_html.innerHTML : '';\n this.dom_html.appendChild(dom);\n this.bind_dom(dom, 'keyup', 'html.keyup', 'active');\n this.bind_dom(dom, 'focus', 'html.focus', 'active');\n this.bind_dom(dom, 'blur', 'html.blur', 'active');\n },\n\n refresh_properties_image: function (binder) {\n this._refresh_property_coords(binder);\n this._refresh_property_sizes(binder);\n \/*var i, dom = this.w.document.createElement('label'), option;\n dom.appendChild(this.w.document.createTextNode('asset\\u00A0:'));\n dom.classList.add('label-sprite');\n dom.setAttribute('for', 'input-background');\n this.dom_html.appendChild(dom);\n\n dom = this.w.document.createElement('select');\n option = this.w.document.createElement('option');\n option.value = 'none';\n option.innerHTML = '- none -';\n dom.appendChild(option);\n for (i in this.w.window.wemplate_stage.page.assets) {\n if (this.w.window.wemplate_stage.page.assets.hasOwnProperty(i)) {\n option = this.w.document.createElement('option');\n option.value =\n option.innerHTML = this.w.window.wemplate_stage.page.assets[i];\n dom.appendChild(option);\n }\n }\n this.dom_html.appendChild(dom);*\/\n },\n\n input_cube_rotate_change: function () {\n var binder = this.w.window.wemplate_stage.state_variable_get('edit_waiting', 'binder_focused');\n if (binder) {\n var h = this.w.window.parseInt(this.element_rotation.fields.h.field.value),\n p = this.w.window.parseInt(this.element_rotation.fields.p.field.value),\n b = this.w.window.parseInt(this.element_rotation.fields.b.field.value);\n\n h = h || 0;\n p = p || 0;\n b = b || 0;\n\n binder.rotate_euler(h, p, b);\n this.w.window.wemplate_stage.page.render();\n }\n },\n\n states: {\n edit_waiting: {\n init: function () {\n this.bind(this.w.window.wemplate_stage, 'binder_focus', 'edit_waiting');\n this.bind(this.w.window.wemplate_stage, 'binder_blur', 'edit_waiting');\n },\n exit: function () {\n this.unbind(this.w.window.wemplate_stage, 'binder_focus', 'edit_waiting');\n this.unbind(this.w.window.wemplate_stage, 'binder_blur', 'edit_waiting');\n if (this.state_is_active('active')) {\n this.state_quit('active');\n }\n },\n binder_focus: function (binder) {\n if (binder !== null && binder !== undefined) {\n this.state_start('active');\n }\n },\n binder_blur: function () {\n this.state_quit('active');\n }\n },\n active: {\n init: function () {\n var binder = this.w.window.wemplate_stage.state_variable_get('edit_waiting', 'binder_focused');\n this.refresh_properties(binder);\n },\n exit: function () {\n this.refresh_properties();\n },\n background: {\n change: function (e) {\n this.element_target.style_set('background-color', e.target.value);\n }\n },\n color: {\n change: function (e) {\n this.element_target.style_set('color', e.target.value);\n }\n },\n html: {\n keyup: function (e) {\n this.element_target.dom_fill('html', e.target.value);\n this.element_target.render();\n },\n focus: function () {\n this.w.window.wemplate_stage.state_quit('keyboard_control');\n },\n blur: function () {\n this.w.window.wemplate_stage.state_start('keyboard_control');\n }\n },\n input_cube_rotate_change: function () {\n this.input_cube_rotate_change();\n },\n input_position_x_change: function (e) {\n var binder = this.w.window.wemplate_stage.state_variable_get('edit_waiting', 'binder_focused');\n binder.left = this.w.window.parseInt(e.target.value);\n binder.render();\n },\n input_position_y_change: function (e) {\n var binder = this.w.window.wemplate_stage.state_variable_get('edit_waiting', 'binder_focused');\n binder.top = this.w.window.parseInt(e.target.value);\n binder.render();\n },\n input_position_z_change: function (e) {\n var binder = this.w.window.wemplate_stage.state_variable_get('edit_waiting', 'binder_focused');\n binder.z = this.w.window.parseInt(e.target.value);\n binder.render();\n },\n input_width_change: function (e) {\n var binder = this.w.window.wemplate_stage.state_variable_get('edit_waiting', 'binder_focused');\n binder.width = this.w.window.parseInt(e.target.value);\n binder.render();\n },\n input_height_change: function (e) {\n var binder = this.w.window.wemplate_stage.state_variable_get('edit_waiting', 'binder_focused');\n binder.height = this.w.window.parseInt(e.target.value);\n binder.render();\n },\n input_depth_change: function (e) {\n var binder = this.w.window.wemplate_stage.state_variable_get('edit_waiting', 'binder_focused');\n binder.depth = this.w.window.parseInt(e.target.value);\n binder.render();\n }\n }\n }\n });\n \/\/ [-->\n}(wjs));\n}"},"wemplate_box_save":{"element":true,"binder":{"path_client":"collection\/element\/wemplate_box_save\/","css":false},"javascript":"function(){(function (wjs) {\n 'use strict';\n \/\/ <--]\n wjs.loader('element').construct('wemplate_box_save', {\n base: 'welements\\\\wemplate_box',\n options_default: {\n title: 'Output',\n height: 40\n },\n\n init: function (options) {\n this.w.call_base(this, 'init', arguments);\n this.button_add('save', 'Save');\n this.button_add('join', 'Join us');\n this.dom.appendChild(this.w.document.createElement('br'));\n \/\/ States connexion\n this.bind(this.w.window.wemplate_stage, 'state_start', 'global');\n this.bind(this.w.window.wemplate_stage, 'state_quit', 'global');\n \/\/ Start edit waiting if stage state is started\n if (this.w.window.wemplate_stage.state_is_active('edit_waiting')) {\n this.state_start('edit_waiting');\n }\n },\n\n exit: function () {\n this.unbind(this.w.window.wemplate_stage, 'state_start', 'global');\n this.unbind(this.w.window.wemplate_stage, 'state_quit', 'global');\n this.w.call_base(this, 'exit', arguments);\n },\n\n button_click_save: function () {\n this.w.window.wemplate_stage.popup_open('product_save');\n },\n\n button_click_join: function () {\n this.w.window.open('http:\/\/market.wexample.com', '_blank');\n },\n\n states: {\n global: {\n state_start: function (binder, state_name) {\n if (state_name === 'edit_waiting') {\n this.state_start('edit_waiting');\n }\n },\n state_quit: function (binder, state_name) {\n if (state_name === 'edit_waiting') {\n this.state_quit('edit_waiting');\n }\n },\n binder_exit: function () {\n this.exit();\n }\n },\n edit_waiting: {\n init: function () {\n this.button_toggle_all(true);\n },\n exit: function () {\n this.button_toggle_all(false);\n }\n }\n }\n });\n \/\/ [-->\n}(wjs));\n}"},"wemplate_stage":{"element":true,"#require":{"element":["stage","wemplate_page","clip","grid","wemplate_area","wemplate_area_top","wemplate_area_left","wemplate_area_right","wemplate_area_timeline","wemplate_explorer_element","wemplate_box","wemplate_box_load","wemplate_box_assets","wemplate_box_explore","wemplate_box_plugins","wemplate_explorer_assets","wemplate_explorer_plugins","wemplate_box_properties","wemplate_box_save"],"plugin":["wemplate_edit","inflate","fullscreen"]},"binder":{"path_client":"collection\/element\/wemplate_stage\/","css":"body { -webkit-touch-callout:none; -webkit-user-select:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; margin:0 }\n.wemplate_stage { background:black url('wemplate.jpg') no-repeat center; color:#333; cursor:url(\"cursor.cur\"), pointer; font-family:Trebuchet MS, sans-serif; }\n.wemplate_frame_editor { position:absolute; top:0; left:0 }\n.wemplate_frame_editor .wemplate_edit-corner { position:fixed; border:solid; }\n.wemplate_frame_editor .wemplate_edit-corner-tl { border-width:1px 0 0 1px }\n.wemplate_frame_editor .wemplate_edit-corner-tr { border-width:1px 1px 0 0 }\n.wemplate_frame_editor .wemplate_edit-corner-br { border-width:0 1px 1px 0 }\n.wemplate_frame_editor .wemplate_edit-corner-bl { border-width:0 0 1px 1px }\n.wemplate_frame_editor .wemplate_edit-corner-mode_select { border-color:#EEE }\n.wemplate_frame_editor .wemplate_edit-corner-mode_select_plugin { border-color:#80b2ff; border-style:dotted }\n.wemplate_frame_editor .wemplate_edit-corner-mode_select_parent { border-color:black; opacity:.2 }\n.wemplate_frame_editor .wemplate_edit-corner-mode_append { border-color:orange }\n\n.tool_panel { position:absolute; background:#222; border:1px solid #333; color:#666; font-size:12px; width:250px; top:38px; left:343px; }\n.tool_panel a { text-decoration:none; color:#666; }\n.tool_panel a:hover { color:#888; }\n\n\n\n"},"javascript":"function(){\/**\n * @require element > stage\n * @require element > wemplate_page\n * @require element > clip\n * @require element > grid\n * @require element > wemplate_area\n * @require element > wemplate_area_top\n * @require element > wemplate_area_left\n * @require element > wemplate_area_right\n * @require element > wemplate_area_timeline\n * @require element > wemplate_explorer_element\n * @require element > wemplate_box\n * @require element > wemplate_box_load\n * @require element > wemplate_box_assets\n * @require element > wemplate_box_explore\n * @require element > wemplate_box_plugins\n * @require element > wemplate_explorer_assets\n * @require element > wemplate_explorer_plugins\n * @require element > wemplate_box_properties\n * @require element > wemplate_box_save\n * @require plugin > wemplate_edit\n * @require plugin > inflate\n * @require plugin > fullscreen\n *\/\n(function (wjs) {\n 'use strict';\n \/\/ <--]\n wjs.loader('element').construct('wemplate_stage', {\n base: 'welements\\\\stage',\n options_default: {\n plugins: [\n {\n name: 'fullscreen'\n }\n ]\n },\n properties: {\n editors: null,\n page: null,\n dev: false,\n area_top: null,\n area_left: null,\n area_right: null,\n area_timeline: null,\n tooltip_element: null,\n colors_extract: [\n '444333', '334437', '334444', '333344', '333344', '443342', \/\/ Dull\n '522525', '525025', '255231', '255152', '252652', '52254B', \/\/ Average\n 'B75E5E', 'B7B35E', '5EB776', '5EB5B7', '5E60B7', 'B75EA9' \/\/ Intense\n ],\n user: {\n premium: false\n },\n save_formats: {\n online: {\n title: 'Online',\n description: 'Only for premium users, save your scene on this website.',\n access: 'premium'\n },\n wex: {\n title: 'Wex',\n description: 'Internal format for wemplate, use it for your personal storage and to reload the scene into wemplate.'\n },\n html: {\n title: 'HTML',\n description: 'HTML format only, use it to integrate your scene in your custom site or templates. Wex file is included.'\n },\n drupal_6x: {\n title: 'Drupal 6-x',\n description: 'Embedded into a Drupal 6.x module, your scene will be available as a Drupal block. Wex file is included.'\n },\n drupal_7x: {\n title: 'Drupal 7-x',\n description: 'Embedded into a Drupal 7.x module, your scene will be available as a Drupal block. Wex file is included.'\n },\n drupal_8x: {\n title: 'Drupal 8-x',\n description: 'Embedded into a Drupal 8.x module, your scene will be available as a Drupal block. Wex file is included.'\n }\n },\n regexArrayBracket: new RegExp('(.+[^\\\\]])\\\\[(.+)\\\\]$'),\n queryCachedSearch: null,\n queryCachedHash: null,\n paramFromQuery: null,\n paramFromHash: null,\n _queryParam: null\n },\n\n __construct: function (options) {\n this.w.call_base(this, '__construct', arguments);\n \/\/ Build param array.\n this.queryParamRefresh();\n \/\/ Set some action at the very end.\n var changelog = this.w.window.wemplate.transcoded_variable('client', 'last_changes'),\n product_default = this.getParam('p');\n this.user.premium = this.getParam('premium') === '1';\n \/\/ Wemplate is playing.\n this.play();\n \/\/ Open product or load new page.\n if (typeof product_default === 'string') {\n this.load(product_default);\n }\n else {\n this.page_init();\n }\n if (changelog !== false) {\n this.tooltip(this.w.window.wemplate.transcoded_variable('client', 'last_changes'));\n }\n },\n\n init: function (options) {\n \/\/ Launch bootstrap.\n this.state_start('wemplate_bootstrap');\n this.w.call_base(this, 'init', arguments);\n \/\/ Save as global object.\n this.w.window.wemplate_stage = this;\n this.w.document.body.appendChild(this.dom);\n \/\/ Left area.\n this.area_top = this.element_add('wemplate_area_top');\n this.area_left = this.element_add('wemplate_area_left');\n this.area_right = this.element_add('wemplate_area_right');\n this.area_timeline = this.element_add('wemplate_area_timeline');\n this.area_panels = this.element_add('wemplate_area_panels');\n \/\/ Quit bootstrap.\n this.state_quit('wemplate_bootstrap');\n },\n\n page_init: function () {\n this.page_exit();\n if (this.state_is_active('edit_waiting')) {\n this.state_quit('edit_waiting');\n }\n \/\/ Launch bootstrap.\n this.state_start('product_loading');\n \/\/ Create page.\n this.page = this.element_add('wemplate_page', {\n stage: this\n });\n \/\/ Add a overall place to store interface elements like element editors.\n this.editors = this.element_add();\n this.editors.dom.classList.add('wemplate_frame_editor');\n this.page.render();\n this.trigger('page_init', [this.page]);\n var panel = this.getParam('panel');\n if (this.area_panels.panel_exists(panel)) {\n this.area_panels.panel_open(panel);\n }\n \/\/ Launch bootstrap.\n this.state_quit('product_loading');\n this.state_start('edit_waiting');\n this.play();\n },\n\n page_exit: function () {\n var i;\n for (i in this.assets) {\n if (this.assets.hasOwnProperty(i)) {\n this.asset_remove(i);\n }\n }\n this.assets = [];\n this.stop();\n this.binder_blur();\n \/\/ Clear editors if exists.\n if (this.editors !== null) {\n this.editors.exit();\n }\n if (this.page !== null) {\n this.page.exit();\n }\n this.editors = null;\n this.page = null;\n this.trigger('page_exit');\n },\n\n url: function (name) {\n var url = this.w.window.wemplate.path('client', name);\n url += url.indexOf('?') === -1 ? '?' : '';\n \/\/ Append wjs extra arguments, it may be change in the future.\n var q = this.w.transcode.transcoded_variable('client', 'load_url_queries');\n return url + (q ? this.w.param(q) : '');\n },\n\n load: function (scene_serial) {\n this.page_init();\n \/\/ Use wjs XMLHttpRequest.\n this.w.xhr = new this.w.window.XMLHttpRequest();\n this.w.xhr.open(\"POST\", this.url('load'), false);\n this.w.xhr.onreadystatechange = function () {\n if (this.w.xhr.readyState === 4 && this.w.xhr.status === 200) {\n switch (this.w.xhr.responseText) {\n case 'ERROR_NOT_FOUND':\n this.tooltip('Product not found', 'error');\n break;\n default:\n this.setParam('p', scene_serial);\n this.load_map(JSON.parse(this.w.xhr.responseText));\n }\n }\n }.bind(this);\n this.w.xhr.setRequestHeader(\"Content-type\", \"application\/x-www-form-urlencoded\");\n this.w.xhr.send(this.w.param({\n scene: scene_serial\n }));\n },\n\n \/**\n * Load from an external file uploaded by user.\n *\/\n load_wex: function (json) {\n this.page_init();\n json.serial = undefined;\n var i;\n for (i in json.assets) {\n if (json.assets.hasOwnProperty(i)) {\n \/\/ We need to replace spaces by '+' for compatibility\n \/\/ Working base64 file in img src attribute need \"+\"\n \/\/ but on file loading they are not into assets code.\n \/\/ It may be due to php json encoding.\n this.asset_add('data', i, json.assets[i].replace(\/ \/g, '+'));\n }\n }\n json.assets = {};\n return this.load_map(json);\n },\n\n load_map: function (data) {\n if (data !== 'error' && data.hasOwnProperty('title') && data.hasOwnProperty('serial')) {\n var i;\n this.product_data = data;\n this.w.document.title = data.title + ' - wemplate.wexample.com';\n this.page.title = data.title;\n this.page.serial = data.serial;\n this.page.fps =\n this.area_timeline.field_fps.field.value =\n !isNaN(data.fps) ? data.fps : 30;\n this.assets_path = data.assets_path;\n \/\/ Load first assets to have them available at object creation.\n if (data.hasOwnProperty('assets')) {\n for (i in data.assets) {\n if (data.assets.hasOwnProperty(i)) {\n this.asset_add('file', data.assets[i], data.assets[i]);\n }\n }\n }\n \/\/ Product may be empty.\n if (data.hasOwnProperty('content')) {\n for (i in data.content) {\n if (data.content.hasOwnProperty(i)) {\n this.page.child_add(data.content[i].loader, data.content[i].type, data.content[i]);\n }\n }\n }\n this.trigger('product_loaded', data);\n }\n },\n\n image_base64: function (url, callback) {\n var canvas = this.w.document.createElement('canvas'),\n context = canvas.getContext('2d'),\n image = new this.w.window.Image();\n image.crossOrigin = 'Anonymous';\n image.onload = function () {\n canvas.height = this.height;\n canvas.width = this.width;\n context.drawImage(this, 0, 0);\n callback.apply(this, [url, canvas.toDataURL('image\/png')]);\n };\n image.src = url;\n },\n\n image_base64_multiple: function (urls, callback) {\n this._image_base64_multiple_urls = urls;\n this._image_base64_multiple_output = {};\n this._image_base64_multiple_callback = callback;\n this._image_base64_multiple();\n },\n\n _image_base64_multiple: function (last_name, last_value) {\n if (last_name !== undefined) {\n this._image_base64_multiple_output[last_name] = last_value;\n }\n if (this._image_base64_multiple_urls.length > 0) {\n this.image_base64(this._image_base64_multiple_urls.pop(), this._image_base64_multiple.bind(this), undefined);\n }\n else {\n var callback = this._image_base64_multiple_callback,\n output = this._image_base64_multiple_output;\n delete this._image_base64_multiple_urls;\n delete this._image_base64_multiple_output;\n delete this._image_base64_multiple_callback;\n if (callback !== undefined) {\n callback(output);\n }\n }\n },\n\n save: function (callback, format, assets_converted) {\n var i, data, assets, assets_files, data_send;\n \/\/ Format undefined or no access.\n if (!this.save_formats.hasOwnProperty(format) || (this.save_formats[format].hasOwnProperty('access') && !this.user_access(this.save_formats[format].access))) {\n return false;\n }\n \/\/ If no assets sent, we are in the first loop of save function,\n \/\/ so we need to check assets encoding.\n if (assets_converted === undefined) {\n assets_files = [];\n \/\/ Create a list of assets to convert to base64.\n for (i in this.assets) {\n if (this.assets.hasOwnProperty(i)) {\n if (this.assets[i].type === 'file') {\n assets_files.push(this.assets_path + this.assets[i].data);\n }\n }\n }\n \/\/ We need assets to be all converted to base64,\n \/\/ conversion is asynchronous.\n if (this.w.object_size(assets_files) > 0) {\n this.image_base64_multiple(assets_files, function (assets) {\n \/\/ assets should not return undefined content\n this.save(callback, format, assets);\n }.bind(this));\n return;\n }\n \/\/ There is no asset to convert,\n \/\/ we can continue.\n assets_converted = {};\n }\n \/\/ We load page data.\n data = this.page.save();\n \/\/ We continue only if data exists.\n if (data !== false) {\n assets = {};\n \/\/ List of converted assets return an object indexed with\n \/\/ absolute urls, we have to convert it.\n for (i in assets_converted) {\n if (assets_converted.hasOwnProperty(i)) {\n \/\/ Get replace linux backslashes by window slashes and split to get file name.\n assets[i.replace(new RegExp('`\\\\`', 'g'), '\/').split('\/').pop()] = assets_converted[i];\n }\n }\n \/\/ Get other \"data\" assets, they have been added\n \/\/ by user in this current session.\n for (i in this.assets) {\n if (this.assets.hasOwnProperty(i)) {\n if (this.assets[i].type === 'data') {\n assets[this.assets[i].name] = this.assets[i].data;\n }\n }\n }\n \/\/ Now all assets are encoded, we can push.\n data.assets = assets;\n data.version = this.w.window.wemplate.version;\n \/\/ Create send package.\n data_send = {\n scene: encodeURIComponent(JSON.stringify(data)),\n format: format\n };\n this.w.xhr = new this.w.window.XMLHttpRequest();\n this.w.xhr.open('POST', this.url('save'), false);\n this.w.xhr.setRequestHeader(\"Content-type\", \"application\/x-www-form-urlencoded\");\n this.w.xhr.onreadystatechange = function () {\n var returned;\n if (this.w.xhr.readyState === 4 && this.w.xhr.status === 200) {\n if (this.w.xhr.responseText.indexOf('SUCCESS:') === 0) {\n returned = this.w.xhr.responseText.substr(this.w.xhr.responseText.indexOf(':') + 1);\n if (format === 'online') {\n this.page.serial = returned;\n this.tooltip('Scene saved online...');\n }\n else {\n this.w.window.location.href = this.w.window.wemplate.path('client', 'temp') + '\/' + returned;\n }\n }\n callback(this.w.xhr.responseText);\n }\n }.bind(this);\n this.w.xhr.send(this.w.param(data_send));\n }\n },\n\n user_access: function (level) {\n \/\/ Really simple access management, if user is premium the it's ok.\n return level === 'premium' && this.w.window.wemplate_stage.user.premium === true;\n },\n\n binder_focus: function (binder) {\n \/\/ Deselect current.\n this.binder_blur();\n \/\/ Save as focused.\n this.state_variable_set('edit_waiting', 'binder_focused', binder);\n \/\/ Trigger event.\n this.trigger('binder_focus', [binder]);\n binder.trigger('binder_focus', [binder]);\n },\n\n binder_blur: function () {\n var binder = this.state_variable_get('edit_waiting', 'binder_focused');\n if (binder !== undefined) {\n this.state_variable_unset('edit_waiting', 'binder_focused');\n \/\/ Trigger event.\n this.trigger('binder_blur', [binder]);\n binder.trigger('binder_blur', [binder]);\n }\n },\n\n page_play: function () {\n this.state_replace('edit_waiting', 'wemplate_play');\n this.page.play();\n },\n\n page_stop: function () {\n this.page.stop();\n this.state_replace('wemplate_play', 'edit_waiting');\n this.page.render();\n },\n\n popup_open: function (type) {\n this.state_replace('edit_waiting', 'popup_open');\n this.popup = this.element_add('wemplate_popup\\\\' + type);\n },\n\n popup_close: function () {\n \/\/ Exit popup if not already made (by close button)\n if (!Object.isSealed(this.popup)) {\n this.popup.exit();\n }\n this.state_replace('popup_open', 'edit_waiting');\n },\n\n play_toggle: function () {\n if (this.page.play_started !== true) {\n this.page_play();\n }\n else {\n this.page_stop();\n }\n },\n\n tooltip: function (message, message_type) {\n if (this.tooltip_element !== null) {\n if (!Object.isSealed(this.tooltip_element)) {\n this.tooltip_element.exit();\n }\n delete this.tooltip_element;\n }\n this.tooltip_element = this.element_add('wemplate_tooltip', {\n message: message,\n message_type: message_type\n });\n },\n\n eventKeyCode: function (e) {\n \/\/ The property to obtain a keycode depends on browsers you are using.\n \/\/ The following statement allows you to obtain a keycode\n return e.keyCode || e.which;\n },\n\n getParam: function (paramName) {\n \/\/ Hash is always prior to query strings\n return this.queryParamGet()[paramName];\n },\n\n setParam: function (paramName, paramValue) {\n this.paramFromHash[paramName] = paramValue;\n this.w.window.location.hash = this.queryStringEncode(this.paramFromHash);\n },\n\n removeParam: function (paramName) {\n if (this.paramFromHash.hasOwnProperty(paramName)) {\n delete this.paramFromHash[paramName];\n }\n this.w.window.location.hash = this.queryStringEncode(this.paramFromHash);\n },\n\n queryParamGet: function () {\n this.queryParamRefresh();\n return this._queryParam;\n },\n\n queryParamSet: function (value) {\n this._queryParam = value;\n },\n\n queryParamRefresh: function () {\n \/\/ Check changes by comparing search and hash values.\n if (this.queryCachedSearch !== this.w.window.location.search || this.queryCachedHash !== this.w.window.location.hash) {\n this._queryParam = this.queryParamGetFromLocation();\n \/\/ Save status of query to prevent useless reloads.\n this.queryCachedSearch = this.w.window.location.search;\n this.queryCachedHash = this.w.window.location.hash;\n }\n },\n\n queryParamGetFromLocation: function () {\n this.paramFromQuery = this.queryStringsDecode(this.w.window.location.search.substring(1));\n this.paramFromHash = this.queryStringsDecode(this.w.window.location.hash.substring(1));\n var output = this.queryObjectExtend({}, this.paramFromQuery);\n output = this.queryObjectExtend(output, this.paramFromHash);\n return output;\n },\n\n queryObjectExtend: function (output, add) {\n var i;\n \/\/ Copy data from query to output.\n for (i in add) {\n if (add.hasOwnProperty(i)) {\n output[i] = add[i];\n }\n }\n return output;\n },\n\n queryStringEncode: function (json) {\n var output = [], i;\n for (i in json) {\n if (json.hasOwnProperty(i)) {\n \/\/ A parameter may not have a value,\n \/\/ especially into hash part, it\n \/\/ avoid also null objects.\n if (json[i] === undefined || json[i] === null) {\n output.push(i);\n }\n else if (typeof json[i] === 'object') {\n output.push(this.queryStringEncodeObject(i, json[i]));\n }\n \/\/ Parameter is a key \/ value pair.\n else {\n output.push(i + '=' + encodeURIComponent(json[i]));\n }\n }\n }\n return output.join('&');\n },\n\n queryStringEncodeObject: function (paramName, paramObject) {\n var output = [], i;\n for (i in paramObject) {\n if (paramObject.hasOwnProperty(i)) {\n if (typeof paramObject[i] === 'object') {\n output.push(this.queryStringEncodeObject(paramName + '[' + i + ']', paramObject[i]));\n }\n else {\n output.push(paramName + '[' + i + ']=' + encodeURIComponent(paramObject[i]));\n }\n }\n }\n return output.join('&');\n },\n\n queryStringsDecode: function (query) {\n query = query.split('&');\n var output = [], i, length = query.length, item;\n for (i = 0; i < length; i++) {\n item = query[i].split(\"=\");\n \/\/ Avoid empty keys.\n if (item[0]) {\n \/\/ Get brackets.\n if (this.regexArrayBracket.exec(item[0])) {\n this.queryStringsDecodeObject(item[0], item[1], output);\n }\n else {\n output[item[0]] = decodeURIComponent(item[1]);\n }\n }\n }\n\n return output;\n },\n\n queryStringsDecodeObject: function (key, value, output) {\n var i,\n base,\n result = this.regexArrayBracket.exec(key),\n brackets = result[2].split(']['),\n length = brackets.length,\n name = result[1];\n \/\/ Create output array if not exists.\n output[name] = (output[name] === undefined) ? {} : output[name];\n \/\/ Iterate over brackets to create final multidimensional array.\n base = output[name];\n for (i = 0; i < length; i++) {\n if (i === length - 1) {\n base[brackets[i]] = decodeURIComponent(value);\n }\n else {\n base[brackets[i]] = (base[brackets[i]] === undefined) ? {} : base[brackets[i]];\n }\n base = base[brackets[i]];\n }\n },\n\n states: {\n edit_waiting: {\n init: function () {\n this.state_start('keyboard_control');\n var binder = this.state_variable_get('edit_waiting', 'binder_focused_previous');\n if (binder !== undefined) {\n this.binder_focus(binder);\n }\n },\n exit: function () {\n this.state_variable_set('edit_waiting', 'binder_focused_previous', this.state_variable_get('edit_waiting', 'binder_focused'));\n this.binder_blur();\n this.state_quit('keyboard_control');\n }\n },\n \/\/ We use e separated state to allow to disable keyboard control\n \/\/ but we keep start and stop in the same time of edit_waiting.\n \/\/ It could be replaced by a more fine method based on the focus\n \/\/ of stage element (ex, space bar enabled when page is focused, etc...)\n keyboard_control: {\n init: function () {\n this.bind_dom(window, 'keyup', 'win.keyup', 'keyboard_control');\n this.bind_dom(window, 'keydown', 'win.keydown', 'keyboard_control');\n },\n exit: function () {\n this.unbind_dom(window, 'keyup', 'win.keyup', 'keyboard_control');\n this.unbind_dom(window, 'keydown', 'win.keydown', 'keyboard_control');\n },\n win: {\n keyup: function (e) {\n switch (this.eventKeyCode(e)) {\n \/\/ Space bar\n case 32 :\n \/\/ Stop is managed into play state.\n this.page_play();\n break;\n \/\/ On press delete\n case 46 :\n if (this.state_variable_get('edit_waiting', 'binder_focused') !== undefined && this.state_variable_get('edit_waiting', 'binder_focused') !== null) {\n var binder = this.state_variable_get('edit_waiting', 'binder_focused');\n if (binder.is_a('plugin')) {\n if (binder.type === 'wemplate_edit') {\n return;\n }\n binder.binder.plugout(binder);\n \/\/ Set focus to parent.\n this.binder_focus(binder.binder);\n binder.binder.render();\n }\n else if (binder.is_a('sprite')) {\n this.binder_blur();\n binder.exit();\n }\n }\n break;\n }\n },\n keydown: function (e) {\n switch (this.eventKeyCode(e)) {\n \/\/ o => open\n case 79 :\n if (e.ctrlKey) {\n e.preventDefault();\n e.stopImmediatePropagation();\n this.popup_open('product_open');\n }\n break;\n \/\/ n => new\n case 78 :\n if (e.ctrlKey) {\n e.preventDefault();\n e.stopImmediatePropagation();\n this.w.window.wemplate_stage.page_init();\n return false;\n }\n break;\n \/\/ s\n case 83 :\n \/\/ + ctrl\n if (e.ctrlKey) {\n e.preventDefault();\n e.stopImmediatePropagation();\n this.popup_open('product_save');\n }\n break;\n }\n }\n }\n },\n wemplate_play: {\n init: function () {\n this.bind_dom(this.w.window, 'keyup', 'win.keyup', 'wemplate_play');\n },\n exit: function () {\n this.unbind_dom(this.w.window, 'keyup', 'win.keyup', 'wemplate_play');\n },\n win: {\n keyup: function (e) {\n switch (this.eventKeyCode(e)) {\n \/\/ Space bar\n case 32 :\n \/\/ Play is managed into default state.\n this.page_stop();\n break;\n }\n }\n }\n }\n }\n });\n \/\/ [-->\n}(wjs));\n}"}},"plugin":{"wemplate_edit":{"plugin":true,"binder":{"path_client":"collection\/plugin\/wemplate_edit\/","css":false},"javascript":"function(){(function (wjs) {\n 'use strict';\n \/\/ <--]\n wjs.loader('plugin').construct('wemplate_edit', {\n properties: {\n corners_scale_max: 10,\n corners_width: 1,\n center_image_offset: 6,\n editors_mode: null,\n page_mousedown_active: false\n },\n\n init: function (options) {\n this.w.call_base(this, 'init', arguments);\n this.bind(this.w.window.wemplate_stage, 'stage.state_start', 'global');\n this.bind(this.w.window.wemplate_stage, 'stage.state_quit', 'global');\n \/\/ We listen in all states to replace plugin position.\n this.bind(this.binder, 'plugin', 'global');\n this.bind(this.binder, 'plugout', 'global');\n \/\/ dev\n if (this.w.window.wemplate_stage.dev === true) {\n this.dom_dev = this.w.document.createElement('div');\n this.binder.dom.appendChild(this.dom_dev);\n this.dom_dev.innerHTML = '...';\n this.dom_dev.setAttribute('style', 'opacity:.9; background:#333; position:absolute; top:5px; right:-110px; width:100px; padding:5px; box-shadow:0px 1px 6px rgba(255,255,255,0.3)');\n }\n \/\/ Add on children\n if (this.binder.children.length > 0) {\n var i;\n for (i = 0; i < this.binder.children.length; i += 1) {\n this.binder.children[i].plugin('wemplate_edit');\n }\n }\n },\n\n exit: function () {\n this.unbind(this.w.window.wemplate_stage, 'stage.state_start', 'global');\n this.unbind(this.w.window.wemplate_stage, 'stage.state_quit', 'global');\n this.unbind(this.binder, 'plugin', 'global');\n this.unbind(this.binder, 'plugout', 'global');\n \/\/ Sometime we can exit items during play process\n \/\/ so edit_waiting state will be disabled.\n if (this.state_is_active('edit_waiting')) {\n this.state_quit('edit_waiting');\n }\n this.w.call_base(this, 'exit', arguments);\n },\n\n save: function () {\n var output, children = [], child, plugins = [], i;\n \/\/ Get options data.\n output = this.save_binder_options(this.binder);\n \/\/ Get plugins options.\n for (i in this.binder.plugins_list) {\n \/\/ Exclude wemplate_* plugins.\n if (this.binder.plugins_list.hasOwnProperty(i) && this.binder.plugins_list[i].type.indexOf('wemplate_') === -1) {\n plugins.push(this.save_binder_options(this.binder.plugins_list[i]));\n }\n }\n output.plugins = plugins;\n \/\/ Get children data.\n for (child in this.binder.children) {\n if (this.binder.children.hasOwnProperty(child)) {\n children.push(this.binder.children[child].plugin_get('wemplate_edit').save());\n }\n }\n \/\/ Append children only if exists.\n if (children.length !== 0) {\n output.children = children;\n }\n return output;\n },\n\n save_binder_options: function (binder) {\n var output, i;\n output = {\n type: binder.type\n };\n \/\/ Wemplate stage can't be saved, return only children data.\n if (binder.is_a('wemplate_stage')) {\n \/\/ Wemplate stage will be a normal stage in production.\n output.type = 'stage';\n return output;\n }\n \/\/ Get properties\n for (i in binder.options) {\n if (binder.options.hasOwnProperty(i)) {\n \/\/ undefined says to not save this data.\n if (binder.options[i].dump !== undefined) {\n \/\/ Value is true, so we try to get value of binder[i]\n if (binder.options[i].dump === true && binder.hasOwnProperty(i)) {\n output[i] = binder[i];\n }\n \/\/ Value is returned by a function.\n else if (typeof binder.options[i].dump === 'function') {\n output[i] = binder.options[i].dump(binder, binder.options[i].value);\n }\n \/\/ Value is a static value\n else if (binder.options[i].dump !== undefined) {\n output[i] = binder.options[i].dump;\n }\n \/\/ No undefined allowed.\n else {\n this.error('Missing dump function for variable ' + i);\n }\n }\n }\n }\n return output;\n },\n\n \/**\n * Display editors of specified mode (color).\n *\/\n editors_display: function (editors_mode) {\n var i, corners;\n \/\/ Hide previous corners.\n if (this.editors_mode !== null) {\n this.editors_hide();\n }\n this.dom_related = [];\n \/\/ Set as current mode.\n this.editors_mode = editors_mode;\n \/\/ List of corners\n corners = ['tl', 'tr', 'br', 'bl'];\n this.corners = {};\n \/\/ Create objects.\n for (i in corners) {\n if (corners.hasOwnProperty(i)) {\n \/\/ Create dom object.\n this.corners[corners[i]] = this.w.document.createElement('div');\n this.corners[corners[i]].classList.add('wemplate_edit-corner');\n this.corners[corners[i]].classList.add('wemplate_edit-corner-mode_' + this.editors_mode);\n this.corners[corners[i]].classList.add('wemplate_edit-corner-' + corners[i]);\n \/\/ Append to body (not into element).\n this.w.window.wemplate_stage.editors.dom.appendChild(this.corners[corners[i]]);\n \/\/ Save dom to the list of all dom object associated with binder dom\n \/\/ concerned by mouseup, mousedown and other listeners.\n this.dom_related.push(this.corners[corners[i]]);\n }\n }\n \/\/ Center point.\n this.center = this.w.document.createElement('img');\n this.center.style.position = 'fixed';\n this.center.setAttribute('src', this.w.window.wemplate_stage.path_client + 'clip_focused-center.gif');\n this.w.window.wemplate_stage.editors.dom.appendChild(this.center);\n \/\/ Add to dom list.\n this.dom_related.push(this.center);\n \/\/ Refresh display, scene is not playing, so we render current state.\n this.binder.render();\n },\n\n editors_bind: function (event_dom, event_name, state_name, toggle) {\n var i;\n toggle += '_dom';\n for (i in this.dom_related) {\n if (this.dom_related.hasOwnProperty(i)) {\n this[toggle](this.dom_related[i], event_dom, event_name, state_name);\n }\n }\n },\n\n \/**\n * Remove displayed editors.\n *\/\n editors_hide: function () {\n var i;\n \/\/ Remove all corners objects.\n for (i in this.dom_related) {\n if (this.dom_related.hasOwnProperty(i)) {\n this.dom_related[i].parentNode.removeChild(this.dom_related[i]);\n }\n }\n this.editors_mode = null;\n },\n\n render: function () {\n if (this.w.window.wemplate_stage.state_variable_get('edit_waiting', 'binder_focused') === this.binder && !this.binder.is_a('container')) {\n if (this.binder.render_data.hasOwnProperty('left')) {\n this.w.window.wemplate_stage.area_right.box_properties.element_coords.fields.x.field.value = this.binder.render_data.left;\n this.w.window.wemplate_stage.area_right.box_properties.element_coords.fields.y.field.value = this.binder.render_data.top;\n this.w.window.wemplate_stage.area_right.box_properties.element_sizes.fields.size_x.field.value = this.binder.render_data.width;\n this.w.window.wemplate_stage.area_right.box_properties.element_sizes.fields.size_y.field.value = this.binder.render_data.height;\n }\n else {\n this.w.window.wemplate_stage.area_right.box_properties.element_coords.fields.x.field.value = this.binder.left;\n this.w.window.wemplate_stage.area_right.box_properties.element_coords.fields.y.field.value = this.binder.top;\n this.w.window.wemplate_stage.area_right.box_properties.element_sizes.fields.size_x.field.value = this.binder.width;\n this.w.window.wemplate_stage.area_right.box_properties.element_sizes.fields.size_y.field.value = this.binder.height;\n }\n }\n },\n\n render_postprocess: function () {\n\n \/\/ Dev\n if (this.w.window.wemplate_stage.dev === true) {\n this.dom_dev.style.fontSize = '10px';\n this.dom_dev.innerHTML = this.binder.states_current.join('
') + '
' +\n this.states_current.join('
') + '
' +\n 'id : ' + this.binder.id + '
' +\n 'name : ' + this.binder.parent.name + '
' +\n 'parent : ' + this.binder.parent.id + '
' +\n 'index : ' + this.binder.tree_index();\n }\n\n if (this.editors_mode === null) {\n return;\n }\n\n var render_data_adjusted = this.binder.dom.getBoundingClientRect(),\n corners_scale = (render_data_adjusted.width > (this.corners_scale_max + this.corners_width) * 2) ? this.corners_scale_max : (render_data_adjusted.width \/ 2) - (this.corners_width * 2);\n corners_scale = (render_data_adjusted.height > (corners_scale + this.corners_width) * 2) ? corners_scale : (render_data_adjusted.height \/ 2) - (this.corners_width * 2);\n\n \/\/ Corners.\n this.corners.tl.style.width =\n this.corners.tl.style.height =\n this.corners.tr.style.width =\n this.corners.tr.style.height =\n this.corners.br.style.width =\n this.corners.br.style.height =\n this.corners.bl.style.width =\n this.corners.bl.style.height = corners_scale + 'px';\n\n this.corners.tl.style.top = this.corners.tr.style.top = render_data_adjusted.top + 'px';\n this.corners.bl.style.top = this.corners.br.style.top = render_data_adjusted.top + render_data_adjusted.height - corners_scale - this.corners_width + 'px';\n this.corners.tl.style.left = this.corners.bl.style.left = render_data_adjusted.left + 'px';\n this.corners.tr.style.left = this.corners.br.style.left = render_data_adjusted.left + render_data_adjusted.width - corners_scale - this.corners_width + 'px';\n \/\/ Centers\n this.center.style.top = (render_data_adjusted.top + (render_data_adjusted.height \/ 2) - this.center_image_offset) + 'px';\n this.center.style.left = (render_data_adjusted.left + (render_data_adjusted.width \/ 2) - this.center_image_offset) + 'px';\n },\n\n dom_clickable: function (dom) {\n \/\/ Check if dom is main object, or children of dom_html.\n return dom !== this.binder.dom && (this.binder.dom_html === null || !this.binder.dom_html.contains(dom));\n },\n\n states: {\n global: {\n \/\/ Keep plugin at end.\n plugin: function () {\n this.w.array_move(this.binder.plugins_list, this.binder.plugins_list.indexOf(this), this.binder.plugins_list.length);\n if (this.w.window.wemplate_stage.page.play_started === false) {\n this.binder.render();\n }\n },\n plugout: function () {\n this.w.array_move(this.binder.plugins_list, this.binder.plugins_list.indexOf(this), this.binder.plugins_list.length);\n if (this.w.window.wemplate_stage.page.play_started === false) {\n this.binder.render();\n }\n },\n stage: {\n state_start: function (binder, state_name) {\n if (state_name === 'edit_waiting') {\n if (!this.state_is_active('edit_waiting')) {\n this.state_start('edit_waiting');\n }\n }\n else if (state_name === 'edit_sprite_resize' && this.w.window.wemplate_stage.resizing !== this.binder) {\n this.state_quit('edit_waiting');\n }\n \/\/ User is dragging a binder\n else if (state_name === 'edit_binder_drag') {\n \/\/ But not this one.\n if (!this.state_is_active('edit_drag')) {\n this.state_replace('edit_waiting', 'edit_freezed');\n }\n }\n },\n state_quit: function (binder, state_name) {\n if (state_name === 'edit_waiting') {\n if (this.state_is_active('edit_waiting')) {\n this.state_quit('edit_waiting');\n }\n if (this.state_is_active('edit_waiting_focused')) {\n this.state_quit('edit_waiting_focused');\n }\n }\n else if (state_name === 'edit_sprite_resize' && this.w.window.wemplate_stage.resizing !== this.binder) {\n this.state_start('edit_waiting');\n }\n \/\/ User has dragged a binder.\n else if (state_name === 'edit_binder_drag') {\n \/\/ But not this one.\n if (!this.state_is_active('edit_drag')) {\n this.state_replace('edit_freezed', 'edit_waiting');\n }\n }\n }\n }\n },\n edit_waiting: {\n init: function () {\n \/\/ Listen for a global focus command,\n \/\/ it allows to handle focus on plugins.\n this.bind(this.w.window.wemplate_stage, 'binder_focus', 'edit_waiting');\n \/\/ Or for a mouseup on the binder.\n this.bind_dom(this.binder.dom, 'mouseup', 'dom.mouseup', 'edit_waiting');\n \/\/ Check if a binder is already focused\n var binder = this.w.window.wemplate_stage.state_variable_get('edit_waiting', 'binder_focused');\n if (binder) {\n this.states.edit_waiting.binder_focus(binder);\n }\n },\n exit: function () {\n this.unbind(this.w.window.wemplate_stage, 'binder_focus', 'edit_waiting');\n this.unbind_dom(this.binder.dom, 'mouseup', 'dom.mouseup', 'edit_waiting');\n },\n binder_focus: function (binder) {\n if (binder === this.binder) {\n this.state_replace('edit_waiting', 'edit_waiting_focused');\n }\n else if (this.binder.plugins_list.indexOf(binder) !== -1 && binder.is_a('plugin')) {\n \/\/ We manage plugin focus.\n this.state_start('edit_waiting_plugin_focused');\n }\n },\n dom: {\n mouseup: function (e) {\n \/\/ Target is not dom or child of dom.\n if (this.dom_clickable(e.target)) {\n return;\n }\n if (this.binder !== this.w.window.wemplate_stage.page) {\n this.w.window.wemplate_stage.binder_focus(this.binder);\n }\n else {\n this.w.window.wemplate_stage.binder_blur();\n }\n }\n }\n },\n \/\/ User is dragging another sprite.\n edit_freezed: {\n\n },\n \/\/ Global function when a binder (parent or plugin) is selected.\n edit_binder_focused: {\n init: function () {\n this.bind_dom(this.w.window.wemplate_stage.page.dom, 'mousedown', 'dom.page_mousedown', 'edit_binder_focused');\n },\n exit: function () {\n this.unbind_dom(this.w.window.wemplate_stage.page.dom, 'mousedown', 'dom.page_mousedown', 'edit_binder_focused');\n },\n page_mousedown: function (e) {\n \/\/ Save page as pressed on page,\n \/\/ this allow to deselect item on mouseup.\n this.page_mousedown_active = true;\n \/\/ On mouseup we will deselect all.\n this.bind_dom(window, 'mouseup', 'dom.window_mouseup', 'edit_binder_focused');\n },\n window_mouseup: function (e) {\n \/\/ Remove listener\n this.unbind_dom(window, 'mouseup', 'dom.window_mouseup', 'edit_binder_focused');\n \/\/ On click on stage when focused on an binder deselect it.\n \/\/ Mouse muse have been previously pressed on page object.\n if (e.target === this.w.window.wemplate_stage.page.dom_html && this.page_mousedown_active) {\n this.w.window.wemplate_stage.binder_blur();\n }\n this.page_mousedown_active = false;\n }\n },\n \/\/ Binder have focus.\n edit_waiting_focused: {\n init: function () {\n \/\/ Display selection corners.\n this.editors_display('select');\n this.editors_bind('mousedown', 'dom.binder_mousedown', 'edit_waiting_focused', 'bind');\n \/\/ Allow resizing.\n this.binder.plugin('wemplate_resize');\n \/\/ Add listener on mouse down.\n this.bind_dom(this.binder.dom, 'mousedown', 'dom.binder_mousedown', 'edit_waiting_focused');\n \/\/ Wait for deselection.\n this.bind(this.w.window.wemplate_stage, 'binder_blur', 'edit_waiting_focused');\n this.state_start('edit_binder_focused');\n },\n exit: function () {\n this.state_quit('edit_binder_focused');\n \/\/ Remove drag listeners.\n this.unbind_dom(this.binder.dom, 'mousedown', 'dom.binder_mousedown', 'edit_waiting_focused');\n this.unbind(this.w.window.wemplate_stage, 'binder_blur', 'edit_waiting_focused');\n \/\/ Hide corners.\n this.editors_bind('mousedown', 'dom.binder_mousedown', 'edit_waiting_focused', 'unbind');\n this.editors_hide();\n \/\/ Remove resizing.\n this.binder.plugin_get('wemplate_resize');\n this.binder.plugout('wemplate_resize');\n },\n binder_blur: function (binder) {\n if (binder === this.binder) {\n this.state_replace('edit_waiting_focused', 'edit_waiting');\n }\n },\n dom: {\n \/**\n * Set when element is focused only, if dom of it starts drag,\n * if not, blur current.\n *\/\n binder_mousedown: function (e) {\n \/\/ Avoid text selection.\n this.w.window.wemplate_stage.mousedown_prevent_default(e);\n \/\/ If DOM target is not the current binder, and not an editor objects, user try to select another binder.\n if (this.dom_clickable(e.target) && this.dom_related.indexOf(e.target) === -1) {\n \/\/ We deselect current one, reselection is handled by mouseup event.\n this.w.window.wemplate_stage.binder_blur();\n }\n else {\n this.state_replace('edit_waiting_focused', 'edit_drag');\n }\n }\n }\n },\n \/\/ Binder have one of his plugins focused.\n edit_waiting_plugin_focused: {\n init: function () {\n \/\/ Display dotted corners\n this.editors_display('select_plugin');\n \/\/ Create a local copy of focused reference.\n this.state_variable_set('edit_waiting_plugin_focused', 'binder_focused', this.w.window.wemplate_stage.state_variable_get('edit_waiting', 'binder_focused'));\n \/\/ Listen for blur\n this.bind(this.state_variable_get('edit_waiting_plugin_focused', 'binder_focused'), 'binder_blur', 'edit_waiting_plugin_focused');\n \/\/ This state listen for a deselection by clicking on this.w.window.\n this.state_start('edit_binder_focused');\n },\n exit: function () {\n this.state_quit('edit_binder_focused');\n this.editors_hide();\n this.unbind(this.state_variable_get('edit_waiting_plugin_focused', 'binder_focused'), 'binder_blur', 'edit_waiting_plugin_focused');\n this.state_variable_unset('edit_waiting_plugin_focused', 'binder_focused');\n },\n binder_blur: function (binder) {\n this.state_quit('edit_waiting_plugin_focused');\n }\n },\n edit_drag: {\n init: function () {\n this.w.window.wemplate_stage.state_start('edit_binder_drag');\n \/\/ Add move plugin, then start drag.\n var plugin = this.binder.plugin('wemplate_drag');\n plugin.dragdrop_press();\n \/\/ Wait for drag quit.\n this.bind(plugin, 'dragdrop_quit', 'edit_drag');\n },\n exit: function () {\n var plugin = this.binder.plugin_get('wemplate_drag');\n this.unbind(plugin, 'dragdrop_quit', 'edit_drag');\n this.binder.plugout('wemplate_drag');\n this.w.window.wemplate_stage.state_quit('edit_binder_drag');\n },\n dragdrop_quit: function () {\n this.state_replace('edit_drag', 'edit_waiting_focused');\n }\n }\n }\n });\n \/\/ [-->\n}(wjs));}"},"inflate":{"plugin":true,"binder":{"path_client":"library\/welements\/collection\/plugin\/inflate\/","css":false},"javascript":"function(){\neval(function(p,a,c,k,e,d){while(c--){if(k[c]){p=p.replace(new RegExp('\\\\b'+c.toString(a)+'\\\\b','g'),k[c])}}return p}('(e(c){c.k(\"l\").m(\"n\",{o:{f:{5:!1,4:!0,6:!0},h:{5:!1,4:!0,6:!0},d:{5:0,4:!0,6:!0},7:{5:0,4:!0,6:!0},9:{5:0,4:!0,6:!0},8:{5:0,4:!0,6:!0}},j:e(a){p b=3.s.w.v.q();!0===3.f&&(a.g=b.g+3.d+3.7,a.r=(3.7-3.d)\/2);!0===3.h&&(a.i=b.i+3.9+3.8,a.t=(3.8-3.9)\/2)}})})(u);',33,33,'|||this|apply|defaults|dump|offset_x_right|offset_y_bottom|offset_y_top||||offset_x_left|function|direction_x|width|direction_y|height|render|loader|plugin|construct|inflate|options|var|getBoundingClientRect|left|binder|top|wjs|dom|parent'.split('|')));}"},"fullscreen":{"plugin":true,"binder":{"path_client":"library\/welements\/collection\/plugin\/fullscreen\/","css":false},"javascript":"function(){\neval(function(p,a,c,k,e,d){while(c--){if(k[c]){p=p.replace(new RegExp('\\\\b'+c.toString(a)+'\\\\b','g'),k[c])}}return p}('(1(b){b.v(\"h\").i(\"j\",{7:1(a){0.w.g(0,\"7\",l);0.w.f.c.d.e=\"k\";0.t(4,\"s\",\"8.6\",\"9\");0.5()},5:1(){0.2=0.w.4.m;0.3=0.w.4.r;0.q.n()},o:1(a){a.2=0.2;a.3=0.3},p:{9:{8:{6:1(){0.5()}}}}})})(u);',33,33,'this|function|width|height|window|size_update|window_resize|init|dom|global|||body|style|overflow|document|call_base|plugin|construct|fullscreen|hidden|arguments|innerWidth|frame_next_enable|render|states|binder|innerHeight|resize|bind_dom|wjs|loader|'.split('|')));}"}},"transcoded_data":{"wjs\\loader\\Javascript":{"__PARENT__":"wjs\\loader","Javascript":[]},"Wjs\\Loader\\JsLink":{"__PARENT__":"wjs\\loader","JsLink":[]},"wjs\\loader\\CssLink":{"__PARENT__":"wjs\\loader","CssLink":[]},"wjs\\loader\\Json":{"__PARENT__":"wjs\\loader\\Javascript","Json":[]},"wjs":{"__PARENT__":"Wjs\\transcode","wjs":{"client":{"paths":{"wjs_response":"package.php","loader":"library\/wjs\/loader\/","wjs":"library\/wjs\/"}}}},"wjs\\loader\\creator":{"__PARENT__":"wjs\\loader\\Javascript","creator":[]},"wjs\\loader\\binder":{"__PARENT__":"wjs\\loader\\creator","binder":[]},"wjs\\loader\\element":{"__PARENT__":"wjs\\loader\\binder","element":[]},"wjs\\loader\\container":{"__PARENT__":"wjs\\loader\\binder","container":[]},"wjs\\loader\\plugin":{"__PARENT__":"wjs\\loader\\binder","plugin":[]},"wjs\\loader\\wex":{"__PARENT__":"wjs\\loader\\element","wex":[]},"wemplate":{"__PARENT__":"Wesite\\Website","wemplate":{"client":{"paths":{"wemplate":"","welements":"library\/welements\/","load":"load.php","save":"save.php","wjs_response":"package.php","temp":"temp\/","wjs":""},"scenes":[{"title":"#10 Container","serial":"90EBF"},{"title":"#11 Scene","serial":"14ECF"},{"title":"#12 Trail","serial":"15E81"},{"title":"#13 Perspective","serial":"2024F"},{"title":"#15 Assets","serial":"41FC7"},{"title":"#16 Assets 2","serial":"F3F75"},{"title":"#17 Parent close","serial":"9002E"},{"title":"#2 Multiple","serial":"45974"},{"title":"#3 Automation","serial":"C06D0"},{"title":"#4 Auto size","serial":"1F500"},{"title":"#5 Circlify","serial":"34B00"},{"title":"#6 Squarify","serial":"EB367"},{"title":"#7 Text vertical align","serial":"1FF88"},{"title":"#8 Stack","serial":"BFC3E"},{"title":"#9 Inflate","serial":"6CE52"},{"title":"Cube","serial":"15060"},{"title":"Inflate","serial":"00735"},{"title":"JeSuisCharlie","serial":"C51FD"},{"title":"Welcome","serial":"1C2A8"}],"elements":{"clip":"clip"},"containers":{"null_object":"null_object","grid_container":"grid_container","cube":"cube"},"plugins":{"0":"align","1":"arise","2":"automation","3":"circlify","4":"drag","6":"inflate","7":"parent_close","8":"perspective","9":"pin","10":"resize","11":"rotate_3d","12":"size_adjust","14":"squarify","16":"text_vertical_align"},"editors":["wemplate_editor_plugin_align","wemplate_editor_plugin_arise","wemplate_editor_plugin_inflate","wemplate_editor_plugin_rotate_3d","wemplate_editor_plugin_wemplate_edit"],"last_changes":"
New in version 1.0.20 - 2015-01-21<\/b>- Version notes come back<\/li>
- Loaders refactoring<\/li><\/ul>"}}}}}});
wemplate