server

Clone or download

Refactored config, added sound-on-action-clicked properties

Modified Files

/*
/*
Config.java
Config.java
Contributor(s) : Debayan Sutradhar (@rnayabed)
Contributor(s) : Debayan Sutradhar (@rnayabed)
handler for config.xml
handler for config.xml
*/
*/
package com.stream_pi.server.io;
package com.stream_pi.server.io;
import java.awt.*;
import java.awt.*;
import java.io.File;
import java.io.File;
import java.lang.reflect.Array;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Objects;
import java.util.Objects;
import java.util.logging.Logger;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamResult;
import com.stream_pi.server.Main;
import com.stream_pi.server.Main;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.iohelper.IOHelper;
import com.stream_pi.util.iohelper.IOHelper;
import com.stream_pi.util.xmlconfighelper.XMLConfigHelper;
import com.stream_pi.util.xmlconfighelper.XMLConfigHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Element;
public class Config
public class Config
{
{
private static Config instance = null;
private static Config instance = null;
private final File configFile;
private final File configFile;
private Document document;
private Document document;
private Config() throws SevereException {
private Config() throws SevereException {
try {
try {
configFile = new File(ServerInfo.getInstance().getPrePath()+"config.xml");
configFile = new File(ServerInfo.getInstance().getPrePath()+"config.xml");
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
document = docBuilder.parse(configFile);
document = docBuilder.parse(configFile);
} catch (Exception e) {
} catch (Exception e) {
e.printStackTrace();
e.printStackTrace();
throw new SevereException("Config", "Unable to read config.xml\n"+e.getMessage());
throw new SevereException("Config", "Unable to read config.xml\n"+e.getMessage());
}
}
}
}
public static synchronized Config getInstance() throws SevereException
public static synchronized Config getInstance() throws SevereException
{
{
if(instance == null)
if(instance == null)
instance = new Config();
instance = new Config();
return instance;
return instance;
}
}
public static void nullify()
public static void nullify()
{
{
instance = null;
instance = null;
}
}
Logger logger = Logger.getLogger(Config.class.getName());
Logger logger = Logger.getLogger(Config.class.getName());
public void save() throws SevereException {
public void save() throws SevereException {
try {
try {
logger.info("Saving config ...");
logger.info("Saving config ...");
Transformer transformer = TransformerFactory.newInstance().newTransformer();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
Result output = new StreamResult(configFile);
Result output = new StreamResult(configFile);
Source input = new DOMSource(document);
Source input = new DOMSource(document);
transformer.transform(input, output);
transformer.transform(input, output);
logger.info("... Done!");
logger.info("... Done!");
} catch (Exception e) {
} catch (Exception e) {
throw new SevereException("Config", "unable to save config.xml");
throw new SevereException("Config", "unable to save config.xml");
}
}
}
}
//Getters
//Getters
//comms
//comms
private Element getCommsElement()
private Element getCommsElement()
{
{
return (Element) document.getElementsByTagName("comms").item(0);
return (Element) document.getElementsByTagName("comms").item(0);
}
}
public String getServerName()
public String getServerName()
{
{
return XMLConfigHelper.getStringProperty(getCommsElement(), "name",
return XMLConfigHelper.getStringProperty(getCommsElement(), "name",
getDefaultServerName(), false, true, document, configFile);
getDefaultServerName(), false, true, document, configFile);
}
}
public int getPort()
public int getPort()
{
{
return XMLConfigHelper.getIntProperty(getCommsElement(), "port",
return XMLConfigHelper.getIntProperty(getCommsElement(), "port",
getDefaultPort(), false, true, document, configFile);
getDefaultPort(), false, true, document, configFile);
}
}
//default getters
//default getters
public String getDefaultServerName()
public String getDefaultServerName()
{
{
return "Stream-Pi Server";
return "Stream-Pi Server";
}
}
public static int getDefaultPort()
public static int getDefaultPort()
{
{
return 6504;
return 6504;
}
}
private Element getServerElement()
{
return (Element) document.getElementsByTagName("server").item(0);
}
//server
//server
private Element getDividerPositionsElement()
private Element getDividerPositionsElement()
{
{
return (Element) getServerElement().getElementsByTagName("divider-positions").item(0);
return (Element) document.getElementsByTagName("divider-positions").item(0);
}
}
public String getDefaultLeftDividerPositions()
public String getDefaultLeftDividerPositions()
{
{
return "3.0";
return "3.0";
}
}
public double[] getLeftDividerPositions()
public double[] getLeftDividerPositions()
{
{
String[] strArr = XMLConfigHelper.getStringProperty(getDividerPositionsElement(), "left",
String[] strArr = XMLConfigHelper.getStringProperty(getDividerPositionsElement(), "left",
getDefaultLeftDividerPositions(), false, true, document, configFile)
getDefaultLeftDividerPositions(), false, true, document, configFile)
.split(",");
.split(",");
double[] r = new double[strArr.length];
double[] r = new double[strArr.length];
for (int i = 0;i<strArr.length;i++)
for (int i = 0;i<strArr.length;i++)
{
{
r[i] = Double.parseDouble(strArr[i]);
r[i] = Double.parseDouble(strArr[i]);
}
}
return r;
return r;
}
}
public void setLeftDividerPositions(double[] position)
public void setLeftDividerPositions(double[] position)
{
{
String r = Arrays.toString(position);
String r = Arrays.toString(position);
getDividerPositionsElement().getElementsByTagName("left").item(0).setTextContent(r.substring(1, r.length()-1));
getDividerPositionsElement().getElementsByTagName("left").item(0).setTextContent(r.substring(1, r.length()-1));
}
}
public String getDefaultRightDividerPositions()
public String getDefaultRightDividerPositions()
{
{
return "3.0";
return "3.0";
}
}
public double[] getRightDividerPositions()
public double[] getRightDividerPositions()
{
{
String[] strArr = XMLConfigHelper.getStringProperty(getDividerPositionsElement(), "right",
String[] strArr = XMLConfigHelper.getStringProperty(getDividerPositionsElement(), "right",
getDefaultRightDividerPositions(), false, true, document, configFile)
getDefaultRightDividerPositions(), false, true, document, configFile)
.split(",");
.split(",");
double[] r = new double[strArr.length];
double[] r = new double[strArr.length];
for (int i = 0;i<strArr.length;i++)
for (int i = 0;i<strArr.length;i++)
{
{
r[i] = Double.parseDouble(strArr[i]);
r[i] = Double.parseDouble(strArr[i]);
}
}
return r;
return r;
}
}
public void setRightDividerPositions(double[] position)
public void setRightDividerPositions(double[] position)
{
{
String r = Arrays.toString(position);
String r = Arrays.toString(position);
getDividerPositionsElement().getElementsByTagName("right").item(0).setTextContent(r.substring(1, r.length()-1));
getDividerPositionsElement().getElementsByTagName("right").item(0).setTextContent(r.substring(1, r.length()-1));
}
}
private Element getActionGridElement()
private Element getActionGridElement()
{
{
return (Element) getServerElement().getElementsByTagName("action-grid").item(0);
return (Element) document.getElementsByTagName("action-grid").item(0);
}
}
public int getActionGridActionGap()
public int getActionGridActionGap()
{
{
return XMLConfigHelper.getIntProperty(getActionGridElement(), "gap",
return XMLConfigHelper.getIntProperty(getActionGridElement(), "gap",
getDefaultActionGridActionGap(), false, true, document, configFile);
getDefaultActionGridActionGap(), false, true, document, configFile);
}
}
public int getActionGridActionSize()
public int getActionGridActionSize()
{
{
return XMLConfigHelper.getIntProperty(getActionGridElement(), "size",
return XMLConfigHelper.getIntProperty(getActionGridElement(), "size",
getDefaultActionGridSize(), false, true, document, configFile);
getDefaultActionGridSize(), false, true, document, configFile);
}
}
public String getCurrentThemeFullName()
public String getCurrentThemeFullName()
{
{
return XMLConfigHelper.getStringProperty(getServerElement(), "current-theme-full-name",
return XMLConfigHelper.getStringProperty((Element) document, "current-theme-full-name",
getDefaultCurrentThemeFullName(), false, true, document, configFile);
getDefaultCurrentThemeFullName(), false, true, document, configFile);
}
}
public String getThemesPath()
public String getThemesPath()
{
{
return XMLConfigHelper.getStringProperty(getServerElement(), "themes-path",
return XMLConfigHelper.getStringProperty((Element) document, "themes-path",
getDefaultThemesPath(), false, true, document, configFile);
getDefaultThemesPath(), false, true, document, configFile);
}
}
public String getPluginsPath()
public String getPluginsPath()
{
{
return XMLConfigHelper.getStringProperty(getServerElement(), "plugins-path",
return XMLConfigHelper.getStringProperty((Element) document, "plugins-path",
getDefaultPluginsPath(), false, true, document, configFile);
getDefaultPluginsPath(), false, true, document, configFile);
}
}
//default getters
//default getters
public String getDefaultCurrentThemeFullName()
public String getDefaultCurrentThemeFullName()
{
{
return "com.stream_pi.defaultlight";
return "com.stream_pi.defaultlight";
}
}
public String getDefaultThemesPath()
public String getDefaultThemesPath()
{
{
return ServerInfo.getInstance().getPrePath()+"Themes/";
return ServerInfo.getInstance().getPrePath()+"Themes/";
}
}
public String getDefaultPluginsPath()
public String getDefaultPluginsPath()
{
{
return ServerInfo.getInstance().getPrePath()+"Plugins/";
return ServerInfo.getInstance().getPrePath()+"Plugins/";
}
}
//server > startup-window-size
//server > startup-window-size
private Element getStartupWindowSizeElement()
private Element getStartupWindowSizeElement()
{
{
return (Element) getServerElement().getElementsByTagName("startup-window-size").item(0);
return (Element) document.getElementsByTagName("startup-window-size").item(0);
}
}
public double getStartupWindowWidth()
public double getStartupWindowWidth()
{
{
return XMLConfigHelper.getDoubleProperty(getStartupWindowSizeElement(), "width",
return XMLConfigHelper.getDoubleProperty(getStartupWindowSizeElement(), "width",
getDefaultStartupWindowWidth(), false, true, document, configFile);
getDefaultStartupWindowWidth(), false, true, document, configFile);
}
}
public double getStartupWindowHeight()
public double getStartupWindowHeight()
{
{
return XMLConfigHelper.getDoubleProperty(getStartupWindowSizeElement(), "height",
return XMLConfigHelper.getDoubleProperty(getStartupWindowSizeElement(), "height",
getDefaultStartupWindowHeight(), false, true, document, configFile);
getDefaultStartupWindowHeight(), false, true, document, configFile);
}
}
//default getters
//default getters
public int getDefaultStartupWindowWidth()
public int getDefaultStartupWindowWidth()
{
{
return 1024;
return 1024;
}
}
public int getDefaultStartupWindowHeight()
public int getDefaultStartupWindowHeight()
{
{
return 768;
return 768;
}
}
//sound on action clicked
private Element getSoundOnActionClickedElement()
{
return (Element) document.getElementsByTagName("sound-on-action-clicked").item(0);
}
//others
//others
private Element getOthersElement()
private Element getOthersElement()
{
{
return (Element) document.getElementsByTagName("others").item(0);
return (Element) document.getElementsByTagName("others").item(0);
}
}
public boolean getStartOnBoot()
public boolean getStartOnBoot()
{
{
return XMLConfigHelper.getBooleanProperty(getOthersElement(), "start-on-boot",
return XMLConfigHelper.getBooleanProperty(getOthersElement(), "start-on-boot",
getDefaultStartOnBoot(), false, true, document, configFile);
getDefaultStartOnBoot(), false, true, document, configFile);
}
}
public boolean getMinimiseToSystemTrayOnClose()
public boolean getMinimiseToSystemTrayOnClose()
{
{
return XMLConfigHelper.getBooleanProperty(getOthersElement(), "minimize-to-tray-on-close",
return XMLConfigHelper.getBooleanProperty(getOthersElement(), "minimize-to-tray-on-close",
getDefaultMinimiseToSystemTrayOnClose(), false, true, document, configFile);
getDefaultMinimiseToSystemTrayOnClose(), false, true, document, configFile);
}
}
public boolean isFirstTimeUse()
public boolean isFirstTimeUse()
{
{
return XMLConfigHelper.getBooleanProperty(getOthersElement(), "first-time-use", true, false, true, document, configFile);
return XMLConfigHelper.getBooleanProperty(getOthersElement(), "first-time-use", true, false, true, document, configFile);
}
}
public boolean isAllowDonatePopup()
public boolean isAllowDonatePopup()
{
{
return XMLConfigHelper.getBooleanProperty(getOthersElement(), "allow-donate-popup", true, false, true, document, configFile);
return XMLConfigHelper.getBooleanProperty(getOthersElement(), "allow-donate-popup", true, false, true, document, configFile);
}
}
//default getters
//default getters
public boolean getDefaultStartOnBoot()
public boolean getDefaultStartOnBoot()
{
{
return false;
return false;
}
}
public boolean getDefaultMinimiseToSystemTrayOnClose()
public boolean getDefaultMinimiseToSystemTrayOnClose()
{
{
return true;
return true;
}
}
//Setters
//Setters
//comms
//comms
public void setServerName(String name)
public void setServerName(String name)
{
{
getCommsElement().getElementsByTagName("name").item(0).setTextContent(name);
getCommsElement().getElementsByTagName("name").item(0).setTextContent(name);
}
}
public void setServerPort(int port)
public void setServerPort(int port)
{
{
getCommsElement().getElementsByTagName("port").item(0).setTextContent(port+"");
getCommsElement().getElementsByTagName("port").item(0).setTextContent(port+"");
}
}
//server
//server
public int getDefaultActionGridActionGap()
public int getDefaultActionGridActionGap()
{
{
return 5;
return 5;
}
}
public int getDefaultActionGridSize()
public int getDefaultActionGridSize()
{
{
return 100;
return 100;
}
}
public void setActionGridSize(int size)
public void setActionGridSize(int size)
{
{
getActionGridElement().getElementsByTagName("size").item(0).setTextContent(size+"");
getActionGridElement().getElementsByTagName("size").item(0).setTextContent(size+"");
}
}
public void setActionGridGap(int size)
public void setActionGridGap(int size)
{
{
getActionGridElement().getElementsByTagName("gap").item(0).setTextContent(size+"");
getActionGridElement().getElementsByTagName("gap").item(0).setTextContent(size+"");
}
}
public void setPluginsPath(String path)
public void setPluginsPath(String path)
{
{
getServerElement().getElementsByTagName("plugins-path").item(0).setTextContent(path);
document.getElementsByTagName("plugins-path").item(0).setTextContent(path);
}
}
public void setThemesPath(String path)
public void setThemesPath(String path)
{
{
getServerElement().getElementsByTagName("themes-path").item(0).setTextContent(path);
document.getElementsByTagName("themes-path").item(0).setTextContent(path);
}
}
public void setCurrentThemeFullName(String themeName)
public void setCurrentThemeFullName(String themeName)
{
{
getServerElement().getElementsByTagName("current-theme-full-name").item(0).setTextContent(themeName);
document.getElementsByTagName("current-theme-full-name").item(0).setTextContent(themeName);
}
}
//server > startup-window-size
//server > startup-window-size
public void setStartupWindowSize(double width, double height)
public void setStartupWindowSize(double width, double height)
{
{
setStartupWindowWidth(width);
setStartupWindowWidth(width);
setStartupWindowHeight(height);
setStartupWindowHeight(height);
}
}
public void setStartupWindowWidth(double width)
public void setStartupWindowWidth(double width)
{
{
getStartupWindowSizeElement().getElementsByTagName("width").item(0).setTextContent(width+"");
getStartupWindowSizeElement().getElementsByTagName("width").item(0).setTextContent(width+"");
}
}
public void setStartupWindowHeight(double height)
public void setStartupWindowHeight(double height)
{
{
getStartupWindowSizeElement().getElementsByTagName("height").item(0).setTextContent(height+"");
getStartupWindowSizeElement().getElementsByTagName("height").item(0).setTextContent(height+"");
}
}
//others
//others
public void setStartupOnBoot(boolean value)
public void setStartupOnBoot(boolean value)
{
{
getOthersElement().getElementsByTagName("start-on-boot").item(0).setTextContent(value+"");
getOthersElement().getElementsByTagName("start-on-boot").item(0).setTextContent(value+"");
}
}
public void setMinimiseToSystemTrayOnClose(boolean value)
public void setMinimiseToSystemTrayOnClose(boolean value)
{
{
getOthersElement().getElementsByTagName("minimize-to-tray-on-close").item(0).setTextContent(value+"");
getOthersElement().getElementsByTagName("minimize-to-tray-on-close").item(0).setTextContent(value+"");
}
}
public void setFirstTimeUse(boolean value)
public void setFirstTimeUse(boolean value)
{
{
getOthersElement().getElementsByTagName("first-time-use").item(0).setTextContent(value+"");
getOthersElement().getElementsByTagName("first-time-use").item(0).setTextContent(value+"");
}
}
public void setAllowDonatePopup(boolean value)
public void setAllowDonatePopup(boolean value)
{
{
getOthersElement().getElementsByTagName("allow-donate-popup").item(0).setTextContent(value+"");
getOthersElement().getElementsByTagName("allow-donate-popup").item(0).setTextContent(value+"");
}
}
public static void unzipToDefaultPrePath() throws Exception
public static void unzipToDefaultPrePath() throws Exception
{
{
IOHelper.unzip(Objects.requireNonNull(Main.class.getResourceAsStream("Default.zip")), ServerInfo.getInstance().getPrePath());
IOHelper.unzip(Objects.requireNonNull(Main.class.getResourceAsStream("Default.zip")), ServerInfo.getInstance().getPrePath());
Config config = Config.getInstance();
Config config = Config.getInstance();
config.setThemesPath(config.getDefaultThemesPath());
config.setThemesPath(config.getDefaultThemesPath());
config.setPluginsPath(config.getDefaultPluginsPath());
config.setPluginsPath(config.getDefaultPluginsPath());
if(SystemTray.isSupported())
if(SystemTray.isSupported())
{
{
config.setMinimiseToSystemTrayOnClose(true);
config.setMinimiseToSystemTrayOnClose(true);
}
}
config.save();
config.save();
}
}
public void setShowAlertsPopup(boolean value)
public void setShowAlertsPopup(boolean value)
{
{
getOthersElement().getElementsByTagName("alerts-popup").item(0).setTextContent(value+"");
getOthersElement().getElementsByTagName("alerts-popup").item(0).setTextContent(value+"");
}
}
public boolean isShowAlertsPopup()
public boolean isShowAlertsPopup()
{
{
return XMLConfigHelper.getBooleanProperty(getOthersElement(), "alerts-popup", getDefaultIsShowAlertsPopup(), false, true, document, configFile);
return XMLConfigHelper.getBooleanProperty(getOthersElement(), "alerts-popup", getDefaultIsShowAlertsPopup(), false, true, document, configFile);
}
}
public boolean getDefaultIsShowAlertsPopup()
public boolean getDefaultIsShowAlertsPopup()
{
{
return true;
return true;
}
}
public void setSoundOnActionClickedStatus(boolean value)
{
getSoundOnActionClickedElement().getElementsByTagName("status").item(0).setTextContent(value+"");
}
public boolean getSoundOnActionClickedStatus()
{
return XMLConfigHelper.getBooleanProperty(getSoundOnActionClickedElement(), "status", getDefaultSoundOnActionClickedStatus(), false, true, document, configFile);
}
public boolean getDefaultSoundOnActionClickedStatus()
{
return false;
}
public void setSoundOnActionClickedFilePath(String value)
{
getSoundOnActionClickedElement().getElementsByTagName("file-path").item(0).setTextContent(value);
}
public String getSoundOnActionClickedFilePath()
{
return XMLConfigHelper.getStringProperty(getSoundOnActionClickedElement(), "file-path", getDefaultSoundOnActionClickedFilePath(), false, true, document, configFile);
}
public String getDefaultSoundOnActionClickedFilePath()
{
return null; //To be replaced with a real default beep sound later.
}
}
}
PKԽR 
PKԽR 
config.xmluSMo0W k IGr۞+{^y!ll;&@GN޼<ol^'ye)-<MiP;^~#&>p#FRcG@kZձ$}698{gό2?PONL fz8^n/s&@`9%H<[KV9űZ>ftNP;j,:*Zu@;waEa/D% N8hͪعwPJHUW7-ñޓ]]_IHAeEȾ̏d٫Q[žށ>/U^T?#v'6Z2(XF[/]l*f\`p#>C)ABafƪ./t]OPK⽾RPlugins/PKꜟQT[mPlugins/config.xml]= @S4
config.xmluSMo0W k IGr۞+{^y!ll;&@GN޼<ol^'ye)-<MiP;^~#&>p#FRcG@kZձ$}698{gό2?PONL fz8^n/s&@`9%H<[KV9űZ>ftNP;j,:*Zu@;waEa/D% N8hͪعwPJHUW7-ñޓ]]_IHAeEȾ̏d٫Q[žށ>/U^T?#v'6Z2(XF[/]l*f\`p#>C)ABafƪ./t]OPK⽾RPlugins/PKꜟQT[mPlugins/config.xml]= @S4
n@@ xNrV7c+k`pz@jSȂ&+$SMWdˬTQnPKRThemes/PKR!Themes/com.stream_pi.defaultdark/PKR%Themes/com.stream_pi.defaultdark/res/PKRNܛ-\
n@@ xNrV7c+k`pz@jSȂ&+$SMWdˬTQnPKRThemes/PKR!Themes/com.stream_pi.defaultdark/PKR%Themes/com.stream_pi.defaultdark/res/PKRNܛ-\
.Themes/com.stream_pi.defaultdark/res/style.cssVm0,_
.Themes/com.stream_pi.defaultdark/res/style.cssVm0,_
l RO;X3$;jջw$ ɞ{ol'ɊkM|d~ju'XwZ?[\6).9yR}AπSMśx UoҢr\XG8-Њ)X.>z$c0Vy{0~ə-3LNMÑ_dWIJr.Pm4 fe DK9 2Z tXXH$8V\@xJ
l RO;X3$;jջw$ ɞ{ol'ɊkM|d~ju'XwZ?[\6).9yR}AπSMśx UoҢr\XG8-Њ)X.>z$c0Vy{0~ə-3LNMÑ_dWIJr.Pm4 fe DK9 2Z tXXH$8V\@xJ
o07.p%B(3<IK^\
o07.p%B(3<IK^\
2Sld ԂiF`CƸZˆܣAXShj8&T?K#KL;ȬW|#7T~ ![nhn5k^n1wSXVN6}0etG#f$GۂsBvuv%!d&a=^_DV:a:S>~+md-}skGkDp yq,?l
2Sld ԂiF`CƸZˆܣAXShj8&T?K#KL;ȬW|#7T~ ![nhn5k^n1wSXVN6}0etG#f$GۂsBvuv%!d&a=^_DV:a:S>~+md-}skGkDp yq,?l
C8a՟]:L =ǙniZta9uJ^Q}C:AV;Y F3 PKR}*Themes/com.stream_pi.defaultdark/theme.xmlmP0 R8`Rʅ'~AikbXC3١S JQ'Ym.ge#N#TVJ6};jn Fis^qBvlGtJ[,VB% hδBM%?)( O2iX`ȼƕ1,LhE^wd] PKR)Themes/com.stream_pi.defaulthighcontrast/PKR-Themes/com.stream_pi.defaulthighcontrast/res/PKRzLqg 6Themes/com.stream_pi.defaulthighcontrast/res/style.cssUK0 .`ƹB qQ$C'{0`|#:
C8a՟]:L =ǙniZta9uJ^Q}C:AV;Y F3 PKR}*Themes/com.stream_pi.defaultdark/theme.xmlmP0 R8`Rʅ'~AikbXC3١S JQ'Ym.ge#N#TVJ6};jn Fis^qBvlGtJ[,VB% hδBM%?)( O2iX`ȼƕ1,LhE^wd] PKR)Themes/com.stream_pi.defaulthighcontrast/PKR-Themes/com.stream_pi.defaulthighcontrast/res/PKRzLqg 6Themes/com.stream_pi.defaulthighcontrast/res/style.cssUK0 .`ƹB qQ$C'{0`|#:
Y[Xɤܟ{v1Ż:kɆACX3ʻp<bm pPhix4 Irh#$4hf휓{L#I5ghR
Y[Xɤܟ{v1Ż:kɆACX3ʻp<bm pPhix4 Irh#$4hf휓{L#I5ghR
P=W㋨M;kZS[T_{0O/cpmʸuܨ2x
P=W㋨M;kZS[T_{0O/cpmʸuܨ2x
VP\8ͩ$x
VP\8ͩ$x
}hۆ|E
}hۆ|E
w
w
FDXP ,{fJA N^O:ր3sxA:6 Ry-(3ŧOڇ]Y 3E5qULx+Yb};-OBYǰ'ǵu}ξOoF\;V5F#S[L76~̚!m'E|YPuN[2K--9n,.T;ϏJO$wj Xq#ựPKRGzK2Themes/com.stream_pi.defaulthighcontrast/theme.xmlmP10 ܑC 40 L h~O7ߝO瓫[]+:Y&t04=iS,aقORÁ̬u8  #ʭykW:ݶE^/#nFV%[[C<y,E'ϡ+gG<IbW~*)@񓽌tЗ?/zZ{):&^moEPKR"Themes/com.stream_pi.defaultlight/PKR&Themes/com.stream_pi.defaultlight/res/PKR܊Y
FDXP ,{fJA N^O:ր3sxA:6 Ry-(3ŧOڇ]Y 3E5qULx+Yb};-OBYǰ'ǵu}ξOoF\;V5F#S[L76~̚!m'E|YPuN[2K--9n,.T;ϏJO$wj Xq#ựPKRGzK2Themes/com.stream_pi.defaulthighcontrast/theme.xmlmP10 ܑC 40 L h~O7ߝO瓫[]+:Y&t04=iS,aقORÁ̬u8  #ʭykW:ݶE^/#nFV%[[C<y,E'ϡ+gG<IbW~*)@񓽌tЗ?/zZ{):&^moEPKR"Themes/com.stream_pi.defaultlight/PKR&Themes/com.stream_pi.defaultlight/res/PKR܊Y
/Themes/com.stream_pi.defaultlight/res/style.cssVˊ0JҖxˬBnl1d$y2{-ۉ@džuιO)_vCɊ2F $'_}[kxBe3<\|vDV[s}XA\iٟ;Xc$7z0EwnvGi^6h4l7`ѢۘOx`* ZYVZI/ _Y .d~+3QpP~xlY$W1DBaqڿqYqwХ{JSqlaaP}\7ת)v!+Djƕ)ӂb;@(خtd6R^MK+E`2$Wdv4%TOK#+ڭ\z߿UTz3G}I3;nRhӵt/e \D7dyk]¹6v(\[]dvL r;^ҍ ξĬ,}v8O.AcG ^g)|=>[TV4*0^ub8T]P <qê?w
/Themes/com.stream_pi.defaultlight/res/style.cssVˊ0JҖxˬBnl1d$y2{-ۉ@džuιO)_vCɊ2F $'_}[kxBe3<\|vDV[s}XA\iٟ;Xc$7z0EwnvGi^6h4l7`ѢۘOx`* ZYVZI/ _Y .d~+3QpP~xlY$W1DBaqڿqYqwХ{JSqlaaP}\7ת)v!+Djƕ)ӂb;@(خtd6R^MK+E`2$Wdv4%TOK#+ڭ\z߿UTz3G}I3;nRhӵt/e \D7dyk]¹6v(\[]dvL r;^ҍ ξĬ,}v8O.AcG ^g)|=>[TV4*0^ub8T]P <qê?w
<a3e:?j5:'/S>O!_hy/X*7 KJ%Ls?S PKR|+Themes/com.stream_pi.defaultlight/theme.xmlmPA0{L0)ă/@hM1qo;3;?<:et%." S*]gzi?$"nxatJr?[̄waALȸXZv PɾErVuL=z\X-yJ~R-cp$Z¡kJXpl\9f&bkwl PKԽR 
<a3e:?j5:'/S>O!_hy/X*7 KJ%Ls?S PKR|+Themes/com.stream_pi.defaultlight/theme.xmlmPA0{L0)ă/@hM1qo;3;?<:et%." S*]gzi?$"nxatJr?[̄waALȸXZv PɾErVuL=z\X-yJ~R-cp$Z¡kJXpl\9f&bkwl PKԽR 
$ config.xml
$ config.xml
=Uu#$[KSPK⽾R$0Plugins/
=Uu#$[KSPK⽾R$0Plugins/
zV9UzV9UPKSPKꜟQT[m$Plugins/config.xml
zV9UzV9UPKSPKꜟQT[m$Plugins/config.xml
~m/[PKSPKR$Themes/
~m/[PKSPKR$Themes/
 ƹ[ ƹ[+ƹ[PKR!$Themes/com.stream_pi.defaultdark/
 ƹ[ ƹ[+ƹ[PKR!$Themes/com.stream_pi.defaultdark/
ƹ[ƹ[eIƹ[PKR%$Themes/com.stream_pi.defaultdark/res/
ƹ[ƹ[eIƹ[PKR%$Themes/com.stream_pi.defaultdark/res/
[ ƹ[ ƹ[PKRNܛ-\
[ ƹ[ ƹ[PKRNܛ-\
.$ 4Themes/com.stream_pi.defaultdark/res/style.css
.$ 4Themes/com.stream_pi.defaultdark/res/style.css
0a[ܤƹ[Fƹ[PKR}*$ Themes/com.stream_pi.defaultdark/theme.xml
0a[ܤƹ[Fƹ[PKR}*$ Themes/com.stream_pi.defaultdark/theme.xml
,[Zƹ[ƹ[PKR)$Themes/com.stream_pi.defaulthighcontrast/
,[Zƹ[ƹ[PKR)$Themes/com.stream_pi.defaulthighcontrast/
/ƹ[/ƹ[ƹ[PKR-$-Themes/com.stream_pi.defaulthighcontrast/res/
/ƹ[/ƹ[ƹ[PKR-$-Themes/com.stream_pi.defaulthighcontrast/res/
@[ܤƹ[ܤƹ[PKRzLqg 6$ xThemes/com.stream_pi.defaulthighcontrast/res/style.css
@[ܤƹ[ܤƹ[PKRzLqg 6$ xThemes/com.stream_pi.defaulthighcontrast/res/style.css
g[ƹ[ƹ[PKRGzK2$ Themes/com.stream_pi.defaulthighcontrast/theme.xml
g[ƹ[ƹ[PKRGzK2$ Themes/com.stream_pi.defaulthighcontrast/theme.xml
g[+ƹ[/ƹ[PKR"$
g[+ƹ[/ƹ[PKR"$
Themes/com.stream_pi.defaultlight/
Themes/com.stream_pi.defaultlight/
Tƹ[Tƹ[ ƹ[PKR&$# Themes/com.stream_pi.defaultlight/res/
Tƹ[Tƹ[ ƹ[PKR&$# Themes/com.stream_pi.defaultlight/res/
[{yƹ[{yƹ[PKR܊Y
[{yƹ[{yƹ[PKR܊Y
/$ g Themes/com.stream_pi.defaultlight/res/style.css
/$ g Themes/com.stream_pi.defaultlight/res/style.css
|[[@qƹ[#ƹ[PKR|+$ Themes/com.stream_pi.defaultlight/theme.xml
|[[@qƹ[#ƹ[PKR|+$ Themes/com.stream_pi.defaultlight/theme.xml
2#[ƹ[Tƹ[PKI
2#[ƹ[Tƹ[PKI