diff --git a/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Voicebank/VoicebankEditor.cs b/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Voicebank/VoicebankEditor.cs
new file mode 100644
index 00000000..67766d02
--- /dev/null
+++ b/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Voicebank/VoicebankEditor.cs
@@ -0,0 +1,152 @@
+// one line to give the program's name and an idea of what it does.
+// Copyright (C) yyyy name of author
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+
+using UniversalEditor.ObjectModels.Multimedia.Audio.Voicebank;
+using UniversalEditor.UserInterface;
+using UniversalEditor.UserInterface.WindowsForms;
+
+namespace UniversalEditor.Editors.Multimedia.Audio.Voicebank
+{
+ // TODO: Create a file-format-independent explorer listview.
+
+ // The VoiceDatabaseEditor uses an Explorer listview interface. This means that
+ // PhonemeGroups are represented as folders, and Phonemes within those PhonemeGroups
+ // are represented as files. This makes it easy for a user to add/delete these kinds
+ // of items without having to learn complex interfaces.
+
+ // Where practical, I'd like to implement this interface in editors. If there is more
+ // than one editor that can be used to edit a particular type of file (for example,
+ // VoiceDatabaseProgrammerEditor and VoiceDatabaseExplorerEditor), the different
+ // editors will be listed when GetAvailableEditors (...) is called.
+
+ // For our test case (EDSEdit), these editors will be listed as tabs near the bottom
+ // of the screen. The upside to this model of course is that there will be a common
+ // editor for these types of files.
+
+ // The ExplorerEditorBase will expose a Folders collection and a Files collection.
+ // The ExplorerEditorBase will also have a built-in search box (which can be hidden
+ // if developing an app that has its own search methods) and a built-in search
+ // function Search(string text) (which can be used when developing aformentioned app)
+
+ // When user clicks on a folder (or a file), the ExplorerView will fire an ItemClick
+ // event (or for double-clicks, an ItemDoubleClick event) that the author of the Editor
+ // will handle by overriding the OnItemClick (or OnItemDoubleClick) event. The item
+ // that had been clicked will automatically go into the navigation stack (so a Back/Up
+ // button can be implemented without too much difficulty) and the author will be
+ // responsible for populating the next set of items in the hierarchy.
+
+ // Of course, the entire idea behind this is that EDS will become a drop-in replacement
+ // for any explorer on any system, and will be able to read and edit any files without
+ // difficulty.
+
+ ///
+ /// Description of VoiceDatabaseEditor.
+ ///
+ public partial class VoicebankEditor : Editor
+ {
+ public VoicebankEditor()
+ {
+ //
+ // The InitializeComponent() call is required for Windows Forms designer support.
+ //
+ InitializeComponent();
+
+ //
+ // TODO: Add constructor code after the InitializeComponent() call.
+ //
+ base.SupportedObjectModels.Add(typeof(VoicebankObjectModel));
+
+ // Select "Explorer" view by default, it looks nice~
+ tabControl1.SelectedIndex = 1;
+ }
+
+ /*
+ public override bool NavigateImaginaryPath(string path)
+ {
+ if (base.ObjectModel is VoicebankObjectModel)
+ {
+ VoicebankObjectModel ddi = (base.ObjectModel as VoicebankObjectModel);
+ PhonemeGroup pg = ddi.PhonemeGroups[path];
+ if (pg != null)
+ {
+ lvGroups.Items[ddi.PhonemeGroups.IndexOf(pg)].Selected = true;
+ }
+ else
+ {
+ MessageBox.Show("Phoneme group " + path + " does not exist in this file!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+ return false;
+ }
+ */
+
+
+ protected override void OnObjectModelChanged(EventArgs e)
+ {
+ base.OnObjectModelChanged(e);
+
+ if (base.ObjectModel is VoicebankObjectModel)
+ {
+ VoicebankObjectModel ddi = (base.ObjectModel as VoicebankObjectModel);
+ lvGroups.Items.Clear();
+ lvPhonemes.Items.Clear();
+
+ foreach(PhonemeGroup pg in ddi.PhonemeGroups)
+ {
+ ListViewItem lvi = new ListViewItem();
+ lvi.Text = pg.Title;
+ lvi.SubItems.Add(pg.Phonemes.Count.ToString());
+ // lvi.SubItems.Add(pg.Data1.ToString());
+ // lvi.SubItems.Add(pg.Data2.ToString());
+ lvGroups.Items.Add(lvi);
+
+ ListViewItem lvie = new ListViewItem();
+ lvie.Text = pg.Title;
+ lvie.SubItems.Add(pg.Phonemes.Count.ToString());
+ // lvie.SubItems.Add(pg.Data1.ToString());
+ // lvie.SubItems.Add(pg.Data2.ToString());
+ lvie.ImageKey = "folder_closed";
+ lvExplorer.Items.Add(lvie);
+ }
+ }
+ }
+
+ void lvGroups_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (base.ObjectModel is VoicebankObjectModel)
+ {
+ VoicebankObjectModel ddi = (base.ObjectModel as VoicebankObjectModel);
+ lvPhonemes.Items.Clear();
+ if (lvGroups.SelectedIndices.Count == 1)
+ {
+ foreach (Phoneme p in ddi.PhonemeGroups[lvGroups.SelectedIndices[0]].Phonemes)
+ {
+ ListViewItem lvi = new ListViewItem();
+ lvi.Text = p.Title;
+ // lvi.SubItems.Add(p.Data.ToString());
+ lvPhonemes.Items.Add(lvi);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Voicebank/VoicebankEditor.designer.cs b/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Voicebank/VoicebankEditor.designer.cs
new file mode 100644
index 00000000..d40895ab
--- /dev/null
+++ b/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Voicebank/VoicebankEditor.designer.cs
@@ -0,0 +1,286 @@
+// one line to give the program's name and an idea of what it does.
+// Copyright (C) yyyy name of author
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+namespace UniversalEditor.Editors.Multimedia.Audio.Voicebank
+{
+ partial class VoicebankEditor
+ {
+ ///
+ /// Designer variable used to keep track of non-visual components.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Disposes resources used by the control.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing) {
+ if (components != null) {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ ///
+ /// This method is required for Windows Forms designer support.
+ /// Do not change the method contents inside the source code editor. The Forms designer might
+ /// not be able to load this method if it was changed manually.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(VoiceDatabaseEditor));
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.button2 = new System.Windows.Forms.Button();
+ this.lvPhonemes = new System.Windows.Forms.ListView();
+ this.chPhonemeName = new System.Windows.Forms.ColumnHeader();
+ this.chPhonemeData = new System.Windows.Forms.ColumnHeader();
+ this.groupBox2 = new System.Windows.Forms.GroupBox();
+ this.button1 = new System.Windows.Forms.Button();
+ this.lvGroups = new System.Windows.Forms.ListView();
+ this.chPhonemeGroupName = new System.Windows.Forms.ColumnHeader();
+ this.chPhonemeGroupPhonemeCount = new System.Windows.Forms.ColumnHeader();
+ this.chPhonemeGroupData1 = new System.Windows.Forms.ColumnHeader();
+ this.chPhonemeGroupData2 = new System.Windows.Forms.ColumnHeader();
+ this.tabControl1 = new System.Windows.Forms.TabControl();
+ this.tabPage1 = new System.Windows.Forms.TabPage();
+ this.tabPage2 = new System.Windows.Forms.TabPage();
+ this.lvExplorer = new System.Windows.Forms.ListView();
+ this.imlExplorerLargeIcons = new System.Windows.Forms.ImageList(this.components);
+ this.imlExplorerSmallIcons = new System.Windows.Forms.ImageList(this.components);
+ this.groupBox1.SuspendLayout();
+ this.groupBox2.SuspendLayout();
+ this.tabControl1.SuspendLayout();
+ this.tabPage1.SuspendLayout();
+ this.tabPage2.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // groupBox1
+ //
+ this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.groupBox1.Controls.Add(this.button2);
+ this.groupBox1.Controls.Add(this.lvPhonemes);
+ this.groupBox1.Location = new System.Drawing.Point(3, 123);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(400, 175);
+ this.groupBox1.TabIndex = 1;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "Phoneme List";
+ //
+ // button2
+ //
+ this.button2.Location = new System.Drawing.Point(6, 19);
+ this.button2.Name = "button2";
+ this.button2.Size = new System.Drawing.Size(75, 23);
+ this.button2.TabIndex = 0;
+ this.button2.Text = "button1";
+ this.button2.UseVisualStyleBackColor = true;
+ //
+ // lvPhonemes
+ //
+ this.lvPhonemes.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.lvPhonemes.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+ this.chPhonemeName,
+ this.chPhonemeData});
+ this.lvPhonemes.FullRowSelect = true;
+ this.lvPhonemes.GridLines = true;
+ this.lvPhonemes.HideSelection = false;
+ this.lvPhonemes.Location = new System.Drawing.Point(6, 48);
+ this.lvPhonemes.Name = "lvPhonemes";
+ this.lvPhonemes.Size = new System.Drawing.Size(388, 121);
+ this.lvPhonemes.TabIndex = 1;
+ this.lvPhonemes.UseCompatibleStateImageBehavior = false;
+ this.lvPhonemes.View = System.Windows.Forms.View.Details;
+ //
+ // chPhonemeName
+ //
+ this.chPhonemeName.Text = "Name";
+ this.chPhonemeName.Width = 285;
+ //
+ // chPhonemeData
+ //
+ this.chPhonemeData.Text = "Data";
+ this.chPhonemeData.Width = 94;
+ //
+ // groupBox2
+ //
+ this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.groupBox2.Controls.Add(this.button1);
+ this.groupBox2.Controls.Add(this.lvGroups);
+ this.groupBox2.Location = new System.Drawing.Point(3, 3);
+ this.groupBox2.Name = "groupBox2";
+ this.groupBox2.Size = new System.Drawing.Size(397, 114);
+ this.groupBox2.TabIndex = 0;
+ this.groupBox2.TabStop = false;
+ this.groupBox2.Text = "Phoneme Groups";
+ //
+ // button1
+ //
+ this.button1.Location = new System.Drawing.Point(6, 19);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(75, 23);
+ this.button1.TabIndex = 0;
+ this.button1.Text = "button1";
+ this.button1.UseVisualStyleBackColor = true;
+ //
+ // lvGroups
+ //
+ this.lvGroups.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.lvGroups.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+ this.chPhonemeGroupName,
+ this.chPhonemeGroupPhonemeCount,
+ this.chPhonemeGroupData1,
+ this.chPhonemeGroupData2});
+ this.lvGroups.FullRowSelect = true;
+ this.lvGroups.GridLines = true;
+ this.lvGroups.HideSelection = false;
+ this.lvGroups.Location = new System.Drawing.Point(6, 48);
+ this.lvGroups.Name = "lvGroups";
+ this.lvGroups.Size = new System.Drawing.Size(385, 60);
+ this.lvGroups.TabIndex = 1;
+ this.lvGroups.UseCompatibleStateImageBehavior = false;
+ this.lvGroups.View = System.Windows.Forms.View.Details;
+ this.lvGroups.SelectedIndexChanged += new System.EventHandler(this.lvGroups_SelectedIndexChanged);
+ //
+ // chPhonemeGroupName
+ //
+ this.chPhonemeGroupName.Text = "Name";
+ this.chPhonemeGroupName.Width = 190;
+ //
+ // chPhonemeGroupPhonemeCount
+ //
+ this.chPhonemeGroupPhonemeCount.Text = "Phonemes";
+ this.chPhonemeGroupPhonemeCount.Width = 82;
+ //
+ // chPhonemeGroupData1
+ //
+ this.chPhonemeGroupData1.Text = "Data 1";
+ //
+ // chPhonemeGroupData2
+ //
+ this.chPhonemeGroupData2.Text = "Data 2";
+ //
+ // tabControl1
+ //
+ this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.tabControl1.Controls.Add(this.tabPage1);
+ this.tabControl1.Controls.Add(this.tabPage2);
+ this.tabControl1.Location = new System.Drawing.Point(3, 3);
+ this.tabControl1.Name = "tabControl1";
+ this.tabControl1.SelectedIndex = 0;
+ this.tabControl1.Size = new System.Drawing.Size(414, 327);
+ this.tabControl1.TabIndex = 3;
+ //
+ // tabPage1
+ //
+ this.tabPage1.Controls.Add(this.groupBox2);
+ this.tabPage1.Controls.Add(this.groupBox1);
+ this.tabPage1.Location = new System.Drawing.Point(4, 22);
+ this.tabPage1.Name = "tabPage1";
+ this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
+ this.tabPage1.Size = new System.Drawing.Size(406, 301);
+ this.tabPage1.TabIndex = 0;
+ this.tabPage1.Text = "Programmer";
+ this.tabPage1.UseVisualStyleBackColor = true;
+ //
+ // tabPage2
+ //
+ this.tabPage2.Controls.Add(this.lvExplorer);
+ this.tabPage2.Location = new System.Drawing.Point(4, 22);
+ this.tabPage2.Name = "tabPage2";
+ this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
+ this.tabPage2.Size = new System.Drawing.Size(406, 301);
+ this.tabPage2.TabIndex = 1;
+ this.tabPage2.Text = "Explorer";
+ this.tabPage2.UseVisualStyleBackColor = true;
+ //
+ // lvExplorer
+ //
+ this.lvExplorer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.lvExplorer.FullRowSelect = true;
+ this.lvExplorer.GridLines = true;
+ this.lvExplorer.HideSelection = false;
+ this.lvExplorer.LargeImageList = this.imlExplorerLargeIcons;
+ this.lvExplorer.Location = new System.Drawing.Point(3, 3);
+ this.lvExplorer.Name = "lvExplorer";
+ this.lvExplorer.Size = new System.Drawing.Size(400, 295);
+ this.lvExplorer.SmallImageList = this.imlExplorerSmallIcons;
+ this.lvExplorer.TabIndex = 1;
+ this.lvExplorer.UseCompatibleStateImageBehavior = false;
+ //
+ // imlExplorerLargeIcons
+ //
+ this.imlExplorerLargeIcons.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imlExplorerLargeIcons.ImageStream")));
+ this.imlExplorerLargeIcons.TransparentColor = System.Drawing.Color.Transparent;
+ this.imlExplorerLargeIcons.Images.SetKeyName(0, "folder_closed");
+ this.imlExplorerLargeIcons.Images.SetKeyName(1, "folder_open");
+ //
+ // imlExplorerSmallIcons
+ //
+ this.imlExplorerSmallIcons.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imlExplorerSmallIcons.ImageStream")));
+ this.imlExplorerSmallIcons.TransparentColor = System.Drawing.Color.Transparent;
+ this.imlExplorerSmallIcons.Images.SetKeyName(0, "folder_closed");
+ this.imlExplorerSmallIcons.Images.SetKeyName(1, "folder_open");
+ //
+ // VoiceDatabaseEditor
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.tabControl1);
+ this.Name = "VoiceDatabaseEditor";
+ this.Size = new System.Drawing.Size(420, 333);
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox2.ResumeLayout(false);
+ this.tabControl1.ResumeLayout(false);
+ this.tabPage1.ResumeLayout(false);
+ this.tabPage2.ResumeLayout(false);
+ this.ResumeLayout(false);
+ }
+ private System.Windows.Forms.ImageList imlExplorerSmallIcons;
+ private System.Windows.Forms.ImageList imlExplorerLargeIcons;
+ private System.Windows.Forms.ListView lvExplorer;
+ private System.Windows.Forms.TabPage tabPage2;
+ private System.Windows.Forms.TabPage tabPage1;
+ private System.Windows.Forms.TabControl tabControl1;
+ private System.Windows.Forms.ColumnHeader chPhonemeGroupData2;
+ private System.Windows.Forms.ColumnHeader chPhonemeGroupData1;
+ private System.Windows.Forms.ListView lvPhonemes;
+ private System.Windows.Forms.ColumnHeader chPhonemeGroupPhonemeCount;
+ private System.Windows.Forms.ColumnHeader chPhonemeGroupName;
+ private System.Windows.Forms.ColumnHeader chPhonemeData;
+ private System.Windows.Forms.ColumnHeader chPhonemeName;
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.Button button2;
+ private System.Windows.Forms.ListView lvGroups;
+ private System.Windows.Forms.GroupBox groupBox2;
+ private System.Windows.Forms.GroupBox groupBox1;
+ }
+}
diff --git a/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Voicebank/VoicebankEditor.resx b/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Voicebank/VoicebankEditor.resx
new file mode 100644
index 00000000..2009534e
--- /dev/null
+++ b/CSharp/Engines/WindowsForms/Plugins/UniversalEditor.Plugins.Multimedia.UserInterface.WindowsForms/Editors/Multimedia/Audio/Voicebank/VoicebankEditor.resx
@@ -0,0 +1,273 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 9, 8
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
+ LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
+ ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACC
+ GAAAAk1TRnQBSQFMAgEBAgEAAQQBAAEEAQABIAEAASABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAGA
+ AwABIAMAAQEBAAEgBgABQP8A/wD/AP8A/wD/AKgAAwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMB
+ Af8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMB
+ Af8DAQH/AwEB/wMBAf8DAQH//wAJAAMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMB
+ Af8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMB
+ Af8DAQH/AwEB/wMBAf8DAQH/AwEB/xAAA4EB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEB
+ AoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEB
+ AoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEB
+ AoEB/wEBAoEB/wMBAf//AAEAA4EB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEB
+ AoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEB
+ AoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEBAoEB/wEB
+ AoEB/wEBAoEB/wEBAoEB/wEBAoEB/wMBAf8MAAOBAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBAoEB/wMBAf//AAEAA4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
+ Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQKBAf8DAQH/DAADgQH/A8AB/wEBA/8DwAH/AQED/wPA
+ Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8BAQKBAf8DAQH//wABAAOBBf8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/AQECgQH/AwEB/wgAA4EB/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wMBAf8DAQH//wABAAOBBf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQECgQH/AwEB/wgA
+ A4EB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/A8AB/wMBAf8DAQH/
+ /wABAAOBBf8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ AQECgQH/AwEB/wgAA4EB/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A4EB/wMBAf8DAQH//wABAAOBBf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQECgQH/AwEB/wgAA4EB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/A4EB/wMBAf8DAQH//wABAAOBBf8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/AQECgQH/AwEB/wQAA4EB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wMBAf8BAQKBAf8DAQH//wABAAOBBf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
+ Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQECgQH/AwEB/wQAA4EB/wPA
+ Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wMBAf8BAQKBAf8DAQH/
+ /wABAAOBBf8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ AQECgQH/AwEB/wQAA4EB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ A4EB/wMBAf8BAQKBAf8DAQH//wABAAOBBf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
+ Af8BAQP/A8AB/wEBA/8DwAH/AQECgQH/AwEB/wQAA4EB/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
+ Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A4EB/wMBAf8BAQKBAf8DAQH//wABAAOBBf8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/AQECgQH/AwEB/wOBAf8DwAH/AQED/wPA
+ Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8DAQH/A4EB/wEBAoEB/wMBAf//AAEA
+ A4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQKB
+ Af8DAQH/A4EB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wMB
+ Af8DgQH/AQECgQH/AwEB//8AAQADgQX/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wEBAoEB/wMBAf8DgQH/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
+ Af8BAQP/A8AB/wEBA/8DgQH/AwEB/wEBA/8BAQKBAf8DAQH//wABAAOBBf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQECgQH/AwEB/wOBAf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
+ Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wOBAf8DAQH/A8AB/wEBAoEB/wMBAf//AAEA
+ A4EF/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8BAQKB
+ Af8DAQH/A4Fp/wMBAf8DgQH/AQED/wEBAoEB/wMBAf//AAEAA4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQKBAf8DAQH/BAADgQH/A4EB/wPAAf8DwAH/
+ A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/
+ A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf8BAQP/A8AB/wEBAoEB/wMBAf//AAEAA4EF/wPA
+ Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8BAQKBAf8DAQH/
+ DAADgQX/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
+ Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wEBAoEB/wMBAf//AAEA
+ A4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQKB
+ Af8DAQH/DAADgQX/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBAoEB/wMB
+ Af//AAEAA4EF/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
+ Af8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8BAQKBAf8DAQH/DAADgQX/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wEB
+ AoEB/wMBAf//AAEAA4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQKBAf8DAQH/DAADgQX/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/
+ AQED/wPAAf8BAQP/A8AB/wEBL/8DAQH//wAFAAOBdf8BAQKBAf8DAQH/DAADgQX/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8DgQH/A4EB/wOBAf8DgQH/
+ A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB//8ACQADgQH/A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/
+ A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf8DwAH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/
+ A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DAQH/FAADgQX/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/A4EB//8AOQADgQX/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/A4EB/1QAA4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8DgQH//wBBAAOBBf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/A4EB/1wAA4El/wOBAf//AEkAA4El/wOBAf9kAAOBAf8DgQH/A4EB/wOBAf8DgQH/
+ A4EB/wOBAf8DgQH/A4EB//8AUQADgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf//AP8A
+ /wDPAAFCAU0BPgcAAT4DAAEoAwABgAMAASADAAEBAQABAQYAAQIWAAP/AQAI/wgACP8IAAj/CAAE/wHw
+ AgABAQgAAYACAAEBAeAPAAHgDwAB4A8AAcAPAAHADwABwA8AAcAPAAGADwABgA8AAYAPAAGAXwABgA8A
+ AeAPAAHgDwAB4A8AAeACAAEBDAAB4AIAAQMLAAEBAfABAAEfAf8IAAGAAQAC/wH4AQABPwH/CAABwAEB
+ Av8B/AEAAX8B/wgAAeABAwL/Af4BAAL/CAAB8AEHBv8IAAj/CAAL
+
+
+
+ 162, 10
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
+ LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
+ ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADI
+ BQAAAk1TRnQBSQFMAgEBAgEAAQUBAAEEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
+ AwABEAMAAQEBAAEgBgABEP8A/wAYAAMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMB
+ Af8DAQH/AwEB/wMBAf8DAQH/EAADAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/AwEB/wMBAf8DAQH/
+ AwEB/wMBAf8DAQH/gAADgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOB
+ Af8DgQH/A4EB/wMBAf8MAAOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/
+ A4EB/wMBAf8DAQH/gAADgQX/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEB
+ A/8DgQH/AwEB/wwAA4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wOBAf8DAQH/
+ AwEB/4AAA4EF/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/A4EB/wMB
+ Af8IAAOBBf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AwEB/wOBAf8DAQH/
+ gAADgQX/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DgQH/AwEB/wgA
+ A4EF/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wOBAf8DAQH/A4EB/wMBAf+AAAOB
+ Bf8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wOBAf8DAQH/BAADgQX/
+ A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wMBAf8DgQH/A4EB/wMBAf+AAAOB
+ Bf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wOBAf8DAQH/BAADgSn/
+ A4EB/wMBAf8DwAH/A4EB/wMBAf+AAAOBBf8DwAH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
+ Af8BAQP/A8AB/wOBAf8DAQH/BAADgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/
+ A4EB/wOBAf8DgQH/AQED/wOBAf8DAQH/gAADgQX/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPA
+ Af8BAQP/A8AB/wEBA/8DgQH/AwEB/wgAA4EF/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AB/wEBA/8DwAH/A4EB/wMBAf+AAAOBMf8DgQH/AwEB/wgAA4EF/wEBA/8DwAH/AQED/wPAAf8BAQP/
+ A8AV/wOBAf8DAQH/gAADgQH/AQED/wPAAf8BAQP/A8AB/wEBA/8DwAH/AQED/wOBAf8DgQH/A4EB/wOB
+ Af8DgQH/A4EB/wwAA4EF/wPAAf8BAQP/A8AB/wEBA/8DwAX/A4EB/wOBAf8DgQH/A4EB/wOBAf8DgQH/
+ iAADgQH/AQED/wPAAf8BAQP/A8AB/wEBA/8DgQH/KAADgRX/A4EB/6QAA4EB/wOBAf8DgQH/A4EB/wOB
+ Af8wAAOBAf8DgQH/A4EB/wOBAf8DgQH//wChAAFCAU0BPgcAAT4DAAEoAwABQAMAARADAAEBAQABAQUA
+ AYAXAAP/AQAE/wQABP8EAAGAAQEB4AYAAQEBwAYAAQEBwAYAAQEBgAYAAQEBgAYAAQEHAAEBBwABAQcA
+ AQEBgAYAAQEBgAYAAQMBgAEBBAABgAH/AcABfwQAAcEB/wHgAf8EAAT/BAAL
+
+
+
+ 37
+
+
\ No newline at end of file
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/DataFormats/Multimedia/AudioCollection/Synthesized/SPC2/SPC2DataFormat.cs b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/DataFormats/Multimedia/AudioCollection/Synthesized/SPC2/SPC2DataFormat.cs
new file mode 100644
index 00000000..ecc914a0
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/DataFormats/Multimedia/AudioCollection/Synthesized/SPC2/SPC2DataFormat.cs
@@ -0,0 +1,143 @@
+// Universal Editor DataFormat for loading SPC2 synthesized audio files
+// Copyright (C) 2014 Mike Becker's Software
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using UniversalEditor.DataFormats.Multimedia.Audio.Synthesized.SPC;
+using UniversalEditor.IO;
+using UniversalEditor.ObjectModels.FileSystem;
+using UniversalEditor.ObjectModels.Multimedia.AudioCollection.Synthesized;
+
+namespace UniversalEditor.DataFormats.Multimedia.AudioCollection.Synthesized.SPC2
+{
+ public class SPC2DataFormat : DataFormat
+ {
+ private static DataFormatReference _dfr = null;
+ public override DataFormatReference MakeReference()
+ {
+ if (_dfr == null)
+ {
+ _dfr = base.MakeReference();
+ _dfr.Capabilities.Add(typeof(SynthesizedAudioCollectionObjectModel), DataFormatCapabilities.All);
+ _dfr.ImportOptions.Add(new CustomOptionBoolean("UseID666TagInformationIfAvailable", "Use &ID666 tag information if available"));
+ _dfr.ExportOptions.Add(new CustomOptionBoolean("IncludeID666TagInformation", "Include &ID666 tag information in output file"));
+ _dfr.Filters.Add("K.Horton's KSPC/SPC2 audio file", new byte?[][] { new byte?[] { (byte)'K', (byte)'S', (byte)'P', (byte)'C', (byte)0x1A } }, new string[] { "*.kspc" });
+ _dfr.Sources.Add("http://blog.kevtris.org/blogfiles/spc2_file_specification_v1.txt");
+ }
+ return _dfr;
+ }
+
+ private bool mvarUseID666TagInformationIfAvailable = false;
+ public bool UseID666TagInformationIfAvailable { get { return mvarUseID666TagInformationIfAvailable; } set { mvarUseID666TagInformationIfAvailable = value; } }
+
+ protected override void LoadInternal(ref ObjectModel objectModel)
+ {
+ SynthesizedAudioCollectionObjectModel coll = (objectModel as SynthesizedAudioCollectionObjectModel);
+ if (coll == null) throw new ObjectModelNotSupportedException();
+
+ Reader reader = base.Accessor.Reader;
+ string signature = reader.ReadFixedLengthString(4);
+ byte x1A = reader.ReadByte();
+ if (signature != "KSPC" || x1A != 0x1A) throw new InvalidDataFormatException("File does not begin with 'KSPC', 0x1A");
+
+ byte versionMajor = reader.ReadByte();
+ byte versionMinor = reader.ReadByte();
+
+ ushort fileCount = reader.ReadUInt16();
+ byte[] expansion = reader.ReadBytes(7);
+
+ for (ushort i = 0; i < fileCount; i++)
+ {
+ // Each SPC data block has this format
+ for (int j = 0; j < 256; j++)
+ {
+ // Offsets for all 256, 256 byte blocks of data in RAM
+ ushort dataBlockRAMOffset = reader.ReadUInt16();
+ }
+
+ // DSP register data (as-is from .SPC)
+ byte[] dspRegisterData = reader.ReadBytes(128);
+
+ // IPL ROM (as-is from .SPC)
+ byte[] iplROM = reader.ReadBytes(64);
+
+ // PCL, PCH, A, X, Y, PSW, SP (as-is from .SPC)
+ byte registerPCL = reader.ReadByte();
+ byte registerPCH = reader.ReadByte();
+ byte registerA = reader.ReadByte();
+ byte registerX = reader.ReadByte();
+ byte registerY = reader.ReadByte();
+ byte registerPSW = reader.ReadByte();
+ byte registerSP = reader.ReadByte();
+
+ // channel enable bits, 1 per chan (0 = en, 1 = dis) (as-is)
+ byte channelEnableBits = reader.ReadByte();
+
+ // stored as four bytes, in mm/dd/yyyy as BCD, like so:
+ // 01h, 12h, 20h, 00h would be 01/12/2000
+ // 07h, 30h, 19h, 95h would be 07/30/1995
+ byte[] dateParts = reader.ReadBytes(4);
+ DateTime date = new DateTime
+ (
+ Int32.Parse(dateParts[2].ToString("X").PadLeft(2, '0') + dateParts[3].ToString("X").PadLeft(2, '0')),
+ Int32.Parse(dateParts[0].ToString("X").PadLeft(2, '0')),
+ Int32.Parse(dateParts[1].ToString("X").PadLeft(2, '0'))
+ );
+
+ // 1/64000th's to play before fadeout
+ uint fadeoutDelay = reader.ReadUInt32();
+ // 1/64000th's to fade to silence
+ uint fadeoutLength = reader.ReadUInt32();
+
+ // amplification value (10000h == 1.00)
+ uint iAmplificationValue = reader.ReadUInt32();
+ double amplificationValue = (double)iAmplificationValue * 0.00001;
+
+ SPC700Emulator emulator = (SPC700Emulator)reader.ReadByte();
+
+ byte ostDisk = reader.ReadByte();
+ byte ostTrackNumber = reader.ReadByte();
+
+ ushort copyrightYear = reader.ReadUInt16();
+
+ byte[] unused = reader.ReadBytes(34);
+
+ SynthesizedAudioCollectionTrack track = new SynthesizedAudioCollectionTrack();
+ track.SongTitle = reader.ReadFixedLengthString(32).TrimNull().Trim();
+ track.GameTitle = reader.ReadFixedLengthString(32).TrimNull().Trim();
+ track.ArtistName = reader.ReadFixedLengthString(32).TrimNull().Trim();
+ track.DumperName = reader.ReadFixedLengthString(32).TrimNull().Trim();
+ track.Comments = reader.ReadFixedLengthString(32).TrimNull().Trim();
+ track.AlbumTitle = reader.ReadFixedLengthString(32).TrimNull().Trim();
+ track.PublisherName = reader.ReadFixedLengthString(32).TrimNull().Trim();
+ track.OriginalFileName = reader.ReadFixedLengthString(28).TrimNull().Trim();
+
+ uint extendedDataBlockOffset = reader.ReadUInt32();
+ }
+ }
+
+ protected override void SaveInternal(ObjectModel objectModel)
+ {
+ SynthesizedAudioCollectionObjectModel coll = (objectModel as SynthesizedAudioCollectionObjectModel);
+ if (coll == null) throw new ObjectModelNotSupportedException();
+
+ Writer writer = base.Accessor.Writer;
+ }
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Voicebank/Phoneme.cs b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Voicebank/Phoneme.cs
new file mode 100644
index 00000000..cbe50631
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Voicebank/Phoneme.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.ObjectModels.Multimedia.Audio.Voicebank
+{
+ public class Phoneme
+ {
+ public class PhonemeCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ private string mvarTitle = String.Empty;
+ public string Title { get { return mvarTitle; } set { mvarTitle = value; } }
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Voicebank/PhonemeGroup.cs b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Voicebank/PhonemeGroup.cs
new file mode 100644
index 00000000..f196bbb0
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Voicebank/PhonemeGroup.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace UniversalEditor.ObjectModels.Multimedia.Audio.Voicebank
+{
+ public class PhonemeGroup
+ {
+ public class PhonemeGroupCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ private string mvarTitle = String.Empty;
+ public string Title { get { return mvarTitle; } set { mvarTitle = value; } }
+
+ private Phoneme.PhonemeCollection mvarPhonemes = new Phoneme.PhonemeCollection();
+ public Phoneme.PhonemeCollection Phonemes { get { return mvarPhonemes; } }
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Voicebank/VoicebankObjectModel.cs b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Voicebank/VoicebankObjectModel.cs
index fbd53bfc..e84eecd2 100644
--- a/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Voicebank/VoicebankObjectModel.cs
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/Audio/Voicebank/VoicebankObjectModel.cs
@@ -38,6 +38,9 @@ namespace UniversalEditor.ObjectModels.Multimedia.Audio.Voicebank
private string mvarID = string.Empty;
public string ID { get { return mvarID; } set { mvarID = value; } }
+ private PhonemeGroup.PhonemeGroupCollection mvarPhonemeGroups = new PhonemeGroup.PhonemeGroupCollection();
+ public PhonemeGroup.PhonemeGroupCollection PhonemeGroups { get { return mvarPhonemeGroups; } }
+
private VoicebankSynthesisParameters mvarSynthesisParameters = new VoicebankSynthesisParameters();
public VoicebankSynthesisParameters SynthesisParameters { get { return mvarSynthesisParameters; } }
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/AudioCollection/Synthesized/SynthesizedAudioCollectionObjectModel.cs b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/AudioCollection/Synthesized/SynthesizedAudioCollectionObjectModel.cs
new file mode 100644
index 00000000..ed6de2ee
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/AudioCollection/Synthesized/SynthesizedAudioCollectionObjectModel.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using UniversalEditor.ObjectModels.Multimedia.Audio.Synthesized;
+
+namespace UniversalEditor.ObjectModels.Multimedia.AudioCollection.Synthesized
+{
+ public class SynthesizedAudioCollectionObjectModel : ObjectModel
+ {
+ private static ObjectModelReference _omr = null;
+ public override ObjectModelReference MakeReference()
+ {
+ if (_omr == null)
+ {
+ _omr = base.MakeReference();
+ _omr.Title = "Synthesized audio collection";
+ }
+ return _omr;
+ }
+
+ private SynthesizedAudioCollectionTrack.SynthesizedAudioCollectionTrackCollection mvarTracks = new SynthesizedAudioCollectionTrack.SynthesizedAudioCollectionTrackCollection();
+ public SynthesizedAudioCollectionTrack.SynthesizedAudioCollectionTrackCollection Tracks { get { return mvarTracks; } }
+
+ public override void Clear()
+ {
+ mvarTracks.Clear();
+ }
+
+ public override void CopyTo(ObjectModel where)
+ {
+ SynthesizedAudioCollectionObjectModel clone = (where as SynthesizedAudioCollectionObjectModel);
+ foreach (SynthesizedAudioCollectionTrack track in mvarTracks)
+ {
+ clone.Tracks.Add(track.Clone() as SynthesizedAudioCollectionTrack);
+ }
+ }
+ }
+}
diff --git a/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/AudioCollection/Synthesized/SynthesizedAudioCollectionTrack.cs b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/AudioCollection/Synthesized/SynthesizedAudioCollectionTrack.cs
new file mode 100644
index 00000000..19f1e38d
--- /dev/null
+++ b/CSharp/Plugins/UniversalEditor.Plugins.Multimedia/ObjectModels/Multimedia/AudioCollection/Synthesized/SynthesizedAudioCollectionTrack.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using UniversalEditor.ObjectModels.Multimedia.Audio.Synthesized;
+
+namespace UniversalEditor.ObjectModels.Multimedia.AudioCollection.Synthesized
+{
+ public class SynthesizedAudioCollectionTrack : ICloneable
+ {
+ public class SynthesizedAudioCollectionTrackCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ private string mvarSongTitle = String.Empty;
+ public string SongTitle { get { return mvarSongTitle; } set { mvarSongTitle = value; } }
+
+ private string mvarGameTitle = String.Empty;
+ public string GameTitle { get { return mvarGameTitle; } set { mvarGameTitle = value; } }
+
+ private string mvarArtistName = String.Empty;
+ public string ArtistName { get { return mvarArtistName; } set { mvarArtistName = value; } }
+
+ private string mvarDumperName = String.Empty;
+ public string DumperName { get { return mvarDumperName; } set { mvarDumperName = value; } }
+
+ private string mvarComments = String.Empty;
+ public string Comments { get { return mvarComments; } set { mvarComments = value; } }
+
+ private string mvarAlbumTitle = String.Empty;
+ public string AlbumTitle { get { return mvarAlbumTitle; } set { mvarAlbumTitle = value; } }
+
+ private string mvarPublisherName = String.Empty;
+ public string PublisherName { get { return mvarPublisherName; } set { mvarPublisherName = value; } }
+
+ private string mvarOriginalFileName = String.Empty;
+ public string OriginalFileName { get { return mvarOriginalFileName; } set { mvarOriginalFileName = value; } }
+
+ private SynthesizedAudioObjectModel mvarObjectModel = null;
+ public SynthesizedAudioObjectModel ObjectModel { get { return mvarObjectModel; } }
+
+ }
+}