From 0d61aa88c2aa553575a7ecce619016cacc27e167 Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Thu, 13 Jun 2019 19:21:19 -0700 Subject: [PATCH] Add utility to inline includes in the XML data structure --- experiments/modern/.watchmanconfig | 0 experiments/modern/src/App.js | 43 +- .../src/__snapshots__/utils.test.js.snap | 4251 +++++++++++++++++ experiments/modern/src/utils.js | 41 + experiments/modern/src/utils.test.js | 67 + 5 files changed, 4362 insertions(+), 40 deletions(-) create mode 100644 experiments/modern/.watchmanconfig create mode 100644 experiments/modern/src/__snapshots__/utils.test.js.snap create mode 100644 experiments/modern/src/utils.js create mode 100644 experiments/modern/src/utils.test.js diff --git a/experiments/modern/.watchmanconfig b/experiments/modern/.watchmanconfig new file mode 100644 index 00000000..e69de29b diff --git a/experiments/modern/src/App.js b/experiments/modern/src/App.js index 86a10177..5237bcf7 100644 --- a/experiments/modern/src/App.js +++ b/experiments/modern/src/App.js @@ -2,44 +2,10 @@ import React from "react"; import JSZip from "jszip"; import "./App.css"; import { xml2js } from "xml-js"; +import * as Utils from "./utils"; const SkinContext = React.createContext(null); -async function readXml(zip, file) { - // TODO: Handle case where file is not found - // TODO: Escape `file` for rejex characters - const text = await zip.file(new RegExp(file, "i"))[0].async("text"); - return xml2js(text, { compact: false, elementsKey: "children" }); -} - -async function walkAsync(xml, visitor) { - await visitor(xml); - if (xml.children != null) { - await Promise.all(xml.children.map(child => walkAsync(child, visitor))); - } - return xml; -} - -async function resolveIncludes(xml, zip) { - // TODO: Use _.memoize or similar - const includes = {}; - async function readInclude(file) { - if (!includes[file]) { - includes[file] = readXml(zip, file); - } - return includes[file]; - } - - return walkAsync(xml, async node => { - if (node.name === "include") { - // TODO: Normalize file names so that they hit the same cache - const includeXml = await readInclude(node.attributes.file); - node.children = includeXml.children; - } - return xml; - }); -} - async function getSkin() { const resp = await fetch( process.env.PUBLIC_URL + "/skins/CornerAmp_Redux.wal" @@ -47,10 +13,7 @@ async function getSkin() { const blob = await resp.blob(); const zip = await JSZip.loadAsync(blob); - const skinXml = await readXml(zip, "skin.xml"); - const resolved = await resolveIncludes(skinXml, zip); - console.log(resolved); - const player = zip.file("xml/player-elements.xml"); + const player = Utils.getCaseInsensitveFile(zip, "xml/player-elements.xml"); const xml = await player.async("text"); const elementsDoc = await xml2js(xml, { @@ -66,7 +29,7 @@ async function getSkin() { case "bitmap": { const { file, gammagroup, h, id, w, x, y } = element.attributes; // TODO: Escape file for regex - const img = zip.file(new RegExp(file, "i"))[0]; + const img = Utils.getCaseInsensitveFile(zip, file); const imgBlob = await img.async("blob"); const imgUrl = URL.createObjectURL(imgBlob); images[id.toLowerCase()] = { file, gammagroup, h, w, x, y, imgUrl }; diff --git a/experiments/modern/src/__snapshots__/utils.test.js.snap b/experiments/modern/src/__snapshots__/utils.test.js.snap new file mode 100644 index 00000000..dc690530 --- /dev/null +++ b/experiments/modern/src/__snapshots__/utils.test.js.snap @@ -0,0 +1,4251 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`inlineIncludes inlines the contents of included files as children of the include node 1`] = ` +Object { + "children": Array [ + Object { + "attributes": Object { + "version": "1.35", + }, + "children": Array [ + Object { + "children": Array [ + Object { + "children": Array [ + Object { + "text": "1.0", + "type": "text", + }, + ], + "name": "version", + "type": "element", + }, + Object { + "children": Array [ + Object { + "text": "CornerAmp Redux", + "type": "text", + }, + ], + "name": "name", + "type": "element", + }, + Object { + "children": Array [ + Object { + "text": "9 of Nine, Evil Pumpkin, RazorZero", + "type": "text", + }, + ], + "name": "author", + "type": "element", + }, + Object { + "children": Array [ + Object { + "text": "Updated for Winamp 5 by Ariszló", + "type": "text", + }, + ], + "name": "comment", + "type": "element", + }, + Object { + "children": Array [ + Object { + "text": "ariszlo@gmail.com", + "type": "text", + }, + ], + "name": "email", + "type": "element", + }, + Object { + "children": Array [ + Object { + "text": "http://ariszlo.deviantart.com", + "type": "text", + }, + ], + "name": "homepage", + "type": "element", + }, + Object { + "children": Array [ + Object { + "text": "skinshot.png", + "type": "text", + }, + ], + "name": "screenshot", + "type": "element", + }, + ], + "name": "skininfo", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/system-colors.xml", + }, + "children": Array [ + Object { + "children": Array [ + Object { + "comment": " Right-Click Menu ", + "type": "comment", + }, + Object { + "attributes": Object { + "gammagroup": "Backgrounds", + "id": "wasabi.popupmenu.background.selected", + "value": "67,67,77", + }, + "name": "color", + "type": "element", + }, + Object { + "comment": " Generic Trees ", + "type": "comment", + }, + Object { + "attributes": Object { + "gammagroup": "Display Fonts", + "id": "wasabi.tree.text", + "value": "196,255,196", + }, + "name": "color", + "type": "element", + }, + Object { + "comment": " Generic Lists ", + "type": "comment", + }, + Object { + "attributes": Object { + "gammagroup": "Display Fonts", + "id": "wasabi.list.text", + "value": "196,255,196", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Display Backgrounds", + "id": "wasabi.list.background", + "value": "0,0,0", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Text", + "id": "wasabi.list.text.selected", + "value": "255,255,255", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Text Backgrounds", + "id": "wasabi.list.text.selected.background", + "value": "0,0,128", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Text", + "id": "wasabi.list.text.current", + "value": "255,255,255", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Backgrounds", + "id": "wasabi.list.column.background", + "value": "102,102,102", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Backgrounds", + "id": "wasabi.list.column.frame.top", + "value": "192,192,192", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Backgrounds", + "id": "wasabi.list.column.frame.middle", + "value": "128,128,128", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Backgrounds", + "id": "wasabi.list.column.frame.bottom", + "value": "64,64,64", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Backgrounds", + "id": "wasabi.list.column.empty", + "value": "64,64,64", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Text", + "id": "wasabi.list.column.separator", + "value": "128,128,128", + }, + "name": "color", + "type": "element", + }, + Object { + "comment": " edit wnds ", + "type": "comment", + }, + Object { + "attributes": Object { + "gammagroup": "Backgrounds", + "id": "wasabi.window.background", + "value": "128,128,128", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Text", + "id": "wasabi.window.text", + "value": "255,255,255", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Backgrounds", + "id": "wasabi.border.sunken", + "value": "192,192,192", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Backgrounds", + "id": "wasabi.scrollbar.foreground", + "value": "128,128,128", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Backgrounds", + "id": "wasabi.scrollbar.background", + "value": "128,128,128", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Backgrounds", + "id": "wasabi.scrollbar.foreground.inverted", + "value": "128,128,128", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Backgrounds", + "id": "wasabi.scrollbar.background.inverted", + "value": "128,128,128", + }, + "name": "color", + "type": "element", + }, + Object { + "comment": " Item Lists, Lists with playable items ", + "type": "comment", + }, + Object { + "attributes": Object { + "gammagroup": "Display Fonts", + "id": "wasabi.itemlist.outline.current", + "value": "255,255,0", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Display Fonts", + "id": "wasabi.itemlist.outline.focus", + "value": "0,128,128", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Text Backgrounds", + "id": "wasabi.itemlist.selborder", + "value": "64,64,196", + }, + "name": "color", + "type": "element", + }, + Object { + "comment": " Buttons ", + "type": "comment", + }, + Object { + "attributes": Object { + "gammagroup": "Button Fonts", + "id": "wasabi.button.text", + "value": "0,0,0", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Button Fonts", + "id": "wasabi.button.hiliteText", + "value": "255,255,255", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Button Fonts", + "id": "wasabi.button.dimmedText", + "value": "64,64,64", + }, + "name": "color", + "type": "element", + }, + Object { + "comment": " Components ", + "type": "comment", + }, + Object { + "attributes": Object { + "gammagroup": "Titlebar Font", + "id": "wasabi.component.title.foreground", + "value": "255,255,255", + }, + "name": "color", + "type": "element", + }, + Object { + "comment": " Tabsheet ", + "type": "comment", + }, + Object { + "attributes": Object { + "gammagroup": "Text", + "id": "wasabi.tabsheet.activetext", + "value": "255,255,255", + }, + "name": "color", + "type": "element", + }, + Object { + "attributes": Object { + "gammagroup": "Text", + "id": "wasabi.tabsheet.inactivetext", + "value": "200,200,200", + }, + "name": "color", + "type": "element", + }, + ], + "name": "elements", + "type": "element", + }, + ], + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/standardframe.xml", + }, + "children": Array [ + Object { + "comment": " ======================================================================================================= + + This file implements the following objects : + + - Wasabi:StandardFrame:Status + - Wasabi:StandardFrame:NoStatus + - Wasabi:StandardFrame:Modal + - Wasabi:StandardFrame:Static + + Available parameters : + + padtitleleft : resizes the title from the left by the specified amount of pixels + padtitleright : resizes the title from the right by the specified amount of pixels + content : tells the object which group to instantiate in its client area + +======================================================================================================== ", + "type": "comment", + }, + Object { + "attributes": Object { + "file": "studio-elements.xml", + }, + "children": Array [ + Object { + "children": Array [ + Object { + "comment": " Base Texture ", + "type": "comment", + }, + Object { + "attributes": Object { + "file": "window/background.png", + "gammagroup": "Backgrounds", + "id": "wasabi.basetexture", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "comment": " Studio Buttons ", + "type": "comment", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "2", + "id": "wasabi.button.top.left", + "w": "2", + "x": "0", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "2", + "id": "wasabi.button.top", + "w": "25", + "x": "3", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "2", + "id": "wasabi.button.top.right", + "w": "2", + "x": "29", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "25", + "id": "wasabi.button.left", + "w": "2", + "x": "0", + "y": "3", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "25", + "id": "wasabi.button.center", + "w": "25", + "x": "3", + "y": "3", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "25", + "id": "wasabi.button.right", + "w": "2", + "x": "29", + "y": "3", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "2", + "id": "wasabi.button.bottom.left", + "w": "2", + "x": "0", + "y": "29", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "2", + "id": "wasabi.button.bottom", + "w": "25", + "x": "3", + "y": "29", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "2", + "id": "wasabi.button.bottom.right", + "w": "2", + "x": "29", + "y": "29", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "2", + "id": "wasabi.button.pressed.top.left", + "w": "2", + "x": "32", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "2", + "id": "wasabi.button.pressed.top", + "w": "25", + "x": "35", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "2", + "id": "wasabi.button.pressed.top.right", + "w": "2", + "x": "61", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "25", + "id": "wasabi.button.pressed.left", + "w": "2", + "x": "32", + "y": "3", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "25", + "id": "wasabi.button.pressed.center", + "w": "25", + "x": "35", + "y": "3", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "25", + "id": "wasabi.button.pressed.right", + "w": "2", + "x": "61", + "y": "3", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "2", + "id": "wasabi.button.pressed.bottom.left", + "w": "2", + "x": "32", + "y": "29", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "2", + "id": "wasabi.button.pressed.bottom", + "w": "25", + "x": "35", + "y": "29", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "2", + "id": "wasabi.button.pressed.bottom.right", + "w": "2", + "x": "61", + "y": "29", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "comment": " wasabi.button.middle = wasabi.button.center ", + "type": "comment", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "25", + "id": "wasabi.button.middle", + "w": "25", + "x": "3", + "y": "3", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Buttons", + "h": "25", + "id": "wasabi.button.pressed.middle", + "w": "25", + "x": "35", + "y": "3", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "comment": " Scaler ", + "type": "comment", + }, + Object { + "attributes": Object { + "file": "window/studio-elements.png", + "gammagroup": "Backgrounds", + "h": "12", + "id": "wasabi.frame.resizer", + "w": "12", + "x": "64", + "y": "19", + }, + "name": "bitmap", + "type": "element", + }, + ], + "name": "elements", + "type": "element", + }, + ], + "name": "include", + "type": "element", + }, + Object { + "comment": " ======================================================================================================= + + This group serves as a template for all the Wasabi:StandardFrame objects + +======================================================================================================== ", + "type": "comment", + }, + Object { + "attributes": Object { + "id": "wasabi.frame.layout", + }, + "children": Array [ + Object { + "attributes": Object { + "id": "window.top.left", + "image": "wasabi.frame.top.left", + "resize": "topleft", + "x": "0", + "y": "0", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.top", + "image": "wasabi.frame.top", + "relatw": "1", + "resize": "top", + "w": "-30", + "x": "15", + "y": "0", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.top.right", + "image": "wasabi.frame.top.right", + "relatx": "1", + "resize": "topright", + "x": "-15", + "y": "0", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "h": "0", + "id": "window.left", + "image": "wasabi.frame.left", + "relath": "1", + "resize": "left", + "x": "0", + "y": "15", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "h": "0", + "id": "window.right", + "image": "wasabi.frame.right", + "relath": "1", + "relatx": "1", + "resize": "right", + "x": "-5", + "y": "15", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "h": "-10", + "id": "window.resize.disabler", + "relath": "1", + "relatw": "1", + "w": "-10", + "x": "5", + "y": "5", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "bg": "0", + "h": "9", + "id": "sysmenu.status", + "includeonly": "{system}", + "w": "14", + "x": "5", + "y": "3", + }, + "name": "LayoutStatus", + "type": "element", + }, + Object { + "attributes": Object { + "target": "sysmenu.status", + }, + "name": "hideobject", + "type": "element", + }, + Object { + "attributes": Object { + "action": "sysmenu", + "activeAlpha": "0", + "downImage": "wasabi.button.sysmenu", + "id": "mainmenu.inactive", + "image": "wasabi.button.sysmenu.pressed", + "tooltip": "Main Menu", + "x": "5", + "y": "3", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "sysmenu", + "downImage": "wasabi.button.sysmenu.pressed", + "id": "mainmenu", + "image": "wasabi.button.sysmenu", + "inactiveAlpha": "0", + "tooltip": "Main Menu", + "x": "5", + "y": "3", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "CLOSE", + "activeAlpha": "0", + "downImage": "wasabi.button.close", + "id": "Close.inactive", + "image": "wasabi.button.close.pressed", + "relatx": "1", + "tooltip": "Close Window", + "x": "-18", + "y": "3", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "CLOSE", + "downImage": "wasabi.button.close.pressed", + "id": "Close", + "image": "wasabi.button.close", + "inactiveAlpha": "0", + "relatx": "1", + "tooltip": "Close Window", + "x": "-18", + "y": "3", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "h": "11", + "id": "wasabi.titlebar", + "relatw": "1", + "w": "-42", + "x": "22", + "y": "2", + }, + "name": "Wasabi:TitleBar", + "type": "element", + }, + ], + "name": "groupdef", + "type": "element", + }, + Object { + "comment": " ======================================================================================================= + + implementation + +======================================================================================================== ", + "type": "comment", + }, + Object { + "attributes": Object { + "background": "wasabi.frame.basetexture", + "id": "wasabi.standardframe.statusbar", + "sysregion": "1", + "xuitag": "Wasabi:StandardFrame:Status", + }, + "children": Array [ + Object { + "attributes": Object { + "h": "-21", + "id": "wasabi.frame.layout", + "relath": "1", + "relatw": "1", + "w": "0", + "x": "0", + "y": "0", + }, + "name": "group", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.bottom.left.top", + "image": "wasabi.frame.bottom.left.top", + "relaty": "1", + "resize": "bottomleft", + "x": "0", + "y": "-21", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "h": "17", + "id": "window.bottom.left", + "image": "wasabi.frame.bottom.left", + "relaty": "1", + "resize": "bottomleft", + "x": "0", + "y": "-19", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.bottom.left.bottom", + "image": "wasabi.frame.bottom.left.bottom", + "relaty": "1", + "resize": "bottomleft", + "x": "0", + "y": "-2", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.bottom.top", + "image": "wasabi.frame.bottom.top", + "relatw": "1", + "relaty": "1", + "w": "-30", + "x": "15", + "y": "-21", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "h": "17", + "id": "window.bottom", + "image": "wasabi.frame.bottom", + "relatw": "1", + "relaty": "1", + "resize": "bottom", + "w": "-30", + "x": "15", + "y": "-19", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.bottom.bottom", + "image": "wasabi.frame.bottom.bottom", + "relatw": "1", + "relaty": "1", + "resize": "bottom", + "w": "-30", + "x": "15", + "y": "-2", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.bottom.right.top", + "image": "wasabi.frame.bottom.right.top", + "relatx": "1", + "relaty": "1", + "resize": "bottomright", + "x": "-15", + "y": "-21", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "h": "17", + "id": "window.bottom.right", + "image": "wasabi.frame.bottom.right", + "relatx": "1", + "relaty": "1", + "resize": "bottomright", + "x": "-15", + "y": "-19", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.bottom.right.bottom", + "image": "wasabi.frame.bottom.right.bottom", + "relatx": "1", + "relaty": "1", + "resize": "bottomright", + "x": "-15", + "y": "-2", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.resizer", + "image": "wasabi.frame.resizer", + "relatx": "1", + "relaty": "1", + "resize": "bottomright", + "scale": "bottomright", + "x": "-16", + "y": "-16", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "exclude": "{system}", + "h": "17", + "id": "standardframe.layoutstatus", + "relatw": "1", + "relaty": "1", + "w": "-23", + "x": "4", + "y": "-19", + }, + "name": "LayoutStatus", + "type": "element", + }, + Object { + "attributes": Object { + "file": "scripts/standardframe.maki", + "id": "standardframe.script", + "param": "5,15,-10,-36,0,0,1,1", + }, + "name": "script", + "type": "element", + }, + ], + "name": "groupdef", + "type": "element", + }, + Object { + "comment": " ======================================================================================================= + + implementation + +======================================================================================================== ", + "type": "comment", + }, + Object { + "attributes": Object { + "background": "wasabi.frame.basetexture", + "id": "wasabi.standardframe.nostatusbar", + "sysregion": "1", + "xuitag": "Wasabi:StandardFrame:NoStatus", + }, + "children": Array [ + Object { + "attributes": Object { + "h": "-5", + "id": "wasabi.frame.layout", + "relath": "1", + "relatw": "1", + "w": "0", + "x": "0", + "y": "0", + }, + "name": "group", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.bottom.left.top", + "image": "wasabi.frame.bottom.left.top", + "relaty": "1", + "resize": "bottomleft", + "x": "0", + "y": "-5", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "h": "1", + "id": "window.bottom.left", + "image": "wasabi.frame.bottom.left", + "relaty": "1", + "resize": "bottomleft", + "x": "0", + "y": "-3", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.bottom.left.bottom", + "image": "wasabi.frame.bottom.left.bottom", + "relaty": "1", + "resize": "bottomleft", + "x": "0", + "y": "-2", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.bottom.top", + "image": "wasabi.frame.bottom.top", + "relatw": "1", + "relaty": "1", + "w": "-30", + "x": "15", + "y": "-5", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "h": "1", + "id": "window.bottom", + "image": "wasabi.frame.bottom", + "relatw": "1", + "relaty": "1", + "resize": "bottom", + "w": "-30", + "x": "15", + "y": "-3", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.bottom.bottom", + "image": "wasabi.frame.bottom.bottom", + "relatw": "1", + "relaty": "1", + "resize": "bottom", + "w": "-30", + "x": "15", + "y": "-2", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.bottom.right.top", + "image": "wasabi.frame.bottom.right.top", + "relatx": "1", + "relaty": "1", + "resize": "bottomright", + "x": "-15", + "y": "-5", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "h": "1", + "id": "window.bottom.right", + "image": "wasabi.frame.bottom.right", + "relatx": "1", + "relaty": "1", + "resize": "bottomright", + "x": "-15", + "y": "-3", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "window.bottom.right.bottom", + "image": "wasabi.frame.bottom.right.bottom", + "relatx": "1", + "relaty": "1", + "resize": "bottomright", + "x": "-15", + "y": "-2", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "file": "scripts/standardframe.maki", + "id": "standardframe.script", + "param": "5,15,-10,-20,0,0,1,1", + }, + "name": "script", + "type": "element", + }, + ], + "name": "groupdef", + "type": "element", + }, + Object { + "comment": " ======================================================================================================= + + implementation + +======================================================================================================== ", + "type": "comment", + }, + Object { + "attributes": Object { + "id": "wasabi.standardframe.modal", + "inherit_group": "wasabi.standardframe.nostatusbar", + "sysregion": "1", + "xuitag": "Wasabi:StandardFrame:Modal", + }, + "children": Array [ + Object { + "attributes": Object { + "h": "-20", + "id": "wasabi.panel", + "relath": "1", + "relatw": "1", + "w": "-10", + "x": "5", + "y": "15", + }, + "name": "group", + "type": "element", + }, + Object { + "attributes": Object { + "target": "controlmenu;controlmenu.inactive", + }, + "name": "hideobject", + "type": "element", + }, + Object { + "attributes": Object { + "relatw": "1", + "target": "wasabi.titlebar", + "w": "-24", + "x": "4", + }, + "name": "sendparams", + "type": "element", + }, + Object { + "attributes": Object { + "resize": "0", + "target": "window.top.left;window.top;window.top.right;window.left;window.right;window.bottom.left.top;window.bottom.left;window.bottom.left.bottom;window.bottom.top;window.bottom;window.bottom.bottom;window.bottom.right.top;window.bottom.right;window.bottom.right.bottom", + }, + "name": "sendparams", + "type": "element", + }, + ], + "name": "groupdef", + "type": "element", + }, + Object { + "comment": " ======================================================================================================= + + implementation + +======================================================================================================== ", + "type": "comment", + }, + Object { + "attributes": Object { + "id": "wasabi.standardframe.static", + "inherit_group": "wasabi.standardframe.nostatusbar", + "sysregion": "1", + "xuitag": "Wasabi:StandardFrame:Static", + }, + "children": Array [ + Object { + "attributes": Object { + "h": "-20", + "id": "wasabi.panel", + "relath": "1", + "relatw": "1", + "w": "-10", + "x": "5", + "y": "15", + }, + "name": "group", + "type": "element", + }, + Object { + "attributes": Object { + "resize": "0", + "target": "window.top.left;window.top;window.top.right;window.left;window.right;window.bottom.left.top;window.bottom.left;window.bottom.left.bottom;window.bottom.top;window.bottom;window.bottom.bottom;window.bottom.right.top;window.bottom.right;window.bottom.right.bottom", + }, + "name": "sendparams", + "type": "element", + }, + Object { + "comment": " ", + "type": "comment", + }, + ], + "name": "groupdef", + "type": "element", + }, + ], + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/player.xml", + }, + "children": Array [ + Object { + "attributes": Object { + "file": "player-elements.xml", + }, + "children": Array [ + Object { + "children": Array [ + Object { + "attributes": Object { + "file": "player/textmask1.png", + "gammagroup": "CornerAmp", + "id": "mask1", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/textmask2.png", + "gammagroup": "CornerAmp", + "id": "mask2", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/textmask3.png", + "gammagroup": "CornerAmp", + "id": "mask3", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/textmask4.png", + "gammagroup": "CornerAmp", + "id": "mask4", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/titletopleft.png", + "id": "title1", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/titletopright.png", + "id": "title2", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/titledownleft.png", + "id": "title3", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/titledownright.png", + "id": "title4", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/background-LU.png", + "gammagroup": "CornerAmp", + "id": "player.bg", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/background-RU.png", + "gammagroup": "CornerAmp", + "id": "player.bg5", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/background-LD.png", + "gammagroup": "CornerAmp", + "id": "player.bg6", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/background-RD.png", + "gammagroup": "CornerAmp", + "id": "player.bg7", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/main1.png", + "gammagroup": "CornerAmp", + "id": "player.bg1", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/main2.png", + "gammagroup": "CornerAmp", + "id": "player.bg2", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/main3.png", + "gammagroup": "CornerAmp", + "id": "player.bg3", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/main4.png", + "gammagroup": "CornerAmp", + "id": "player.bg4", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/buttons.png", + "gammagroup": "CornerAmp", + "h": "39", + "id": "player.button.previous", + "w": "39", + "x": "40", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/buttons.png", + "gammagroup": "CornerAmp", + "h": "39", + "id": "player.button.previous.pressed", + "w": "39", + "x": "40", + "y": "40", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/buttons.png", + "gammagroup": "CornerAmp", + "h": "39", + "id": "player.button.next", + "w": "39", + "x": "79", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/buttons.png", + "gammagroup": "CornerAmp", + "h": "39", + "id": "player.button.next.pressed", + "w": "39", + "x": "79", + "y": "40", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/buttons.png", + "gammagroup": "CornerAmp", + "h": "39", + "id": "player.button.play", + "w": "39", + "x": "118", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/buttons.png", + "gammagroup": "CornerAmp", + "h": "39", + "id": "player.button.play.pressed", + "w": "39", + "x": "118", + "y": "40", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/buttons.png", + "gammagroup": "CornerAmp", + "h": "39", + "id": "player.button.pause", + "w": "39", + "x": "157", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/buttons.png", + "gammagroup": "CornerAmp", + "h": "39", + "id": "player.button.pause.pressed", + "w": "39", + "x": "157", + "y": "40", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/buttons.png", + "gammagroup": "CornerAmp", + "h": "39", + "id": "player.button.stop", + "w": "39", + "x": "0", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/buttons.png", + "gammagroup": "CornerAmp", + "h": "39", + "id": "player.button.stop.pressed", + "w": "39", + "x": "0", + "y": "40", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/buttons.png", + "gammagroup": "CornerAmp", + "h": "39", + "id": "player.button.eject", + "w": "39", + "x": "196", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/buttons.png", + "gammagroup": "CornerAmp", + "h": "39", + "id": "player.button.eject.pressed", + "w": "39", + "x": "196", + "y": "40", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "14", + "id": "player.toggler.crossfade.disabled", + "w": "32", + "x": "78", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "14", + "id": "player.toggler.crossfade.pressed", + "w": "32", + "x": "78", + "y": "15", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "14", + "id": "player.toggler.crossfade.enabled", + "w": "32", + "x": "78", + "y": "30", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "16", + "id": "player.toggler.shuffle.disabled", + "w": "28", + "x": "109", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "16", + "id": "player.toggler.shuffle.pressed", + "w": "28", + "x": "109", + "y": "15", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "16", + "id": "player.toggler.shuffle.enabled", + "w": "28", + "x": "109", + "y": "30", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "30", + "id": "player.toggler.repeat.disabled", + "w": "72", + "x": "0", + "y": "58", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "30", + "id": "player.toggler.repeat.pressed", + "w": "72", + "x": "0", + "y": "88", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "30", + "id": "player.toggler.repeat.enabled", + "w": "72", + "x": "0", + "y": "118", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "14", + "id": "player.switch.ml.disabled", + "w": "27", + "x": "25", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "14", + "id": "player.switch.ml.pressed", + "w": "27", + "x": "25", + "y": "15", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "14", + "id": "player.switch.ml.enabled", + "w": "27", + "x": "25", + "y": "30", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "15", + "id": "player.switch.eq.disabled", + "w": "26", + "x": "0", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "15", + "id": "player.switch.eq.pressed", + "w": "26", + "x": "0", + "y": "15", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "15", + "id": "player.switch.eq.enabled", + "w": "26", + "x": "0", + "y": "30", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "14", + "id": "player.switch.playlist.disabled", + "w": "28", + "x": "51", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "14", + "id": "player.switch.playlist.pressed", + "w": "28", + "x": "51", + "y": "15", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "14", + "id": "player.switch.playlist.enabled", + "w": "28", + "x": "51", + "y": "30", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "5", + "id": "player.status.stop", + "w": "5", + "x": "186", + "y": "3", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "5", + "id": "player.status.pause", + "w": "5", + "x": "186", + "y": "8", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "5", + "id": "player.status.play", + "w": "5", + "x": "186", + "y": "13", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "10", + "id": "player.seek", + "w": "151", + "x": "0", + "y": "46", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "1", + "id": "player.seek.full", + "w": "151", + "x": "0", + "y": "57", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/volume.png", + "gammagroup": "CornerAmp", + "id": "player.volume", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "player/toggles.png", + "gammagroup": "CornerAmp", + "h": "2", + "id": "player.volume.thumb", + "w": "7", + "x": "184", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "pixel.ttf", + "id": "pixel", + }, + "name": "truetypefont", + "type": "element", + }, + Object { + "attributes": Object { + "file": "lucon.ttf", + "id": "lucon", + }, + "name": "truetypefont", + "type": "element", + }, + ], + "name": "elements", + "type": "element", + }, + ], + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "default_visible": "1", + "default_x": "0", + "default_y": "0", + "id": "Main", + "name": "Main Window", + }, + "children": Array [ + Object { + "attributes": Object { + "file": "player-normal.xml", + }, + "children": Array [ + Object { + "attributes": Object { + "background": "player.bg", + "desktopalpha": "1", + "drawbackground": "0", + "droptarget": "pldr", + "id": "normal", + "maximum_h": "228", + "maximum_w": "246", + "minimum_h": "228", + "minimum_w": "246", + }, + "children": Array [ + Object { + "attributes": Object { + "id": "main1", + "image": "player.bg1", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "main2", + "image": "player.bg2", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "main3", + "image": "player.bg3", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "main4", + "image": "player.bg4", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Title1", + "image": "Title1", + "move": "0", + "x": "0", + "y": "92", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Title2", + "image": "Title2", + "move": "0", + "x": "180", + "y": "92", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Title3", + "image": "Title3", + "move": "0", + "x": "0", + "y": "42", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Title4", + "image": "Title4", + "move": "0", + "x": "181", + "y": "35", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "action": "PREV", + "downImage": "player.button.previous.pressed", + "id": "Previous", + "image": "player.button.previous", + "tooltip": "Previous", + "x": "13", + "y": "183", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "PLAY", + "downImage": "player.button.play.pressed", + "id": "Play", + "image": "player.button.play", + "tooltip": "Play", + "x": "37", + "y": "142", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "PAUSE", + "downImage": "player.button.pause.pressed", + "id": "Pause", + "image": "player.button.pause", + "tooltip": "Pause", + "x": "66", + "y": "102", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "STOP", + "downImage": "player.button.stop.pressed", + "id": "Stop", + "image": "player.button.stop", + "tooltip": "Stop", + "x": "104", + "y": "65", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "NEXT", + "downImage": "player.button.next.pressed", + "id": "Next", + "image": "player.button.next", + "tooltip": "Next", + "x": "148", + "y": "36", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "EJECT", + "downImage": "player.button.eject.pressed", + "id": "Eject", + "image": "player.button.eject", + "tooltip": "Eject", + "x": "198", + "y": "14", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "activeImage": "player.toggler.repeat.enabled", + "cfgattrib": "{45F3F7C1-A6F3-4EE6-A15E-125E92FC3F8D};Repeat", + "cfgval": "2", + "downImage": "player.toggler.repeat.pressed", + "id": "Repeat", + "image": "player.toggler.repeat.disabled", + "tooltip": "Repeat", + "x": "136", + "y": "-15", + }, + "name": "togglebutton", + "type": "element", + }, + Object { + "attributes": Object { + "activeImage": "player.toggler.crossfade.enabled", + "cfgattrib": "{FC3EAF78-C66E-4ED2-A0AA-1494DFCC13FF};Enable crossfading", + "downImage": "player.toggler.crossfade.pressed", + "id": "Crossfade", + "image": "player.toggler.crossfade.disabled", + "tooltip": "Crossfade", + "x": "78", + "y": "-1", + }, + "name": "togglebutton", + "type": "element", + }, + Object { + "attributes": Object { + "activeImage": "player.toggler.shuffle.enabled", + "cfgattrib": "{45F3F7C1-A6F3-4EE6-A15E-125E92FC3F8D};Shuffle", + "downImage": "player.toggler.shuffle.pressed", + "id": "Shuffle", + "image": "player.toggler.shuffle.disabled", + "tooltip": "Shuffle", + "x": "109", + "y": "-1", + }, + "name": "togglebutton", + "type": "element", + }, + Object { + "attributes": Object { + "action": "TOGGLE", + "activeImage": "player.switch.eq.enabled", + "downImage": "player.switch.eq.pressed", + "id": "eq", + "image": "player.switch.eq.disabled", + "param": "eq", + "tooltip": "Toggle Equalizer", + "x": "0", + "y": "-1", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "TOGGLE", + "activeImage": "player.switch.ml.enabled", + "downImage": "player.switch.ml.pressed", + "id": "ml", + "image": "player.switch.ml.disabled", + "param": "guid:ml", + "tooltip": "Toggle Music Library", + "x": "25", + "y": "-1", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "TOGGLE", + "activeImage": "player.switch.playlist.enabled", + "downImage": "player.switch.playlist.pressed", + "id": "pl", + "image": "player.switch.playlist.disabled", + "param": "guid:pl", + "tooltip": "Toggle Playlist Editor", + "x": "51", + "y": "-1", + }, + "name": "button", + "type": "element", + }, + Object { + "comment": " Timer ", + "type": "comment", + }, + Object { + "attributes": Object { + "align": "center", + "antialias": "1", + "color": "0,0,0", + "display": "time", + "font": "Pixel", + "fontsize": "28", + "h": "28", + "id": "Timer", + "timecolonwidth": "9", + "w": "65", + "x": "10", + "y": "63", + }, + "name": "text", + "type": "element", + }, + Object { + "attributes": Object { + "align": "center", + "antialias": "1", + "color": "0,0,0", + "default": "", + "display": "songname", + "font": "lucon", + "fontsize": "16", + "h": "16", + "id": "songticker", + "showlen": "1", + "sysregion": "1", + "ticker": "1", + "w": "136", + "x": "2", + "y": "26", + }, + "name": "text", + "type": "element", + }, + Object { + "attributes": Object { + "align": "center", + "antialias": "1", + "color": "0,0,0", + "default": "", + "display": "songinfo", + "font": "Lucon", + "fontsize": "13", + "h": "13", + "id": "songticker2", + "ticker": "1", + "w": "120", + "x": "2", + "y": "42", + }, + "name": "text", + "type": "element", + }, + Object { + "attributes": Object { + "h": "5", + "id": "status", + "pauseBitmap": "player.status.pause", + "playBitmap": "player.status.play", + "stopBitmap": "player.status.stop", + "w": "5", + "x": "3", + "y": "81", + }, + "name": "status", + "type": "element", + }, + Object { + "attributes": Object { + "Ghost": "0", + "id": "volume1", + "image": "player.volume", + "move": "0", + "x": "3", + "y": "95", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "Ghost": "1", + "id": "volumethumb", + "image": "player.volume.thumb", + "move": "0", + "x": "3", + "y": "95", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "Ghost": "0", + "id": "seek1", + "image": "player.seek", + "move": "0", + "x": "3", + "y": "16", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "Ghost": "1", + "id": "seekfull", + "image": "player.seek.full", + "move": "0", + "x": "3", + "y": "21", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "Action": "SEEK", + "h": "0", + "id": "HiddenSeek", + "w": "100", + "x": "150", + "y": "0", + }, + "name": "Slider", + "type": "element", + }, + Object { + "attributes": Object { + "Action": "VOLUME", + "h": "0", + "id": "HiddenVolume", + "w": "100", + "x": "150", + "y": "0", + }, + "name": "Slider", + "type": "element", + }, + Object { + "attributes": Object { + "Ghost": "1", + "id": "mask1", + "image": "mask1", + "move": "1", + "sysregion": "1", + "x": "105", + "y": "26", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "Ghost": "1", + "id": "mask2", + "image": "mask2", + "move": "1", + "sysregion": "1", + "x": "77", + "y": "26", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "Ghost": "1", + "id": "mask3", + "image": "mask3", + "move": "1", + "sysregion": "1", + "x": "105", + "y": "171", + }, + "name": "layer", + "type": "element", + }, + Object { + "attributes": Object { + "Ghost": "1", + "id": "mask4", + "image": "mask4", + "move": "1", + "sysregion": "1", + "x": "77", + "y": "171", + }, + "name": "layer", + "type": "element", + }, + ], + "name": "layout", + "type": "element", + }, + ], + "name": "include", + "type": "element", + }, + ], + "name": "container", + "type": "element", + }, + Object { + "children": Array [ + Object { + "attributes": Object { + "file": "scripts/corner.maki", + "id": "corneramp", + }, + "name": "script", + "type": "element", + }, + ], + "name": "scripts", + "type": "element", + }, + ], + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/pledit.xml", + }, + "children": Array [ + Object { + "attributes": Object { + "component": "guid:{45F3F7C1-A6F3-4ee6-A15E-125E92FC3F8D}", + "default_visible": "0", + "default_y": "250", + "id": "Pledit", + "name": "Playlist Editor", + }, + "children": Array [ + Object { + "attributes": Object { + "id": "pledit.content.group", + }, + "children": Array [ + Object { + "attributes": Object { + "autoclose": "1", + "autoopen": "1", + "h": "0", + "noshowcmdbar": "1", + "param": "guid:{45F3F7C1-A6F3-4ee6-A15E-125E92FC3F8D}", + "relath": "1", + "relatw": "1", + "w": "0", + "x": "0", + "y": "0", + }, + "name": "component", + "type": "element", + }, + ], + "name": "groupdef", + "type": "element", + }, + Object { + "attributes": Object { + "default_h": "200", + "default_w": "320", + "id": "normal", + "minimum_h": "116", + "minimum_w": "275", + }, + "children": Array [ + Object { + "attributes": Object { + "content": "pledit.content.group", + "h": "0", + "relath": "1", + "relatw": "1", + "w": "0", + "x": "0", + "y": "0", + }, + "name": "Wasabi:StandardFrame:Status", + "type": "element", + }, + Object { + "attributes": Object { + "align": "center", + "display": "PE_Info", + "font": "wasabi.font.default", + "h": "10", + "id": "PLTime", + "relatw": "1", + "relaty": "1", + "valign": "top", + "w": "-162", + "x": "116", + "y": "-14", + }, + "name": "text", + "type": "element", + }, + ], + "name": "layout", + "type": "element", + }, + ], + "name": "container", + "type": "element", + }, + ], + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/video.xml", + }, + "children": Array [ + Object { + "attributes": Object { + "component": "guid:{F0816D7B-FFFC-4343-80F2-E8199AA15CC3}", + "default_visible": "0", + "dynamic": "1", + "id": "Video", + "name": "Video", + }, + "children": Array [ + Object { + "attributes": Object { + "id": "video.content.group", + }, + "children": Array [ + Object { + "attributes": Object { + "disableanimatedrects": "1", + "h": "0", + "noshowcmdbar": "1", + "param": "guid:{F0816D7B-FFFC-4343-80F2-E8199AA15CC3}", + "relath": "1", + "relatw": "1", + "w": "0", + "x": "0", + "y": "0", + }, + "name": "component", + "type": "element", + }, + ], + "name": "groupdef", + "type": "element", + }, + Object { + "attributes": Object { + "default_h": "200", + "default_w": "320", + "droptarget": "pldr", + "id": "normal", + "minimum_h": "116", + "minimum_w": "275", + }, + "children": Array [ + Object { + "attributes": Object { + "content": "video.content.group", + "h": "0", + "relath": "1", + "relatw": "1", + "w": "0", + "x": "0", + "y": "0", + }, + "name": "Wasabi:StandardFrame:Status", + "type": "element", + }, + Object { + "attributes": Object { + "align": "center", + "display": "VID_Info", + "font": "wasabi.font.default", + "h": "10", + "id": "VIDInfo", + "relatw": "1", + "relaty": "1", + "valign": "top", + "w": "-178", + "x": "127", + "y": "-14", + }, + "name": "text", + "type": "element", + }, + ], + "name": "layout", + "type": "element", + }, + ], + "name": "container", + "type": "element", + }, + ], + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/eq.xml", + }, + "children": Array [ + Object { + "children": Array [ + Object { + "attributes": Object { + "file": "equalizer/equalizer-placeholder.png", + "id": "eq.placeholder", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "equalizer/eq-buttons.png", + "gammagroup": "Buttons", + "h": "11", + "id": "eq.switch.on.disabled", + "w": "23", + "x": "0", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "equalizer/eq-buttons.png", + "gammagroup": "Buttons", + "h": "11", + "id": "eq.switch.on.pressed", + "w": "23", + "x": "0", + "y": "12", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "equalizer/eq-buttons.png", + "gammagroup": "Buttons", + "h": "11", + "id": "eq.switch.on.enabled", + "w": "23", + "x": "0", + "y": "24", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "equalizer/eq-buttons.png", + "gammagroup": "Buttons", + "h": "11", + "id": "eq.switch.auto.disabled", + "w": "31", + "x": "24", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "equalizer/eq-buttons.png", + "gammagroup": "Buttons", + "h": "11", + "id": "eq.switch.auto.pressed", + "w": "31", + "x": "24", + "y": "12", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "equalizer/eq-buttons.png", + "gammagroup": "Buttons", + "h": "11", + "id": "eq.switch.auto.enabled", + "w": "31", + "x": "24", + "y": "24", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "equalizer/eq-buttons.png", + "gammagroup": "Buttons", + "h": "11", + "id": "eq.button.presets", + "w": "41", + "x": "56", + "y": "0", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "equalizer/eq-buttons.png", + "gammagroup": "Buttons", + "h": "11", + "id": "eq.button.presets.pressed", + "w": "41", + "x": "56", + "y": "12", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "equalizer/eq-buttons.png", + "gammagroup": "Buttons", + "h": "12", + "id": "eq.slider.button", + "w": "16", + "x": "56", + "y": "24", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "equalizer/eq-buttons.png", + "gammagroup": "Buttons", + "h": "12", + "id": "eq.slider.button.pressed", + "w": "16", + "x": "56", + "y": "37", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "equalizer/eq-buttons.png", + "gammagroup": "Buttons", + "h": "13", + "id": "eq.slider.horizontal.button", + "w": "17", + "x": "0", + "y": "36", + }, + "name": "bitmap", + "type": "element", + }, + Object { + "attributes": Object { + "file": "equalizer/eq-buttons.png", + "gammagroup": "Buttons", + "h": "13", + "id": "eq.slider.horizontal.button.pressed", + "w": "17", + "x": "18", + "y": "36", + }, + "name": "bitmap", + "type": "element", + }, + ], + "name": "elements", + "type": "element", + }, + Object { + "comment": "groupdef id=\\"eq.content.group\\" name=\\"Equalizer\\" inherit_group=\\"wasabi.panel\\"", + "type": "comment", + }, + Object { + "attributes": Object { + "id": "eq.content.group", + "inherit_group": "wasabi.panel", + }, + "children": Array [ + Object { + "comment": "layer x=\\"0\\" y=\\"0\\" w=\\"0\\" h=\\"0\\" relatw=\\"1\\" relath=\\"1\\"/", + "type": "comment", + }, + Object { + "attributes": Object { + "id": "placeholder", + "image": "eq.placeholder", + "x": "9", + "y": "3", + }, + "name": "layer", + "type": "element", + }, + Object { + "comment": " The spline display ", + "type": "comment", + }, + Object { + "attributes": Object { + "colorbottom": "80,40,60", + "colormiddle": "255,192,255", + "colorpreamp": "128,128,128", + "colortop": "60,80,40", + "gamma": "192", + "h": "15", + "id": "spline", + "w": "115", + "x": "80", + "y": "5", + }, + "name": "eqvis", + "type": "element", + }, + Object { + "comment": " Switches ", + "type": "comment", + }, + Object { + "attributes": Object { + "action": "EQ_TOGGLE", + "activeImage": "eq.switch.on.enabled", + "downImage": "eq.switch.on.pressed", + "id": "toggle", + "image": "eq.switch.on.disabled", + "tooltip": "Toggle Equalizer On/Off", + "x": "10", + "y": "7", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "EQ_AUTO", + "activeImage": "eq.switch.auto.enabled", + "downImage": "eq.switch.auto.pressed", + "id": "auto", + "image": "eq.switch.auto.disabled", + "tooltip": "Toggle Equalizer Automatic Processing", + "x": "37", + "y": "7", + }, + "name": "button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "MENU", + "downImage": "eq.button.presets.pressed", + "id": "presets", + "image": "eq.button.presets", + "param": "presets", + "tooltip": "Manage Equalizer Presets", + "x": "211", + "y": "7", + }, + "name": "button", + "type": "element", + }, + Object { + "comment": " Sliders ", + "type": "comment", + }, + Object { + "attributes": Object { + "action": "EQ_PREAMP", + "downThumb": "eq.slider.button.pressed", + "h": "64", + "id": "preamp", + "orientation": "vertical", + "thumb": "eq.slider.button", + "w": "18", + "x": "13", + "y": "24", + }, + "name": "slider", + "type": "element", + }, + Object { + "attributes": Object { + "action": "EQ_BAND", + "downThumb": "eq.slider.button.pressed", + "h": "64", + "id": "eq1", + "orientation": "vertical", + "param": "1", + "thumb": "eq.slider.button", + "w": "18", + "x": "71", + "y": "24", + }, + "name": "slider", + "type": "element", + }, + Object { + "attributes": Object { + "action": "EQ_BAND", + "downThumb": "eq.slider.button.pressed", + "h": "64", + "id": "eq2", + "orientation": "vertical", + "param": "2", + "thumb": "eq.slider.button", + "w": "18", + "x": "89", + "y": "24", + }, + "name": "slider", + "type": "element", + }, + Object { + "attributes": Object { + "action": "EQ_BAND", + "downThumb": "eq.slider.button.pressed", + "h": "64", + "id": "eq3", + "orientation": "vertical", + "param": "3", + "thumb": "eq.slider.button", + "w": "18", + "x": "107", + "y": "24", + }, + "name": "slider", + "type": "element", + }, + Object { + "attributes": Object { + "action": "EQ_BAND", + "downThumb": "eq.slider.button.pressed", + "h": "64", + "id": "eq4", + "orientation": "vertical", + "param": "4", + "thumb": "eq.slider.button", + "w": "18", + "x": "125", + "y": "24", + }, + "name": "slider", + "type": "element", + }, + Object { + "attributes": Object { + "action": "EQ_BAND", + "downThumb": "eq.slider.button.pressed", + "h": "64", + "id": "eq5", + "orientation": "vertical", + "param": "5", + "thumb": "eq.slider.button", + "w": "18", + "x": "143", + "y": "24", + }, + "name": "slider", + "type": "element", + }, + Object { + "attributes": Object { + "action": "EQ_BAND", + "downThumb": "eq.slider.button.pressed", + "h": "64", + "id": "eq6", + "orientation": "vertical", + "param": "6", + "thumb": "eq.slider.button", + "w": "18", + "x": "161", + "y": "24", + }, + "name": "slider", + "type": "element", + }, + Object { + "attributes": Object { + "action": "EQ_BAND", + "downThumb": "eq.slider.button.pressed", + "h": "64", + "id": "eq7", + "orientation": "vertical", + "param": "7", + "thumb": "eq.slider.button", + "w": "18", + "x": "179", + "y": "24", + }, + "name": "slider", + "type": "element", + }, + Object { + "attributes": Object { + "action": "EQ_BAND", + "downThumb": "eq.slider.button.pressed", + "h": "64", + "id": "eq8", + "orientation": "vertical", + "param": "8", + "thumb": "eq.slider.button", + "w": "18", + "x": "197", + "y": "24", + }, + "name": "slider", + "type": "element", + }, + Object { + "attributes": Object { + "action": "EQ_BAND", + "downThumb": "eq.slider.button.pressed", + "h": "64", + "id": "eq9", + "orientation": "vertical", + "param": "9", + "thumb": "eq.slider.button", + "w": "18", + "x": "215", + "y": "24", + }, + "name": "slider", + "type": "element", + }, + Object { + "attributes": Object { + "action": "EQ_BAND", + "downThumb": "eq.slider.button.pressed", + "h": "64", + "id": "eq10", + "orientation": "vertical", + "param": "10", + "thumb": "eq.slider.button", + "w": "18", + "x": "233", + "y": "24", + }, + "name": "slider", + "type": "element", + }, + Object { + "comment": " Balance and Crossfade ", + "type": "comment", + }, + Object { + "attributes": Object { + "action": "PAN", + "downThumb": "eq.slider.horizontal.button.pressed", + "h": "13", + "id": "Balance", + "thumb": "eq.slider.horizontal.button", + "tooltip": "Balance", + "w": "79", + "x": "39", + "y": "105", + }, + "name": "slider", + "type": "element", + }, + Object { + "attributes": Object { + "cfgattrib": "{F1239F09-8CC6-4081-8519-C2AE99FCB14C};Crossfade time", + "downThumb": "eq.slider.horizontal.button.pressed", + "h": "13", + "high": "20", + "id": "Crossfade", + "thumb": "eq.slider.horizontal.button", + "tooltip": "Crossfade Fade Duration", + "w": "79", + "x": "148", + "y": "105", + }, + "name": "slider", + "type": "element", + }, + Object { + "comment": " Scaler ", + "type": "comment", + }, + Object { + "attributes": Object { + "id": "Scaler", + "image": "wasabi.frame.resizer", + "relatx": "1", + "relaty": "1", + "scale": "bottomright", + "tooltip": "Drag to scale", + "x": "-15", + "y": "-15", + }, + "name": "layer", + "type": "element", + }, + ], + "name": "groupdef", + "type": "element", + }, + Object { + "attributes": Object { + "default_visible": "0", + "default_x": "365", + "default_y": "250", + "id": "eq", + "name": "Equalizer", + }, + "children": Array [ + Object { + "attributes": Object { + "id": "normal", + "maximum_h": "145", + "maximum_w": "275", + "minimum_h": "145", + "minimum_w": "275", + }, + "children": Array [ + Object { + "attributes": Object { + "content": "eq.content.group", + "h": "0", + "relath": "1", + "relatw": "1", + "w": "0", + "x": "0", + "y": "0", + }, + "name": "Wasabi:StandardFrame:NoStatus", + "type": "element", + }, + ], + "name": "layout", + "type": "element", + }, + ], + "name": "container", + "type": "element", + }, + ], + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/color-presets.xml", + }, + "children": Array [ + Object { + "comment": " Gamma sets ", + "type": "comment", + }, + Object { + "attributes": Object { + "id": "Default", + }, + "children": Array [ + Object { + "attributes": Object { + "id": "CornerAmp", + "value": "-100,200,750", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Backgrounds", + "value": "-400,-400,100", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Buttons", + "value": "400,200,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Thinger icons", + "value": "2016,4072,2016", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Menus", + "value": "1000,1000,1000", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Titlebars", + "value": "2048,1024,-1024", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "boost": "1", + "id": "Playback Status Symbols", + "value": "1000,3500,1000", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Titlebar Font", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Button Fonts", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Display Fonts", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Text Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Tree Color", + "value": "1000,2000,1000", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Display Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Scrollbar Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Scrollbar Buttons", + "value": "400,200,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Text", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + ], + "name": "gammaset", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Blue", + }, + "children": Array [ + Object { + "attributes": Object { + "id": "CornerAmp", + "value": "-750,-500,1500", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Backgrounds", + "value": "0,300,1700", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Buttons", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Thinger icons", + "value": "2000,2000,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Menus", + "value": "0,300,1700", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Titlebars", + "value": "2048,1024,-1024", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "boost": "1", + "id": "Playback Status Symbols", + "value": "2000,2000,-500", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Titlebar Font", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Button Fonts", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Display Fonts", + "value": "2000,2000,-500", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Text Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Tree Color", + "value": "2000,2000,-500", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Display Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Scrollbar Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Scrollbar Buttons", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Text", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + ], + "name": "gammaset", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Green", + }, + "children": Array [ + Object { + "attributes": Object { + "id": "CornerAmp", + "value": "-750,750,-1000", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Backgrounds", + "value": "300,1700,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Buttons", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Thinger icons", + "value": "300,1700,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Menus", + "value": "300,1700,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Titlebars", + "value": "2048,1024,-1024", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "boost": "1", + "id": "Playback Status Symbols", + "value": "300,1700,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Titlebar Font", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Button Fonts", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Display Fonts", + "value": "300,1700,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Text Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Tree Color", + "value": "300,1700,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Display Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Scrollbar Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Scrollbar Buttons", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Text", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + ], + "name": "gammaset", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Grey", + }, + "children": Array [ + Object { + "attributes": Object { + "id": "CornerAmp", + "value": "-650,-700,-200", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Buttons", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Thinger icons", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Menus", + "value": "1000,1000,1000", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Titlebars", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "boost": "1", + "id": "Playback Status Symbols", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Titlebar Font", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Button Fonts", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Display Fonts", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Text Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Tree Color", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Display Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Scrollbar Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Scrollbar Buttons", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Text", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + ], + "name": "gammaset", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Red", + }, + "children": Array [ + Object { + "attributes": Object { + "id": "CornerAmp", + "value": "1000,-750,-1000", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Backgrounds", + "value": "1700,300,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Buttons", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Thinger icons", + "value": "1700,300,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Menus", + "value": "1700,300,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Titlebars", + "value": "2048,1024,-1024", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "boost": "1", + "id": "Playback Status Symbols", + "value": "1700,300,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Titlebar Font", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Button Fonts", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Display Fonts", + "value": "1700,300,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Text Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Tree Color", + "value": "1700,300,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Display Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Scrollbar Backgrounds", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Scrollbar Buttons", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + Object { + "attributes": Object { + "id": "Text", + "value": "0,0,0", + }, + "name": "gammagroup", + "type": "element", + }, + ], + "name": "gammaset", + "type": "element", + }, + ], + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/color-themes.xml", + }, + "children": Array [ + Object { + "attributes": Object { + "default_visible": "0", + "id": "colorthemes", + "name": "Color Themes", + }, + "children": Array [ + Object { + "attributes": Object { + "id": "themes", + "name": "Themes", + }, + "children": Array [ + Object { + "attributes": Object { + "h": "-24", + "id": "color.list", + "nocolheader": "1", + "relath": "1", + "relatw": "1", + "w": "-4", + "x": "2", + "y": "2", + }, + "name": "ColorThemes:List", + "type": "element", + }, + Object { + "attributes": Object { + "action": "colorthemes_switch", + "action_target": "color.list", + "h": "19", + "id": "Switch", + "relatw": "%", + "relaty": "1", + "text": "Switch", + "w": "50", + "x": "0", + "y": "-20", + }, + "name": "Wasabi:Button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "colorthemes_previous", + "action_target": "color.list", + "h": "19", + "id": "Previous", + "relatw": "%", + "relatx": "%", + "relaty": "1", + "text": "Previous", + "w": "25", + "x": "50", + "y": "-20", + }, + "name": "Wasabi:Button", + "type": "element", + }, + Object { + "attributes": Object { + "action": "colorthemes_next", + "action_target": "color.list", + "h": "19", + "id": "Next", + "relatw": "%", + "relatx": "%", + "relaty": "1", + "text": "Next", + "w": "25", + "x": "75", + "y": "-20", + }, + "name": "Wasabi:Button", + "type": "element", + }, + ], + "name": "groupdef", + "type": "element", + }, + Object { + "attributes": Object { + "id": "normal", + "maximum_h": "138", + "maximum_w": "275", + "minimum_h": "138", + "minimum_w": "275", + }, + "children": Array [ + Object { + "attributes": Object { + "content": "themes", + "h": "0", + "relath": "1", + "relatw": "1", + "w": "0", + "x": "0", + "y": "0", + }, + "name": "Wasabi:StandardFrame:NoStatus", + "type": "element", + }, + ], + "name": "layout", + "type": "element", + }, + ], + "name": "container", + "type": "element", + }, + ], + "name": "include", + "type": "element", + }, + Object { + "comment": " CornerAmp has never had the thinger but you can add it if you like: + + ", + "type": "comment", + }, + ], + "name": "WasabiXML", + "type": "element", + }, + ], + "declaration": Object { + "attributes": Object { + "encoding": "UTF-8", + "standalone": "yes", + "version": "1.0", + }, + }, +} +`; + +exports[`readXml gets a file independent of case 1`] = ` +Object { + "children": Array [ + Object { + "attributes": Object { + "version": "1.35", + }, + "children": Array [ + Object { + "children": Array [ + Object { + "children": Array [ + Object { + "text": "1.0", + "type": "text", + }, + ], + "name": "version", + "type": "element", + }, + Object { + "children": Array [ + Object { + "text": "CornerAmp Redux", + "type": "text", + }, + ], + "name": "name", + "type": "element", + }, + Object { + "children": Array [ + Object { + "text": "9 of Nine, Evil Pumpkin, RazorZero", + "type": "text", + }, + ], + "name": "author", + "type": "element", + }, + Object { + "children": Array [ + Object { + "text": "Updated for Winamp 5 by Ariszló", + "type": "text", + }, + ], + "name": "comment", + "type": "element", + }, + Object { + "children": Array [ + Object { + "text": "ariszlo@gmail.com", + "type": "text", + }, + ], + "name": "email", + "type": "element", + }, + Object { + "children": Array [ + Object { + "text": "http://ariszlo.deviantart.com", + "type": "text", + }, + ], + "name": "homepage", + "type": "element", + }, + Object { + "children": Array [ + Object { + "text": "skinshot.png", + "type": "text", + }, + ], + "name": "screenshot", + "type": "element", + }, + ], + "name": "skininfo", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/system-colors.xml", + }, + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/standardframe.xml", + }, + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/player.xml", + }, + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/pledit.xml", + }, + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/video.xml", + }, + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/eq.xml", + }, + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/color-presets.xml", + }, + "name": "include", + "type": "element", + }, + Object { + "attributes": Object { + "file": "xml/color-themes.xml", + }, + "name": "include", + "type": "element", + }, + Object { + "comment": " CornerAmp has never had the thinger but you can add it if you like: + + ", + "type": "comment", + }, + ], + "name": "WasabiXML", + "type": "element", + }, + ], + "declaration": Object { + "attributes": Object { + "encoding": "UTF-8", + "standalone": "yes", + "version": "1.0", + }, + }, +} +`; diff --git a/experiments/modern/src/utils.js b/experiments/modern/src/utils.js new file mode 100644 index 00000000..bd4a8520 --- /dev/null +++ b/experiments/modern/src/utils.js @@ -0,0 +1,41 @@ +import { xml2js } from "xml-js"; + +export function getCaseInsensitveFile(zip, filename) { + // TODO: Escape `file` for rejex characters + return zip.file(new RegExp(filename, "i"))[0]; +} + +// Read a +export async function readXml(zip, file) { + // TODO: Handle case where file is not found + const text = await getCaseInsensitveFile(zip, file).async("text"); + return xml2js(text, { compact: false, elementsKey: "children" }); +} + +// Transform an xml tree structure by mapping over each node breadth first +// Parents are mapped before their children +// Children are mapped in parallel +export async function asyncTreeMap(xml, mapper) { + const mapped = await mapper(xml); + if (mapped.children == null) { + return mapped; + } + const promises = mapped.children.map(child => { + return asyncTreeMap(child, mapper); + }); + const children = await Promise.all(promises); + + return { ...mapped, children }; +} + +export async function inlineIncludes(xml, zip) { + return asyncTreeMap(xml, async node => { + if (node.name === "include") { + // TODO: Normalize file names so that they hit the same cache + // TODO: Ensure this node does not already have children for some reason + const { children } = await readXml(zip, node.attributes.file); + return { ...node, children }; + } + return node; + }); +} diff --git a/experiments/modern/src/utils.test.js b/experiments/modern/src/utils.test.js new file mode 100644 index 00000000..679a2a3d --- /dev/null +++ b/experiments/modern/src/utils.test.js @@ -0,0 +1,67 @@ +import * as Utils from "./utils"; +import JSZip from "jszip"; +import { promises as fsPromises } from "fs"; +import path from "path"; + +async function getSkinZip() { + const skinBuffer = await fsPromises.readFile( + path.join(__dirname, "../public/skins/CornerAmp_Redux.zip") + ); + return JSZip.loadAsync(skinBuffer); +} + +describe("getCaseInsensitiveFile", () => { + it("gets a file independent of case", async () => { + const zip = await getSkinZip(); + expect(Utils.getCaseInsensitveFile(zip, "SkIn.XmL")).not.toEqual(null); + }); +}); + +describe("readXml", () => { + it("gets a file independent of case", async () => { + const zip = await getSkinZip(); + const xml = await Utils.readXml(zip, "SkIn.XmL"); + expect(xml).toMatchSnapshot(); + }); +}); + +describe("asyncTreeMao", () => { + it("runs parents before children", async () => { + const callNodeNames = new Set(); + const mapper = node => { + callNodeNames.add(node.name); + if (node.name === "root.2") { + const children = [{ name: "root.2.1" }]; + return { ...node, children }; + } + return node; + }; + + const structure = { + name: "root", + children: [{ name: "root.1" }, { name: "root.2" }, { name: "root.3" }], + }; + + const mappedStructure = await Utils.asyncTreeMap(structure, mapper); + expect(callNodeNames).toEqual( + new Set(["root", "root.1", "root.2", "root.2.1", "root.3"]) + ); + expect(mappedStructure).toEqual({ + name: "root", + children: [ + { name: "root.1" }, + { name: "root.2", children: [{ name: "root.2.1" }] }, + { name: "root.3" }, + ], + }); + }); +}); + +describe("inlineIncludes", () => { + it("inlines the contents of included files as children of the include node", async () => { + const zip = await getSkinZip(); + const xml = await Utils.readXml(zip, "SkIn.XmL"); + const resolvedXml = await Utils.inlineIncludes(xml, zip); + expect(resolvedXml).toMatchSnapshot(); + }); +});