UI: Master-Key-Button (Settings, via Designer) + UI-Designer-WIP + Steuer-PDF
- Settings: neuer Toolbar-Button 'Master-Key erzeugen' (Tab General Settings, via Designer). Erzeugt zufaelligen 32-Byte-AES-Key -> master.key (gitignored), nur aktiv wenn KEIN Key existiert (Env-Var oder Datei), Lockout-Schutz + Backup-Warnung, danach deaktiviert. - Einbezogen: laufende Designer-Umstrukturierung (SettingsView/LauncherForm: Button-Bilder aus Properties.Resources statt eingebettet; dgv_accountlist im Launcher; DashboardView.resx). - docs/steuer: US-CPA-Fragebogen als PDF. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
36c89a6acf
commit
4df07bd3d2
Generated
+42
-5
@@ -32,10 +32,14 @@ namespace PolyTraderSharp.Ui
|
||||
lbl_trading = new ToolStripStatusLabel();
|
||||
lbl_modules = new ToolStripStatusLabel();
|
||||
lbl_ratelimit = new ToolStripStatusLabel();
|
||||
dgv_accountlist = new DataGridView();
|
||||
btn_accounting = new ToolStripButton();
|
||||
toolStripSeparator1 = new ToolStripSeparator();
|
||||
menuStrip.SuspendLayout();
|
||||
toolstrip_windows.SuspendLayout();
|
||||
toolstrip_quickbar.SuspendLayout();
|
||||
statusStrip_info.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)dgv_accountlist).BeginInit();
|
||||
SuspendLayout();
|
||||
//
|
||||
// menuStrip
|
||||
@@ -54,18 +58,18 @@ namespace PolyTraderSharp.Ui
|
||||
miDatei.Name = "miDatei";
|
||||
miDatei.Size = new Size(69, 29);
|
||||
miDatei.Text = "Datei";
|
||||
//
|
||||
//
|
||||
// miBeenden
|
||||
//
|
||||
miBeenden.Name = "miBeenden";
|
||||
miBeenden.Size = new Size(275, 34);
|
||||
miBeenden.Size = new Size(182, 34);
|
||||
miBeenden.Text = "Beenden";
|
||||
//
|
||||
// toolstrip_windows
|
||||
//
|
||||
toolstrip_windows.AutoSize = false;
|
||||
toolstrip_windows.ImageScalingSize = new Size(64, 64);
|
||||
toolstrip_windows.Items.AddRange(new ToolStripItem[] { btn_dashboard, btn_settings, btn_terminal, btn_jobs });
|
||||
toolstrip_windows.Items.AddRange(new ToolStripItem[] { btn_dashboard, btn_settings, btn_terminal, btn_jobs, btn_accounting, toolStripSeparator1 });
|
||||
toolstrip_windows.Location = new Point(0, 35);
|
||||
toolstrip_windows.Name = "toolstrip_windows";
|
||||
toolstrip_windows.Size = new Size(2599, 70);
|
||||
@@ -140,7 +144,7 @@ namespace PolyTraderSharp.Ui
|
||||
statusStrip_info.BackColor = Color.Gainsboro;
|
||||
statusStrip_info.ImageScalingSize = new Size(24, 24);
|
||||
statusStrip_info.Items.AddRange(new ToolStripItem[] { lbl_trading, lbl_modules, lbl_ratelimit });
|
||||
statusStrip_info.Location = new Point(0, 140);
|
||||
statusStrip_info.Location = new Point(0, 637);
|
||||
statusStrip_info.Name = "statusStrip_info";
|
||||
statusStrip_info.Size = new Size(2599, 32);
|
||||
statusStrip_info.TabIndex = 5;
|
||||
@@ -164,11 +168,40 @@ namespace PolyTraderSharp.Ui
|
||||
lbl_ratelimit.Size = new Size(66, 25);
|
||||
lbl_ratelimit.Text = "API: —";
|
||||
//
|
||||
// dgv_accountlist
|
||||
//
|
||||
dgv_accountlist.AllowUserToAddRows = false;
|
||||
dgv_accountlist.AllowUserToDeleteRows = false;
|
||||
dgv_accountlist.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||
dgv_accountlist.Dock = DockStyle.Fill;
|
||||
dgv_accountlist.Location = new Point(0, 139);
|
||||
dgv_accountlist.Name = "dgv_accountlist";
|
||||
dgv_accountlist.ReadOnly = true;
|
||||
dgv_accountlist.RowHeadersWidth = 62;
|
||||
dgv_accountlist.Size = new Size(2599, 498);
|
||||
dgv_accountlist.TabIndex = 6;
|
||||
//
|
||||
// btn_accounting
|
||||
//
|
||||
btn_accounting.Image = Properties.Resources.coins_in_hand;
|
||||
btn_accounting.ImageScaling = ToolStripItemImageScaling.None;
|
||||
btn_accounting.ImageTransparentColor = Color.Magenta;
|
||||
btn_accounting.Name = "btn_accounting";
|
||||
btn_accounting.Size = new Size(106, 65);
|
||||
btn_accounting.Text = "Accounting";
|
||||
btn_accounting.TextImageRelation = TextImageRelation.ImageAboveText;
|
||||
//
|
||||
// toolStripSeparator1
|
||||
//
|
||||
toolStripSeparator1.Name = "toolStripSeparator1";
|
||||
toolStripSeparator1.Size = new Size(6, 70);
|
||||
//
|
||||
// LauncherForm
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(10F, 25F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(2599, 172);
|
||||
ClientSize = new Size(2599, 669);
|
||||
Controls.Add(dgv_accountlist);
|
||||
Controls.Add(statusStrip_info);
|
||||
Controls.Add(toolstrip_quickbar);
|
||||
Controls.Add(toolstrip_windows);
|
||||
@@ -187,6 +220,7 @@ namespace PolyTraderSharp.Ui
|
||||
toolstrip_quickbar.PerformLayout();
|
||||
statusStrip_info.ResumeLayout(false);
|
||||
statusStrip_info.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)dgv_accountlist).EndInit();
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
@@ -208,5 +242,8 @@ namespace PolyTraderSharp.Ui
|
||||
private ToolStripStatusLabel lbl_trading;
|
||||
private ToolStripStatusLabel lbl_modules;
|
||||
private ToolStripStatusLabel lbl_ratelimit;
|
||||
private ToolStripButton btn_accounting;
|
||||
private ToolStripSeparator toolStripSeparator1;
|
||||
private DataGridView dgv_accountlist;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
Generated
+89
-117
@@ -17,52 +17,48 @@ namespace PolyTraderSharp.Ui.Views
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SettingsView));
|
||||
propertyGrid = new PropertyGrid();
|
||||
toolStrip1 = new ToolStrip();
|
||||
tabControl1 = new TabControl();
|
||||
tabPage1 = new TabPage();
|
||||
tabPage2 = new TabPage();
|
||||
toolStrip2 = new ToolStrip();
|
||||
btn_save = new ToolStripButton();
|
||||
btn_loadsettings = new ToolStripButton();
|
||||
btnGenMasterKey = new ToolStripButton();
|
||||
tabPage2 = new TabPage();
|
||||
pgAccount = new PropertyGrid();
|
||||
dgvAccounts = new DataGridView();
|
||||
toolStripAccounts = new ToolStrip();
|
||||
btnAccNew = new ToolStripButton();
|
||||
btnAccDelete = new ToolStripButton();
|
||||
dgvAccounts = new DataGridView();
|
||||
colAccName = new DataGridViewTextBoxColumn();
|
||||
colAccWallet = new DataGridViewTextBoxColumn();
|
||||
colAccDemo = new DataGridViewCheckBoxColumn();
|
||||
colAccActive = new DataGridViewCheckBoxColumn();
|
||||
pgAccount = new PropertyGrid();
|
||||
tabControl1.SuspendLayout();
|
||||
tabPage1.SuspendLayout();
|
||||
tabPage2.SuspendLayout();
|
||||
toolStrip2.SuspendLayout();
|
||||
toolStripAccounts.SuspendLayout();
|
||||
tabPage2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)dgvAccounts).BeginInit();
|
||||
toolStripAccounts.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
//
|
||||
// propertyGrid
|
||||
//
|
||||
//
|
||||
propertyGrid.Dock = DockStyle.Bottom;
|
||||
propertyGrid.Location = new Point(3, 610);
|
||||
propertyGrid.Margin = new Padding(4, 25, 4, 5);
|
||||
propertyGrid.Name = "propertyGrid";
|
||||
propertyGrid.Size = new Size(1171, 274);
|
||||
propertyGrid.TabIndex = 1;
|
||||
//
|
||||
//
|
||||
// toolStrip1
|
||||
//
|
||||
//
|
||||
toolStrip1.ImageScalingSize = new Size(24, 24);
|
||||
toolStrip1.Location = new Point(0, 0);
|
||||
toolStrip1.Name = "toolStrip1";
|
||||
toolStrip1.Size = new Size(1185, 25);
|
||||
toolStrip1.TabIndex = 2;
|
||||
toolStrip1.Text = "toolStrip1";
|
||||
//
|
||||
//
|
||||
// tabControl1
|
||||
//
|
||||
//
|
||||
tabControl1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||
tabControl1.Controls.Add(tabPage1);
|
||||
tabControl1.Controls.Add(tabPage2);
|
||||
@@ -71,9 +67,9 @@ namespace PolyTraderSharp.Ui.Views
|
||||
tabControl1.SelectedIndex = 0;
|
||||
tabControl1.Size = new Size(1185, 925);
|
||||
tabControl1.TabIndex = 3;
|
||||
//
|
||||
//
|
||||
// tabPage1
|
||||
//
|
||||
//
|
||||
tabPage1.Controls.Add(toolStrip2);
|
||||
tabPage1.Controls.Add(propertyGrid);
|
||||
tabPage1.Location = new Point(4, 34);
|
||||
@@ -83,9 +79,43 @@ namespace PolyTraderSharp.Ui.Views
|
||||
tabPage1.TabIndex = 0;
|
||||
tabPage1.Text = "General Settings";
|
||||
tabPage1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// toolStrip2
|
||||
//
|
||||
toolStrip2.ImageScalingSize = new Size(24, 24);
|
||||
toolStrip2.Items.AddRange(new ToolStripItem[] { btn_save, btn_loadsettings, btnGenMasterKey });
|
||||
toolStrip2.Location = new Point(3, 3);
|
||||
toolStrip2.Name = "toolStrip2";
|
||||
toolStrip2.Size = new Size(1171, 34);
|
||||
toolStrip2.TabIndex = 0;
|
||||
toolStrip2.Text = "toolStrip2";
|
||||
//
|
||||
// btn_save
|
||||
//
|
||||
btn_save.Image = Properties.Resources.diskette;
|
||||
btn_save.ImageTransparentColor = Color.Magenta;
|
||||
btn_save.Name = "btn_save";
|
||||
btn_save.Size = new Size(150, 29);
|
||||
btn_save.Text = "Save Changes";
|
||||
//
|
||||
// btn_loadsettings
|
||||
//
|
||||
btn_loadsettings.Image = Properties.Resources.token_quantifier;
|
||||
btn_loadsettings.ImageTransparentColor = Color.Magenta;
|
||||
btn_loadsettings.Name = "btn_loadsettings";
|
||||
btn_loadsettings.Size = new Size(223, 29);
|
||||
btn_loadsettings.Text = "Load Settings from File";
|
||||
//
|
||||
// btnGenMasterKey
|
||||
//
|
||||
btnGenMasterKey.DisplayStyle = ToolStripItemDisplayStyle.Text;
|
||||
btnGenMasterKey.Name = "btnGenMasterKey";
|
||||
btnGenMasterKey.Size = new Size(200, 29);
|
||||
btnGenMasterKey.Text = "Master-Key erzeugen";
|
||||
btnGenMasterKey.ToolTipText = "Erzeugt einen zufälligen AES-Master-Key (nur wenn noch keiner existiert).";
|
||||
//
|
||||
// tabPage2
|
||||
//
|
||||
//
|
||||
tabPage2.Controls.Add(pgAccount);
|
||||
tabPage2.Controls.Add(dgvAccounts);
|
||||
tabPage2.Controls.Add(toolStripAccounts);
|
||||
@@ -96,115 +126,56 @@ namespace PolyTraderSharp.Ui.Views
|
||||
tabPage2.TabIndex = 1;
|
||||
tabPage2.Text = "Polymarket Accounts";
|
||||
tabPage2.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// toolStrip2
|
||||
//
|
||||
toolStrip2.ImageScalingSize = new Size(24, 24);
|
||||
toolStrip2.Items.AddRange(new ToolStripItem[] { btn_save, btn_loadsettings });
|
||||
toolStrip2.Location = new Point(3, 3);
|
||||
toolStrip2.Name = "toolStrip2";
|
||||
toolStrip2.Size = new Size(1171, 34);
|
||||
toolStrip2.TabIndex = 0;
|
||||
toolStrip2.Text = "toolStrip2";
|
||||
//
|
||||
// btn_save
|
||||
//
|
||||
btn_save.Image = (Image)resources.GetObject("btn_save.Image");
|
||||
btn_save.ImageTransparentColor = Color.Magenta;
|
||||
btn_save.Name = "btn_save";
|
||||
btn_save.Size = new Size(150, 29);
|
||||
btn_save.Text = "Save Changes";
|
||||
//
|
||||
// btn_loadsettings
|
||||
//
|
||||
btn_loadsettings.Image = (Image)resources.GetObject("btn_loadsettings.Image");
|
||||
btn_loadsettings.ImageTransparentColor = Color.Magenta;
|
||||
btn_loadsettings.Name = "btn_loadsettings";
|
||||
btn_loadsettings.Size = new Size(223, 29);
|
||||
btn_loadsettings.Text = "Load Settings from File";
|
||||
//
|
||||
// toolStripAccounts
|
||||
//
|
||||
toolStripAccounts.ImageScalingSize = new Size(24, 24);
|
||||
toolStripAccounts.Items.AddRange(new ToolStripItem[] { btnAccNew, btnAccDelete });
|
||||
toolStripAccounts.Location = new Point(3, 3);
|
||||
toolStripAccounts.Name = "toolStripAccounts";
|
||||
toolStripAccounts.Size = new Size(1171, 34);
|
||||
toolStripAccounts.TabIndex = 0;
|
||||
//
|
||||
// btnAccNew
|
||||
//
|
||||
btnAccNew.DisplayStyle = ToolStripItemDisplayStyle.Text;
|
||||
btnAccNew.Name = "btnAccNew";
|
||||
btnAccNew.Size = new Size(130, 29);
|
||||
btnAccNew.Text = "Neuer Account";
|
||||
//
|
||||
// btnAccDelete
|
||||
//
|
||||
btnAccDelete.DisplayStyle = ToolStripItemDisplayStyle.Text;
|
||||
btnAccDelete.Name = "btnAccDelete";
|
||||
btnAccDelete.Size = new Size(90, 29);
|
||||
btnAccDelete.Text = "Löschen";
|
||||
//
|
||||
//
|
||||
// pgAccount
|
||||
//
|
||||
pgAccount.Dock = DockStyle.Fill;
|
||||
pgAccount.Location = new Point(623, 37);
|
||||
pgAccount.Name = "pgAccount";
|
||||
pgAccount.Size = new Size(551, 847);
|
||||
pgAccount.TabIndex = 2;
|
||||
//
|
||||
// dgvAccounts
|
||||
//
|
||||
//
|
||||
dgvAccounts.AllowUserToAddRows = false;
|
||||
dgvAccounts.AllowUserToDeleteRows = false;
|
||||
dgvAccounts.AutoGenerateColumns = false;
|
||||
dgvAccounts.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||
dgvAccounts.Columns.AddRange(new DataGridViewColumn[] { colAccName, colAccWallet, colAccDemo, colAccActive });
|
||||
dgvAccounts.Dock = DockStyle.Left;
|
||||
dgvAccounts.Location = new Point(3, 37);
|
||||
dgvAccounts.MultiSelect = false;
|
||||
dgvAccounts.Name = "dgvAccounts";
|
||||
dgvAccounts.ReadOnly = true;
|
||||
dgvAccounts.RowHeadersVisible = false;
|
||||
dgvAccounts.RowHeadersWidth = 62;
|
||||
dgvAccounts.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
|
||||
dgvAccounts.Size = new Size(620, 847);
|
||||
dgvAccounts.TabIndex = 1;
|
||||
//
|
||||
// colAccName
|
||||
//
|
||||
colAccName.DataPropertyName = "Name";
|
||||
colAccName.HeaderText = "Name";
|
||||
colAccName.Name = "colAccName";
|
||||
colAccName.ReadOnly = true;
|
||||
colAccName.Width = 200;
|
||||
//
|
||||
// colAccWallet
|
||||
//
|
||||
colAccWallet.DataPropertyName = "WalletAddress";
|
||||
colAccWallet.HeaderText = "Wallet";
|
||||
colAccWallet.Name = "colAccWallet";
|
||||
colAccWallet.ReadOnly = true;
|
||||
colAccWallet.Width = 260;
|
||||
//
|
||||
// colAccDemo
|
||||
//
|
||||
colAccDemo.DataPropertyName = "IsDemo";
|
||||
colAccDemo.HeaderText = "Demo";
|
||||
colAccDemo.Name = "colAccDemo";
|
||||
colAccDemo.ReadOnly = true;
|
||||
colAccDemo.Width = 60;
|
||||
//
|
||||
// colAccActive
|
||||
//
|
||||
colAccActive.DataPropertyName = "IsActive";
|
||||
colAccActive.HeaderText = "Aktiv";
|
||||
colAccActive.Name = "colAccActive";
|
||||
colAccActive.ReadOnly = true;
|
||||
colAccActive.Width = 60;
|
||||
//
|
||||
// pgAccount
|
||||
//
|
||||
pgAccount.Dock = DockStyle.Fill;
|
||||
pgAccount.Location = new Point(623, 37);
|
||||
pgAccount.Name = "pgAccount";
|
||||
pgAccount.Size = new Size(551, 847);
|
||||
pgAccount.TabIndex = 2;
|
||||
//
|
||||
//
|
||||
// toolStripAccounts
|
||||
//
|
||||
toolStripAccounts.ImageScalingSize = new Size(24, 24);
|
||||
toolStripAccounts.Items.AddRange(new ToolStripItem[] { btnAccNew, btnAccDelete });
|
||||
toolStripAccounts.Location = new Point(3, 3);
|
||||
toolStripAccounts.Name = "toolStripAccounts";
|
||||
toolStripAccounts.Size = new Size(1171, 34);
|
||||
toolStripAccounts.TabIndex = 0;
|
||||
//
|
||||
// btnAccNew
|
||||
//
|
||||
btnAccNew.Image = Properties.Resources.add;
|
||||
btnAccNew.Name = "btnAccNew";
|
||||
btnAccNew.Size = new Size(157, 29);
|
||||
btnAccNew.Text = "Neuer Account";
|
||||
//
|
||||
// btnAccDelete
|
||||
//
|
||||
btnAccDelete.Image = Properties.Resources.cancel;
|
||||
btnAccDelete.Name = "btnAccDelete";
|
||||
btnAccDelete.Size = new Size(104, 29);
|
||||
btnAccDelete.Text = "Löschen";
|
||||
//
|
||||
// SettingsView
|
||||
//
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(10F, 25F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(1185, 1523);
|
||||
@@ -216,13 +187,13 @@ namespace PolyTraderSharp.Ui.Views
|
||||
tabControl1.ResumeLayout(false);
|
||||
tabPage1.ResumeLayout(false);
|
||||
tabPage1.PerformLayout();
|
||||
tabPage2.ResumeLayout(false);
|
||||
tabPage2.PerformLayout();
|
||||
toolStrip2.ResumeLayout(false);
|
||||
toolStrip2.PerformLayout();
|
||||
tabPage2.ResumeLayout(false);
|
||||
tabPage2.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)dgvAccounts).EndInit();
|
||||
toolStripAccounts.ResumeLayout(false);
|
||||
toolStripAccounts.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)dgvAccounts).EndInit();
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
@@ -237,6 +208,7 @@ namespace PolyTraderSharp.Ui.Views
|
||||
private TabPage tabPage2;
|
||||
private ToolStripButton btn_save;
|
||||
private ToolStripButton btn_loadsettings;
|
||||
private ToolStripButton btnGenMasterKey;
|
||||
private ToolStrip toolStripAccounts;
|
||||
private ToolStripButton btnAccNew;
|
||||
private ToolStripButton btnAccDelete;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Windows.Forms;
|
||||
using PolyTrader.Core.Persistence;
|
||||
using PolyTraderSharp.Models;
|
||||
@@ -33,6 +35,8 @@ namespace PolyTraderSharp.Ui.Views
|
||||
|
||||
btn_save.Click += (_, _) => Save();
|
||||
btn_loadsettings.Click += (_, _) => Reload();
|
||||
btnGenMasterKey.Click += (_, _) => GenerateMasterKey();
|
||||
UpdateMasterKeyButtonState();
|
||||
|
||||
btnAccNew.Click += (_, _) => AddAccount();
|
||||
btnAccDelete.Click += (_, _) => DeleteAccount();
|
||||
@@ -129,5 +133,54 @@ namespace PolyTraderSharp.Ui.Views
|
||||
_state?.Accounts.AddOrUpdate(acc.AccountId, acc, (_, _) => acc);
|
||||
dgvAccounts.Refresh();
|
||||
}
|
||||
|
||||
// ===== Master-Key (at-rest-Verschlüsselung, F1) =====
|
||||
|
||||
/// <summary>Pfad der Master-Key-Datei – identisch zu Program.cs (App-Ordner, gitignored).</summary>
|
||||
private static string MasterKeyFilePath => Path.Combine(AppContext.BaseDirectory, "master.key");
|
||||
|
||||
/// <summary>Existiert bereits ein Master-Key (Umgebungsvariable ODER Datei)?</summary>
|
||||
private static bool MasterKeyExists() =>
|
||||
!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("POLYTRADER_MASTER_KEY"))
|
||||
|| File.Exists(MasterKeyFilePath);
|
||||
|
||||
/// <summary>Button nur aktiv, solange KEIN Master-Key existiert (Überschreiben = Lockout-Gefahr).</summary>
|
||||
private void UpdateMasterKeyButtonState() => btnGenMasterKey.Enabled = !MasterKeyExists();
|
||||
|
||||
private void GenerateMasterKey()
|
||||
{
|
||||
// Sicherheitsnetz gegen Race/Doppelklick: einen bestehenden Key NIEMALS überschreiben.
|
||||
if (MasterKeyExists())
|
||||
{
|
||||
MessageBox.Show(
|
||||
"Es existiert bereits ein Master-Key – Erzeugung abgebrochen. Ein Überschreiben würde den " +
|
||||
"Zugriff auf bereits verschlüsselte Wallet-Keys unwiederbringlich zerstören.",
|
||||
"Master-Key vorhanden", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
UpdateMasterKeyButtonState();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
byte[] keyBytes = RandomNumberGenerator.GetBytes(32); // 256-Bit-Schlüssel
|
||||
File.WriteAllText(MasterKeyFilePath, Convert.ToBase64String(keyBytes));
|
||||
_logger?.Info("🔐 Master-Key erzeugt und in master.key gespeichert. At-rest-Verschlüsselung wird beim nächsten Start aktiv.");
|
||||
|
||||
MessageBox.Show(
|
||||
"Ein zufälliger 32-Byte-Master-Key wurde erzeugt und in der Datei 'master.key' (App-Ordner, gitignored) gespeichert.\n\n" +
|
||||
"WICHTIG:\n" +
|
||||
"• Sichere diese Datei SOFORT separat und sicher (z. B. Passwort-Manager / Offline-Backup).\n" +
|
||||
"• Master-Key-Verlust = KEIN Zugriff mehr auf die verschlüsselten Wallet-Keys!\n" +
|
||||
"• Die Verschlüsselung der Account-Credentials wird beim nächsten Programmstart aktiv.",
|
||||
"Master-Key erzeugt", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Fehler beim Erzeugen des Master-Keys: {ex.Message}",
|
||||
"Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
UpdateMasterKeyButtonState(); // nach Erzeugung deaktivieren
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,32 +118,12 @@
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
<value>225, 17</value>
|
||||
</metadata>
|
||||
<metadata name="toolStrip2.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>162, 17</value>
|
||||
<value>370, 17</value>
|
||||
</metadata>
|
||||
<metadata name="toolStripAccounts.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="btn_save.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAEBSURBVEhL3ZIvC8JAGIf3OTTZ/A62+RXs2g2rFsGi2P0C
|
||||
WlwT02wGMQjLhgVRnAMR/5bVV37CHeduf9TdFQfPDt7wPOy9GWEYkk4MvGzbJsuylAInD2BgmqZS4JQC
|
||||
99tDCcoCl+OBPKdH3qxHe3eiPuAOTFq0CxwWURYQ5QBfojfgKA5sl0Mux7pwJx8H/NOdmvPj64yKs8gM
|
||||
QFqdBlQc7V/nt5HUwDq4cTnj20hiYLW7Unnsv8l/icQGKrVGojwrgpk4lwL1VpdKw40kjCMaYfclzqVA
|
||||
3z1LojSYTPwZ2Bxrzh1gsujPALBmrDt3IA2sG2vXFgBw/lFAJwh0dGLofp4xWrfOyeSKuAAAAABJRU5E
|
||||
rkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="btn_loadsettings.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAEBSURBVEhL3ZIvC8JAGIf3OTTZ/A62+RXs2g2rFsGi2P0C
|
||||
WlwT02wGMQjLhgVRnAMR/5bVV37CHeduf9TdFQfPDt7wPOy9GWEYkk4MvGzbJsuylAInD2BgmqZS4JQC
|
||||
99tDCcoCl+OBPKdH3qxHe3eiPuAOTFq0CxwWURYQ5QBfojfgKA5sl0Mux7pwJx8H/NOdmvPj64yKs8gM
|
||||
QFqdBlQc7V/nt5HUwDq4cTnj20hiYLW7Unnsv8l/icQGKrVGojwrgpk4lwL1VpdKw40kjCMaYfclzqVA
|
||||
3z1LojSYTPwZ2Bxrzh1gsujPALBmrDt3IA2sG2vXFgBw/lFAJwh0dGLofp4xWrfOyeSKuAAAAABJRU5E
|
||||
rkJggg==
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,118 @@
|
||||
%PDF-1.4
|
||||
%“Œ‹ž ReportLab Generated PDF document (opensource)
|
||||
1 0 obj
|
||||
<<
|
||||
/F1 2 0 R /F2 3 0 R /F3 4 0 R
|
||||
>>
|
||||
endobj
|
||||
2 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
3 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
4 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font
|
||||
>>
|
||||
endobj
|
||||
5 0 obj
|
||||
<<
|
||||
/Contents 11 0 R /MediaBox [ 0 0 612 792 ] /Parent 10 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
6 0 obj
|
||||
<<
|
||||
/Contents 12 0 R /MediaBox [ 0 0 612 792 ] /Parent 10 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
7 0 obj
|
||||
<<
|
||||
/Contents 13 0 R /MediaBox [ 0 0 612 792 ] /Parent 10 0 R /Resources <<
|
||||
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
|
||||
>> /Rotate 0 /Trans <<
|
||||
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
8 0 obj
|
||||
<<
|
||||
/PageMode /UseNone /Pages 10 0 R /Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
9 0 obj
|
||||
<<
|
||||
/Author (PolyTrader) /CreationDate (D:20260714175142+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260714175142+02'00') /Producer (ReportLab PDF Library - \(opensource\))
|
||||
/Subject (\(unspecified\)) /Title (US Tax Treatment Questionnaire \204 Polymarket Trading \(Florida LLC\)) /Trapped /False
|
||||
>>
|
||||
endobj
|
||||
10 0 obj
|
||||
<<
|
||||
/Count 3 /Kids [ 5 0 R 6 0 R 7 0 R ] /Type /Pages
|
||||
>>
|
||||
endobj
|
||||
11 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2584
|
||||
>>
|
||||
stream
|
||||
Gatm<?'F9X'n)]]EM"S"!cIoFo<L7.4gUPe.d>c$CL;;u[K*.@ag'p(afj$QCd(Q\Ft;$A^f]gcI[kcQ&O)3EkI]?I,l2LMpKr@>".Cg`O1^9\hs&>N_nSEX.hfNKooeaR(Ph]+S\Nc,]><s;a+<\RU'ZP+<moo_XZ6-#2#A*6rbS\VI5Qko_tR-8/Qr%h%F&XR$b<!]<kN$6.&go%"=a<G9JcB35;uj%Viln**uY%qNpeNs@ouJQ!FE)FcTOM^j((b'lpS*S?C1q:1d,o.9L3Kc\c3S0TA&3*ho>*%=r:[nQIDMu@TIP^8hSAf5HUj^@!7"q60&2H'R.QW6QCJ*<%W,[hnMD"mrfX>IMdFlFOKPqEV:W:a88EFXuL(_kE5Utf>SZ&`3Fq[BS.<fe\#?KcY9@n;GD$"rp]QJm`?ShQG3d/C6+sT\l+uHU7<0/QU5^JCJL:tCRuDInf4><DNEK6MTOY%MncO@lp;]M5ZJbM?HJ-QXk^0JNn15XS62)V7N)X@UJudhb,R1$4)=c=maY:q<2"TBV9PGHg8]lQkIGd<OFH2`/ogiTE8p\!8lOGOnSe3\5i\]_,XI^/M*F_S'Dggg&(5;H.DfC!P_,J[*]H8"r>uUhH3ZtF?(G4f%N^ikr68IW0M]X"'2QjWeggM@8qRh#hgb^.<C[=)Hck">eLMR9`^r1\U(iSaW"HgR\gGtI0!#2uTd2X2S?L5X;-.rl46qO-;&CklQ+^^DL2&B/L1(cO(RaZI;:e//]+E$6:N,SI;)#C"#Q,=0)J)H-%6RKf0OmDug,A8#26/U[3;;^:dE^PLY*Bc>7qup8_1BLqJR>#kHTTWj%'B([Wq^=_34*+PJnI]sq&N@S'#VNYJBc=G3Kr67<;f.eK$d`8#(LCFi!Z+pg-s^^s4jZI,[ArrB=?mBU3]0WYbL&FpO^&/R:qYL*=,EV'=EYOfkZ^[@05/U73`.p$mskM@=oX"FPVjg)I,OFdNR666bc")qnSd"C"anq:>W_,S6$[`dXX!NVC6O>R=J>O[4%B13Acn&df*Yo?lKgA_D3/`/Se@XQgb\4;Ao52;a^jfO<ge-L*]$kOo$qT"rO$eJ0A-;D,fnYYNN);bJk]CLaLB#)-NVOqg]$FYBYK+!BJ?SKKLBY"j:5&gVoK2.9I*4HBO=Hdq]AGIFHliYJP,?gS=A*[GL%FZd$S26!CQdYEcYL5>]eIaue8SrbDIb-BsoHO>e!CY&%p.LpS=6qUGiHZiSoV7qN)T1Z$:t6RCME6BcE2[AIcbZ^4nT5lt9lFuZ#sU&W/`rD]i1a`p#kd._2q2emu(BN9Qb/X9gC-q@BogF:t=$NRX=o;ht4\%+e59++ISg<(/^/NQ[(!tgnGLr:HM,Ds?9P'-0oR@]4gG.P/Wk^k$d/^u+G9Zh^.7_80q#_*h.ZRp!W2!F3CL!`Ut[4HcU*0e8g]QFD>Yh]4QOpoh#b$`21%kq+HWu1K/3'/tG]piPC[M=\/JVmp%BgAP\%Ap8^Vd;+obuP?0V*JBT6DO'VaE&V39$kVWl@p0V$ut%4@Etke7qq><cja4+M^fXWB7;e8!rKf#eUAi3DMd(2_T2d$JGJ/qX-T:9IjKGmdl$$e3nGcXbng?e(3Vi`RXNdqTOW=844Z=,XE/=b/+fq^"Ht>nLqI^eM3?eO\63n6R2p!@Tn/qsf*8r!D)!#VL$`oiIK<8&)BW-b'!$P'7l$AKEg8M*$dXSU5mL^/VLI%g#$Q!q<__t[q>f;W[I)&B^?%[o-k#keAShZMX+;F"$I8"BQ$VJZ!4@nmn/F$gF6IRKC3*bRK"j'dMiU6?9Cmk&(ioBN/<YY-hWQ73goB7A4oE$YVSQo+^-Hn0m?!X.YUKGU7';3,Xl:JH/k6t9l"*p9^g^Q!YBRMFou_Nrf3^Vrb6eqi/4IR%9#D!(aO<pJ[+TmZpo*98!]?P[!!gGp?3;=[MmU)X*Zp8tgpru].?*K7S>q]2%]5@-5_Jk42aJ[6Xk09cP2fkuSAb&d4ni^fqoJ4Jq#c$LoRO,G.i:\_DWr0JZ9BX#6c7LjaPt$aG`VQN(^WF?%1FSI0UUbrE2/HRn7!F:M'M?9O!g.LH7=IcV>P0^d.Y(;Ad+=2fD?OJ$8H>'mp7:l$akON7V:cbm]F.\@@TJ#I==SepG;9&7L&a9gnP'ZH(oDLhTUbI9X!S'#UfWEFG.,bh-I9.&kOQ7a0_"#N"['7)cPVPTiIf-MeRH=DNQ6GX\J[SJO;7.lmj_?'pk"'khi5Ue^20:kjs^tkeh1;'d\dpQu@PeF-fJOY[Z,\+OMq,EbSAZV_$4;DDJ\A**pk[M2L[J2S,%'0AlcVrec<_D)np:Yj(;)Pmmo"20`e9DPP"^m,9$1g)iJ(=>P:a"YG/8^h?6QM*88?Hu.]S?hZ>KY>?q(ilFo5#d*kk:B-2H`4_rqEcQAUHd#QNY!'DC?+M9'UJ#l>TV3RAS;@47][,`eH,9QLa2ad>3Dp:uJrSfNR4eqV/)#<9R2YXT5ps$VGOB'm_hs]e2_-s-q2T)(G0Y^gon,67P*Gbb);dsE1Ff^K*Z<N,jC=sp0XHuiM-^:V_1t5P(Y[>(EW~>endstream
|
||||
endobj
|
||||
12 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2499
|
||||
>>
|
||||
stream
|
||||
Gatm<gMZ%@&q-CU-j7@Q%P15JmTs:\m!'KY0S;sJ>3&+*D6bEA6]mmNe$AQ;3Rsp98PP%5&0%ia?Fm14<Ll2$55"I3gV;^%keD3(4o44E1gcD1oS,4&6m(R[^:gT99]a:<)qW]Td6N0Er)9f["i"Al'_pO,32HX^gJI'G[:0J\B`8sqIumZj*ZYd)\*(&-[o)uP)k(OW`T`8ojK+W'Za?Ao&5;<f:Gc.VoLm;[>YS5"q.S_o@/,348KTIDB4LiK2jHc0_0^Y]48RfA3ZS#ARW%/t\Cc-:aR>&5IJ^'He/<UV#E+eZeKK9Js7)2u/h9Nb9'M/URL>uP/W;;@S=5%/61k<V[6"PIV2e9o`@ZesAs5[V5K-[bpt,X&/cH]kdR&X'JQp:hhUfK/grX[CI*D$6^3b1I\.DRe>Utg.Z.eX^7uH<fOu5DkW.s$mEi)9\]p4BOo1['_QboL[941_$r=eI%DR+/_j,b'9pEu'7TT=^UTQg:)mg#&uoK)9$(=YQ$.9(S/<,tK3WG.nL2Ic_XS4,\K1GN,<Ft]BP80qKJF!FPZ&^\TsVB%2SCh](cWWKh5W?H_!]eaHW8[Erdd:l:CU:nQf?,U,l^:o8bE4\dfg+jhLP=-$-0+Egeh'=e:B8_cW^QidNgN[ll3<"QG,'_YWp':iN.hV?lKB]2..&QCj=fKYe;C+%J,IKcdcP,C8*IQQ^q42<N$uU"D1rTi&asC1fY]sB%8`EGQ[)lj6kPfm1%KO^RNdW#<'EV+R`o,fV9Lc@#9Es@pElIeR73GZtjS=?k)UHJlNXSEAH%S[B)U9lrmla<P0Lb3jaXC('oIm#hE&*rB(7jRH`n"K579.lHMfGM@ZZ1QK(3mZ'39cL-LMYNSZCarAW?mOj/-0sW8g@61aYoGFKW-5'o"_/!n*+&UP'FO4,uXM#j'COYSb`1tERVj*;HtT#*-efHD^28bfTF,_B9+QF&gqKUe#he.VGU#ZmuX,\g6:='V%bATMKQC)$/>JpB'IJ*di>\s=Q:Q`d1t\*cTen:Q[c+NGsd(;TBcOMqs?grJdUkuQQ1=o=r@Q59B]?*5f5).#6(GLB:H"4]s+.:6dCZjTj[7=Lk_/BSqdYc*G(b("fM"r8J3:GmA_kgp*)n6'1Z'G\HUY%84q'Mk^(S?3C\5H[A#jT?>Du\2]0h.^0HHL^CL.'pJ7;1]=c7LChNRhW7O,oh5KV`0m]'@-b+a$$AN);qU!2#`300Fe82`!*fH0-Y?9<T*`EFkakjAR>]C+UPb?X)kSd5=+@8mfmHo3ZC<#IU&`842mk[B$=V\1qShr-s9NJ$&T3%?gnZR)3JN&rjgOg6Je;.5YXfU9]=_H-Q'?/"QO'e?C""GPTV(*.b\@HaoI*Q05N'iIIKO2Bl-47%Ebs8$"Spj@WaG/(,`4(L4!S*,eYIRPn6F6P@\fW"t@L?Cf?%V`>;a4s[nc#0bbGV@mmrS%>OX7?W!71!o=0lcA41]d/Jm#,CoPEj52.`!-8E#?JOgCp=1ubGBj_7e3kE*I`)UN&jZO0%XE=1OK#4A.Pb,]-5k1.n90k^Gf6MV]n;Y\M=XHl-`;@pGDj_>#HN,g^ECq7'dX7Va;+mN/T;F<P@hY6mFSmB[qmf`SPA=0%0PuR,:UEgRm"*j8crs;mOlub2dqQV&e[ZJ\u"S1q5RGMjI#]EdY-&ilR0sg`=]ZL_T,sn'-`Vr1C+'P\W*:cs".K-?TM,cl89E55!Y)F3@/30.!n*9&9SeICoHk(^2X^h]+,:V,s]B6M-c.8,\L!Vd\m(0gFo\f.Keo,@D`sneY+e9,bk4aZ*.."hI&8(G%0H@G:EhQ(l#C1g]:W@7!ei(X"7KmY>::bLgXm%_WnI5g;H;XJ5"e%02cKsHaY.hkCSWOrE,dVh?nC1@4>qC.h`RKkYg4'-+60^:DpTu7c_^7c/U*#`D4ak_b.8c:P]4[U,iE'GeGNVV3#rWU=#0OAg?.^a&]%Y/P0,P3)D<%Jm-cUZ%P]cHEZb7_&,d0TH5qB"rO@oBC0$%A#F'O7g8O-dPD?7_Kre&\]UIW)ek7qY]c&%V/VosaO(,JG3FFcC;qlQ'sh_t<q\BK&^XstAf/Ma7!rE2M0fSO/er8o&s63"*5B?t`hj'(CbJH9b>=)D92/Gs6Y<SibgW]T+/KM<^g:cC#N*HgnF,4Uu=?Ei?^:KQg#6CO!ZH"KJ%fc,+E$DmZ<pW".,*h+]R>W%bE<DQ&u+^s1F"$S"*][`=Unj3lmbs?136#?i,5AF8h'nUFin6<tcL6+84!JHl#Rlu5,Tm'hC;?=n_064?&p_EGjR\LTf]j+<UUUNh#Xh=MTOSl6OqT5LnG'!fQnOBCC8mEDag5BQ:RSRY_lC(GfXjn/nbkO[6Io]oB:R\ab8"u<5(do([32u]kK]"=2bon;OU9Z@t\tdU1FJP?G7;+7b#tpX:o#WMH?^;9=-iT"nL(=Nbol5*Pl@.B.:NTLk<i"TF;oB:nFD`ZjcN\^i#FK)/pA~>endstream
|
||||
endobj
|
||||
13 0 obj
|
||||
<<
|
||||
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2449
|
||||
>>
|
||||
stream
|
||||
Gatm<?$"a[&q&$/R+f-_PHQ6h'WJ8u>fr2rD"_,G?<atqK3r"!P-?8>"TY\"If2/i8sVk6W7nhm8lS1[SEZI+ks7]\rZ_*)(.98-eA$hg)UNjt;%b-2^SU8l]5R/,3tlsN)N:-BK4/TrdIC3gm=M:iI5m%78MZtVb6mOiYpH=CK'%R0r1A/!]gkRanFiBr?ONa&\Y6QCR4+EogR9X)KIeuD%L-G>nj%9iSURcP[_J,%.)*1\mkB.$o/O\6UZi&VBi-r+mC\K,p5M@#%]A9Mjr=)54m_&7-jm*"U&.b]lG+51#)ADSf-0n+p2\-Y.Q-37kO__f;0&e<=g?eb_nWC#WOZp6o[m=0bUfP>qPNe._7Aus"_/uS=u+pKqsCgbU0K+DNP`:W`Ohr-_JGV<Al_6:5mXSK*@#-UXWB.Pdq6Q6-WXidOrM(%+^MojfK,cD*Djk;iS!81LBA7F30"4+E#aUrA.X$**-cH#.e9,'E^4;D=j(/VBL^s&H322n4S/K98nklT1bjA.HcR&gP"7'I8Y6e!Y3W==.p:sOD)`u9ata\3`Q1ChL%,0Wmsk_=5r9QU.6sUS_oQHA@$jWKC*TN6(g>:V56Ld'Q07G5o5d/U;K8rmM5@2Q8je"GG@ZIZ!Z8M7arn"QN>bP>kFshj#4XD@6n@t!la$b>03VS4+$5C\bV[O]mb9!N%cF6_C8#tbCr'hfjS.9W]4C^Q^MSZe?Jr<QXa[:p=k'r%7W0GBL:FO:CL-o*:T_)D-'h3,D"Sh;J+N4$*_tOIEd%D^%8T8ePWW9Zp0^\e"UVQqoX?78L1*Vh\Q!suN;ZarUg'F9Z=u9^*Os&-m7a_s+%8cXk+nKiq<S_#k'WUkj%4$I?+LVPY>JG`*PLU7=9tKq"$#[VX>Mrj9-qL7?h8:$:WSiWcEkW'FFl&Yhj@tl&9"ONlIlYe9I`On&tr8peHb6EQ^kgpd`2d66#rh.irEq;P)MM'3:]%W#t$:gEJ4nEPgHRa-s>o%B)UdTl:W'A'H"-_at5upOuCN`m5ANV$miVinC1:G@L?eB>lIgb,1U,TmF'",:bk1n:d^=%.IP[GNu8_l%qnum`QRn=r_>*tYFKSR$V')8U.hFbhKV@Dp4VXYMaef,k`Q@^OuB2O57rpVep`GE6E#KK+6Y49@]h"/H"i`dDlpeREo1'8&5,QK7REB1B6F/6ZMO-2baDKlFDVboYm=>_9#MW;pTM=C3iR94<1<]Y4#eV$co'k)&+7@<m`g7/c7>1N^(CP8Idd37qo71;DeLNcHu3:Lqa_S<n58]Z[fM$qYb32npIG>2(k-#9)dm>2I-laNK;I!p!M/muC]@CA:5%8ffTJ8`UNW!W^!0"pPOp=T=T>K9<olUc+uXa!IH2+B5SsHsdeb>`3m"A`9%74fF7I,4CDkPm/-D8J0Q]"?6St=l9c*c5Q02.['LBhL4W-*LAC-kT]g>.E2Ht!?].TR*$(#98s0:k/-5?IiaQ`<p"%kDRMNVua[nJlpD;A)+E8Jc`#3F7<Ym(OC&#s\hrD(C?Off$FI7lqMXm5B0DUs.0h:7KpH=$*HAM$Gb-.5d,9YF0+NPFSoam"%q>'h68@W]e#Ghro:aJcR$m.T'"][Ndo#GGm+8@GZW]"OZBQG3^>E?+`V);t*I4K#W_?lVlG'2PBaI7*.UAX8qA+;D+<X1U$WT;6j`k'V"L_4%4HR)(YEF9S)Zf&Nh_5of9pO&<Mlqgkp81pHAB[JjCL'UhF"`f:u)OBu%JHe@RQ?-.^OkiOG-8MZYA`u]>NUZ]%cj*$a@RauoNh)oIg,$AtP-G[)om*0/c4WZ/,/mWIf.^?-Fd_\a?86PPA)m7;YNjZ4i^PBlR47W3=Ot#<Y$I>M+oY`F?Fm1F*X.EoOI?sh/Bk+K^9:qS"qmk4$i*cd6qR=lo!;Oo8c3YV8K<[(L4`fU(S<m5&9J6M(Q<HC:AsdbmAhpKi5II`NdLQ,Y@@$A4Cr+@gAho^r=6/Ml*J@MqYhuYqZ!7;_.fpF>oMG)%l?KrCcZOGq^SkLq[KPgpJI?pV@Q=W3mN6*HK@:\6=O/q5h1OAHJP^h*/"u<<+,kWI9o#,%CbS^i!I*X#E`,PR?=TaEq#<FZpiet?5g7Ak%*pg*]R"i%/1q9",@;VkL;;!gi79r?bBZ80F^8M+h7'(_4/TKdTX*F?1XSJ1N2[J5%lMfU*BdC(T?tX,0nDK14&!=cDJW&_m$ZU=<j\"SR<0T\UH=[GbI7B4D+(E^3'(tV/%JGk7nM0]:>?]j;%rCQD/f(_HuX-9`hUW]"$nVtVPA)spRg<-DJ;BCegC0Xe&0;Z7EK`%_aoe+q&%]aN+q"Ea1+,^5.]I8@\VQ.P<ZE5R5H[lOuJablm^clY\t'R)HPt>*]d9>\d9nm8Q\/O_1Nj<'F]10F=.8Dk$')m21%A5NH3Y+fHC]X1gdNYg"I#XJPP\5"?kZiT)~>endstream
|
||||
endobj
|
||||
xref
|
||||
0 14
|
||||
0000000000 65535 f
|
||||
0000000061 00000 n
|
||||
0000000112 00000 n
|
||||
0000000219 00000 n
|
||||
0000000331 00000 n
|
||||
0000000446 00000 n
|
||||
0000000641 00000 n
|
||||
0000000836 00000 n
|
||||
0000001031 00000 n
|
||||
0000001100 00000 n
|
||||
0000001434 00000 n
|
||||
0000001506 00000 n
|
||||
0000004182 00000 n
|
||||
0000006773 00000 n
|
||||
trailer
|
||||
<<
|
||||
/ID
|
||||
[<18477745dd8f1284102189041b6ea342><18477745dd8f1284102189041b6ea342>]
|
||||
% ReportLab generated PDF document -- digest (opensource)
|
||||
|
||||
/Info 9 0 R
|
||||
/Root 8 0 R
|
||||
/Size 14
|
||||
>>
|
||||
startxref
|
||||
9314
|
||||
%%EOF
|
||||
Reference in New Issue
Block a user