*EIpNg@K9H<=!>fTIO?ltwDIsq329ecy2cPIe<4nYD(Io
zeA$iH)XYes_q5tk+8%@CN*(M3vOUrEmV)&z2$;lqTt83ibZVwMncG+H)>k#agaTVj
zE%JOAE#lk`poOH9sx!NDebx7@(w7DvaA@ilhRJrFNUuKgyJnIiFSICD@mwCKhnLeMUq=oE;tbT;Rit>6>U}
zcRRjGFVehQ-6Yw4c>&7SdAc|IM#YHRFoAp{QR=YcZ&QZ_RJ$Y?<()!6d
zr!|Z?XL?>bKI=
z{bJP3ofhVNqhy?a&J&{^jK0S&G(>}%Z|9p${kPGBRIQ8)YFZhk^_WHs#9b?lkSpN3
zR*NsAnhWG%D)#|cjXKTi1eG3|oR_gr1JJ)`-Pr}S(zSR47h)CF*V6O;T+~=U%4F2X
zXR)b~eyJG~M7{OX7-cD_5Gpl;;
zV9Q3(nnK!XCPI8U{o2f)4jVD+xkIY(FXxBsP5NbKD)UAb9sSeMrJL{heE7kGOMmOz
zEdJ%&{i1E*n_ZXQ{=>^3`uD>>J@?By-@&Ud@49W-qrDGwJRQ30)p3UT!>9Q3#qK2D
z83oprtCoQsI>jk^8EfEG%)JRVP#B*cOY5CD--5eicqWQE>%EbkuGH)VAu
zx0{O#a?cc77I9?Wj~ByxU}3z_-(HM-0
zR~Nse-mQ>r<5=vQmA8^R7WCE+VQe^iG}Ny?rK!THnOma6j6PHab;vx2l_FN*Te)3H
zKBy=gpQmnW0lqR)S8L|Ts>ce8>9dQx8s{24+PUjs<@7!C@?UfHZ_Sqf=K245{=bxF
zxf1?6E9n`frrG2F8O)3P{{k@+m!bF#$$!{vQ
lB>2!9xyWI$(d$2eoRyR3=bR;zx4^&N2{E{~UQqwP1kJ?;<|F7G$!~E}d
zcp$!bdMti#4+LjlZ@0zU+ue(QUcbxjcDH-F>{F8gmopIdwmU68huvp!1_EwN(B<`6
z+%``j;;@I>wQBhPdalg33IA*%0brcGkN?D6etE6TWG2kIHKX04r2aBA|~$4pv^iqgS235YJNC*
zJ@_h#uxj`j)FxjK~
z{!f?Bn#TXV{+s24XMJ;b`k#+|Y~rT))rTn0Qk}yOj~Rzao*h5#WGKU&&jq^YT-KMM
zl>NN4|An%joAvupZ9AUHzp{3CG!|PY8(E2e4%Jp>?C;zyLH`XtUyJ>{TKyY6Sd8=s
z$%h_B6CQ{2&`Z#~JqaJnWl$Ra8t@ai{>a%vJPmj!{G<;6hTu!J2yMO@yZSzg^D7n!
zVaNHc*r(0&t;o7_KF)7I6zF|8Uy6O3KLC99yM?$7@EO2g0zS4_hW5M>k&pim=Qm%-
zZHYoG!DgGA@%&*#A)q_Y`>~hq3pjtXRfuok{D0ret#xS2GU;aGUoOOYwEGUk1^OVa
zpT9zgXL0`@-^UPpNUU^;%&dA7G}IxSFIf%OFWeun%Op}S06v2I??oJ!2l4wprx4%8
z`Q=C*bT!ToBNhnZ@8B~=nCxK6cRY(J5(j(@a5u`Eo~G`M(#GU#tFecjb;Bxf^oi
z2A)b1n==$813RC2+Zi3-c>awGUi|Rmod;HSZA16P@spkZ&(G3y3Oa@Nsek74f3?9E
z&Y0n+Fsd=;dl@&@%wSG~w^sfygTQVo|Ccd;wDhN|&VO#*-Ev@?mH#Ub-xXp)iD$+!
zjS4qp{QXOvC%gTo+4`GW<&RqVZ*puJ_7#w)2*80_e!x}0Baz;MSAq=7cn;k2L6S)y
zUFM)8QK9yngxS0osGcnEoK^;j5#lbuAmAs#B|HN7GN}KvfI(32uLHJ#TK^ny{d!nN
zLFETFh;g&@(`bJy+!k3rblaAr|MA0@U;VEg51eAT__p8Q@;aI|%|(0#6eztTdp?8z
zvECoG2+^OMb9MbwT|)eK5iZ4T@q$l#2sM*W8-dr=8_N)E5W?6$V&uMq>pxow{t$2T
zfSaKPg!tNKA-)Cp&=w({K#8~3%KwA!)L9?^%!cauf0ci+S^R%~{>Jjz(AiV=^{v7G
zt0|U&**U9zD1-mauY98vll8`zSBY2l;cIqQRBn~ZZAIz%%YAFcIN96bBTmDr!kB!L
zJDjl2fDgInP3}B1KEpB?hli2eC3fAWubowRrgAifoAHsj_|#dKKb3hyc~ZR6(ugda
z9zC{#6In`f`PbZR*jCIB>i-!_-ON7L%FEt_H%2~M?nC`!?1rN&htB)LyY@ePPUjnv
zCaUGacXJrujUZ1>d=CN1_T&642qtR*uLbM@d<4)Bcs3>wuLl4rpgx&_-Eb&i)bg(b
zg4&4%Kl8o*aG@UqinIiCjP_5T5ctSdIWT|Rd^Ag@0M$nu;}5)eLs
zoz|>(83gHT0S{&1Vu!rGACRl@bO_kj0e%#a_ah{Qt{X~c;I9A~>2{Y(hz|fh4HyKx
z8Vh0<;7X;%C-1@>r*iVx
zpFwd4cnNUhX8{)i*Nx!XGr(!PPZi?t&O+98{I-4(l$L<&79*Yb0^~Gn1%3l`Tnt=>
zXL@W{$9QHD7Un82$!B6M-iPyBurQwobY6qpL13y6M1W@ip8;YS16(;J#Or`dKO)3A
zcy8I9cowkji$dHFXly^4jZbO)cdhbUt@^K8pP#4y^Ys5OFvI8Re{<-6t@_JapEv41
zfe|qim`f}L8HZ8Gm}6-G|Km6&r_Ov<)E!OedZh@C*4>Rq@G-0ZG^4*74kg0T;UQ}{
z7SrV?kOJZE?HKIp@6W`8$OD(f1J>=y9_)YGs->;H#^>?q0;A2bucu>BI)J4Hv!3Z&
zdj|&ll7YCkH<8>kIOc@Ed%LaO?laudlZeL?!`5^lIi#gi91>M-JGVG>tX`c8U9ZIh
zDQi3$N+wc?NZJ}o#8-#4F)fxD(UPmkBBX%hp9J=$<*(AFMtMLZFNJ8;FAiYZqIesbq7LwaG@`1)PHqFu+N~I?;z(EsCeJAc0hlx+hTz7V%<3_5V{yqQxn=Aj-Du30Je>3C1-VFM0q@TpdbD4je>-4*Tf6GW3
zY1js6n~Fo*&iG0r&_*Y8`GYYDvpEu#P`==z;6XS
zd@daSfC%ngBE(gI-OHhygO2V?7U=t+%e&NrYtYR-2_^bsz#Ur=UKY>&(*Rry0DpT8
zI6FM&3nQL4Y$QKNXtz;Dp5y>~%Bh&F9HB*ZV!
z*0C=N@hIB*mtPj*MZoXhkG7+{#~v1<75827E!2nd?mQ~Qm8e(spW8l{!i}rUx5G0O6|Gt-#CBF(EsNfBEM7`y_Pw;iEZM*N{kyE%;=aV
zfXl`p|4{ErGhb3b_;O|!gO95VF72+N|_vf(M?gBPb*rl}o
G?f(HalW~Cn
literal 0
HcmV?d00001
diff --git a/v2rayN/v2rayN/Forms/AddServer2Form.Designer.cs b/v2rayN/v2rayN/Forms/AddServer2Form.Designer.cs
new file mode 100644
index 00000000..0e407a43
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServer2Form.Designer.cs
@@ -0,0 +1,140 @@
+namespace v2rayN.Forms
+{
+ partial class AddServer2Form
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AddServer2Form));
+ this.btnClose = new System.Windows.Forms.Button();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.txtAddress = new System.Windows.Forms.TextBox();
+ this.label13 = new System.Windows.Forms.Label();
+ this.txtRemarks = new System.Windows.Forms.TextBox();
+ this.label6 = new System.Windows.Forms.Label();
+ this.label1 = new System.Windows.Forms.Label();
+ this.panel2 = new System.Windows.Forms.Panel();
+ this.btnOK = new System.Windows.Forms.Button();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.groupBox1.SuspendLayout();
+ this.panel2.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // btnClose
+ //
+ resources.ApplyResources(this.btnClose, "btnClose");
+ this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.btnClose.Name = "btnClose";
+ this.btnClose.UseVisualStyleBackColor = true;
+ this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
+ //
+ // groupBox1
+ //
+ resources.ApplyResources(this.groupBox1, "groupBox1");
+ this.groupBox1.Controls.Add(this.txtAddress);
+ this.groupBox1.Controls.Add(this.label13);
+ this.groupBox1.Controls.Add(this.txtRemarks);
+ this.groupBox1.Controls.Add(this.label6);
+ this.groupBox1.Controls.Add(this.label1);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.TabStop = false;
+ //
+ // txtAddress
+ //
+ resources.ApplyResources(this.txtAddress, "txtAddress");
+ this.txtAddress.Name = "txtAddress";
+ //
+ // label13
+ //
+ resources.ApplyResources(this.label13, "label13");
+ this.label13.Name = "label13";
+ //
+ // txtRemarks
+ //
+ resources.ApplyResources(this.txtRemarks, "txtRemarks");
+ this.txtRemarks.Name = "txtRemarks";
+ //
+ // label6
+ //
+ resources.ApplyResources(this.label6, "label6");
+ this.label6.Name = "label6";
+ //
+ // label1
+ //
+ resources.ApplyResources(this.label1, "label1");
+ this.label1.Name = "label1";
+ //
+ // panel2
+ //
+ resources.ApplyResources(this.panel2, "panel2");
+ this.panel2.Controls.Add(this.btnClose);
+ this.panel2.Controls.Add(this.btnOK);
+ this.panel2.Name = "panel2";
+ //
+ // btnOK
+ //
+ resources.ApplyResources(this.btnOK, "btnOK");
+ this.btnOK.Name = "btnOK";
+ this.btnOK.UseVisualStyleBackColor = true;
+ this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
+ //
+ // panel1
+ //
+ resources.ApplyResources(this.panel1, "panel1");
+ this.panel1.Name = "panel1";
+ //
+ // AddServer2Form
+ //
+ resources.ApplyResources(this, "$this");
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.btnClose;
+ this.Controls.Add(this.groupBox1);
+ this.Controls.Add(this.panel2);
+ this.Controls.Add(this.panel1);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.Name = "AddServer2Form";
+ this.Load += new System.EventHandler(this.AddServer2Form_Load);
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.panel2.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.Button btnClose;
+ private System.Windows.Forms.Button btnOK;
+ private System.Windows.Forms.TextBox txtRemarks;
+ private System.Windows.Forms.Label label6;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Panel panel1;
+ private System.Windows.Forms.Panel panel2;
+ private System.Windows.Forms.Label label13;
+ private System.Windows.Forms.TextBox txtAddress;
+ }
+}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/AddServer2Form.cs b/v2rayN/v2rayN/Forms/AddServer2Form.cs
new file mode 100644
index 00000000..a88afb44
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServer2Form.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Windows.Forms;
+using v2rayN.Handler;
+using v2rayN.Mode;
+
+namespace v2rayN.Forms
+{
+ public partial class AddServer2Form : BaseForm
+ {
+ public int EditIndex { get; set; }
+ VmessItem vmessItem;
+
+ public AddServer2Form()
+ {
+ InitializeComponent();
+ }
+
+ private void AddServer2Form_Load(object sender, EventArgs e)
+ {
+ if (EditIndex >= 0)
+ {
+ BindingServer();
+ }
+ else
+ {
+ ClearServer();
+ }
+ }
+
+ ///
+ /// 绑定数据
+ ///
+ private void BindingServer()
+ {
+ vmessItem = config.vmess[EditIndex];
+ txtRemarks.Text = vmessItem.remarks;
+ txtAddress.Text = vmessItem.address;
+ txtAddress.ReadOnly = true;
+ }
+
+
+ ///
+ /// 清除设置
+ ///
+ private void ClearServer()
+ {
+ txtRemarks.Text = "";
+ }
+
+ private void btnOK_Click(object sender, EventArgs e)
+ {
+ string remarks = txtRemarks.Text;
+ if (Utils.IsNullOrEmpty(remarks))
+ {
+ UI.Show(UIRes.I18N("PleaseFillRemarks"));
+ return;
+ }
+ vmessItem.remarks = remarks;
+
+ if (ConfigHandler.EditCustomServer(ref config, vmessItem, EditIndex) == 0)
+ {
+ this.DialogResult = DialogResult.OK;
+ }
+ else
+ {
+ UI.Show(UIRes.I18N("OperationFailed"));
+ }
+ }
+
+ private void btnClose_Click(object sender, EventArgs e)
+ {
+ this.DialogResult = DialogResult.Cancel;
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/Forms/AddServer2Form.resx b/v2rayN/v2rayN/Forms/AddServer2Form.resx
new file mode 100644
index 00000000..c98d40e0
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServer2Form.resx
@@ -0,0 +1,390 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ txtAddress
+
+
+ Address
+
+
+ 0
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ Bottom
+
+
+
+ True
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ btnOK
+
+
+ txtRemarks
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ AddServer2Form
+
+
+ label1
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ panel2
+
+
+
+ 12, 27
+
+
+ Fill
+
+
+ True
+
+
+ 313, 21
+
+
+ groupBox1
+
+
+ 6, 12
+
+
+ True
+
+
+ Alias (remarks)
+
+
+ 127, 23
+
+
+ 6
+
+
+ 7
+
+
+ groupBox1
+
+
+ 113, 12
+
+
+ 4
+
+
+ Server
+
+
+ 23
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 0
+
+
+ 611, 60
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Edit custom configuration server
+
+
+ 432, 104
+
+
+ 611, 10
+
+
+ groupBox1
+
+
+ * Fill in manually
+
+
+ 11
+
+
+ 10
+
+
+ panel1
+
+
+ 75, 23
+
+
+ 2
+
+
+ btnClose
+
+
+ 303, 17
+
+
+ 0, 211
+
+
+ 75, 23
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ Top
+
+
+ 0, 10
+
+
+ 3
+
+
+ 611, 201
+
+
+ 2
+
+
+ 4
+
+
+ 3
+
+
+ 127, 62
+
+
+ groupBox1
+
+
+ True
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 83, 12
+
+
+ &Cancel
+
+
+ 12, 62
+
+
+ &OK
+
+
+ 0
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 446, 26
+
+
+ groupBox1
+
+
+ label6
+
+
+ $this
+
+
+ 1
+
+
+ 0, 0
+
+
+ panel2
+
+
+ label13
+
+
+ 83, 12
+
+
+ 22
+
+
+ 1
+
+
+ panel2
+
+
+ 5
+
+
+ 611, 271
+
+
+ 0
+
+
+ v2rayN.Forms.BaseForm, v2rayN, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
+
+
+ $this
+
+
+ 396, 17
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 1
+
+
+ True
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/AddServer2Form.zh-Hans.resx b/v2rayN/v2rayN/Forms/AddServer2Form.zh-Hans.resx
new file mode 100644
index 00000000..a01d4dfa
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServer2Form.zh-Hans.resx
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 取消(&C)
+
+
+ *手填,方便识别管理
+
+
+ 别名(remarks)
+
+
+ 地址(address)
+
+
+ 服务器
+
+
+ 确定(&O)
+
+
+ 编辑自定义配置服务器
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/AddServer3Form.Designer.cs b/v2rayN/v2rayN/Forms/AddServer3Form.Designer.cs
new file mode 100644
index 00000000..3515e6b9
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServer3Form.Designer.cs
@@ -0,0 +1,231 @@
+namespace v2rayN.Forms
+{
+ partial class AddServer3Form
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AddServer3Form));
+ this.btnClose = new System.Windows.Forms.Button();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.label13 = new System.Windows.Forms.Label();
+ this.cmbSecurity = new System.Windows.Forms.ComboBox();
+ this.txtRemarks = new System.Windows.Forms.TextBox();
+ this.label6 = new System.Windows.Forms.Label();
+ this.label5 = new System.Windows.Forms.Label();
+ this.txtId = new System.Windows.Forms.TextBox();
+ this.label3 = new System.Windows.Forms.Label();
+ this.txtPort = new System.Windows.Forms.TextBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.txtAddress = new System.Windows.Forms.TextBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.panel2 = new System.Windows.Forms.Panel();
+ this.btnOK = new System.Windows.Forms.Button();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.menuServer = new System.Windows.Forms.MenuStrip();
+ this.MenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuItemImportClipboard = new System.Windows.Forms.ToolStripMenuItem();
+ this.groupBox1.SuspendLayout();
+ this.panel2.SuspendLayout();
+ this.menuServer.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // btnClose
+ //
+ this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ resources.ApplyResources(this.btnClose, "btnClose");
+ this.btnClose.Name = "btnClose";
+ this.btnClose.UseVisualStyleBackColor = true;
+ this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
+ //
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.label13);
+ this.groupBox1.Controls.Add(this.cmbSecurity);
+ this.groupBox1.Controls.Add(this.txtRemarks);
+ this.groupBox1.Controls.Add(this.label6);
+ this.groupBox1.Controls.Add(this.label5);
+ this.groupBox1.Controls.Add(this.txtId);
+ this.groupBox1.Controls.Add(this.label3);
+ this.groupBox1.Controls.Add(this.txtPort);
+ this.groupBox1.Controls.Add(this.label2);
+ this.groupBox1.Controls.Add(this.txtAddress);
+ this.groupBox1.Controls.Add(this.label1);
+ resources.ApplyResources(this.groupBox1, "groupBox1");
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.TabStop = false;
+ //
+ // label13
+ //
+ resources.ApplyResources(this.label13, "label13");
+ this.label13.Name = "label13";
+ //
+ // cmbSecurity
+ //
+ this.cmbSecurity.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cmbSecurity.FormattingEnabled = true;
+ this.cmbSecurity.Items.AddRange(new object[] {
+ resources.GetString("cmbSecurity.Items"),
+ resources.GetString("cmbSecurity.Items1"),
+ resources.GetString("cmbSecurity.Items2"),
+ resources.GetString("cmbSecurity.Items3"),
+ resources.GetString("cmbSecurity.Items4"),
+ resources.GetString("cmbSecurity.Items5"),
+ resources.GetString("cmbSecurity.Items6"),
+ resources.GetString("cmbSecurity.Items7")});
+ resources.ApplyResources(this.cmbSecurity, "cmbSecurity");
+ this.cmbSecurity.Name = "cmbSecurity";
+ //
+ // txtRemarks
+ //
+ resources.ApplyResources(this.txtRemarks, "txtRemarks");
+ this.txtRemarks.Name = "txtRemarks";
+ //
+ // label6
+ //
+ resources.ApplyResources(this.label6, "label6");
+ this.label6.Name = "label6";
+ //
+ // label5
+ //
+ resources.ApplyResources(this.label5, "label5");
+ this.label5.Name = "label5";
+ //
+ // txtId
+ //
+ resources.ApplyResources(this.txtId, "txtId");
+ this.txtId.Name = "txtId";
+ //
+ // label3
+ //
+ resources.ApplyResources(this.label3, "label3");
+ this.label3.Name = "label3";
+ //
+ // txtPort
+ //
+ resources.ApplyResources(this.txtPort, "txtPort");
+ this.txtPort.Name = "txtPort";
+ //
+ // label2
+ //
+ resources.ApplyResources(this.label2, "label2");
+ this.label2.Name = "label2";
+ //
+ // txtAddress
+ //
+ resources.ApplyResources(this.txtAddress, "txtAddress");
+ this.txtAddress.Name = "txtAddress";
+ //
+ // label1
+ //
+ resources.ApplyResources(this.label1, "label1");
+ this.label1.Name = "label1";
+ //
+ // panel2
+ //
+ this.panel2.Controls.Add(this.btnClose);
+ this.panel2.Controls.Add(this.btnOK);
+ resources.ApplyResources(this.panel2, "panel2");
+ this.panel2.Name = "panel2";
+ //
+ // btnOK
+ //
+ resources.ApplyResources(this.btnOK, "btnOK");
+ this.btnOK.Name = "btnOK";
+ this.btnOK.UseVisualStyleBackColor = true;
+ this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
+ //
+ // panel1
+ //
+ resources.ApplyResources(this.panel1, "panel1");
+ this.panel1.Name = "panel1";
+ //
+ // menuServer
+ //
+ this.menuServer.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.MenuItem1});
+ resources.ApplyResources(this.menuServer, "menuServer");
+ this.menuServer.Name = "menuServer";
+ //
+ // MenuItem1
+ //
+ this.MenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.menuItemImportClipboard});
+ this.MenuItem1.Name = "MenuItem1";
+ resources.ApplyResources(this.MenuItem1, "MenuItem1");
+ //
+ // menuItemImportClipboard
+ //
+ this.menuItemImportClipboard.Name = "menuItemImportClipboard";
+ resources.ApplyResources(this.menuItemImportClipboard, "menuItemImportClipboard");
+ this.menuItemImportClipboard.Click += new System.EventHandler(this.menuItemImportClipboard_Click);
+ //
+ // AddServer3Form
+ //
+ resources.ApplyResources(this, "$this");
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.btnClose;
+ this.Controls.Add(this.groupBox1);
+ this.Controls.Add(this.panel2);
+ this.Controls.Add(this.panel1);
+ this.Controls.Add(this.menuServer);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MinimizeBox = true;
+ this.Name = "AddServer3Form";
+ this.Load += new System.EventHandler(this.AddServer3Form_Load);
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.panel2.ResumeLayout(false);
+ this.menuServer.ResumeLayout(false);
+ this.menuServer.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.Button btnClose;
+ private System.Windows.Forms.Button btnOK;
+ private System.Windows.Forms.TextBox txtRemarks;
+ private System.Windows.Forms.Label label6;
+ private System.Windows.Forms.Label label5;
+ private System.Windows.Forms.TextBox txtId;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.TextBox txtPort;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.TextBox txtAddress;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.ComboBox cmbSecurity;
+ private System.Windows.Forms.Panel panel1;
+ private System.Windows.Forms.Panel panel2;
+ private System.Windows.Forms.Label label13;
+ private System.Windows.Forms.MenuStrip menuServer;
+ private System.Windows.Forms.ToolStripMenuItem MenuItem1;
+ private System.Windows.Forms.ToolStripMenuItem menuItemImportClipboard;
+ }
+}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/AddServer3Form.cs b/v2rayN/v2rayN/Forms/AddServer3Form.cs
new file mode 100644
index 00000000..c39f2cfe
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServer3Form.cs
@@ -0,0 +1,143 @@
+using System;
+using System.Windows.Forms;
+using v2rayN.Handler;
+using v2rayN.Mode;
+
+namespace v2rayN.Forms
+{
+ public partial class AddServer3Form : BaseForm
+ {
+ public int EditIndex { get; set; }
+ VmessItem vmessItem = null;
+
+ public AddServer3Form()
+ {
+ InitializeComponent();
+ }
+
+ private void AddServer3Form_Load(object sender, EventArgs e)
+ {
+ if (EditIndex >= 0)
+ {
+ vmessItem = config.vmess[EditIndex];
+ BindingServer();
+ }
+ else
+ {
+ vmessItem = new VmessItem();
+ ClearServer();
+ }
+ }
+
+ ///
+ /// 绑定数据
+ ///
+ private void BindingServer()
+ {
+
+ txtAddress.Text = vmessItem.address;
+ txtPort.Text = vmessItem.port.ToString();
+ txtId.Text = vmessItem.id;
+ cmbSecurity.Text = vmessItem.security;
+ txtRemarks.Text = vmessItem.remarks;
+ }
+
+
+ ///
+ /// 清除设置
+ ///
+ private void ClearServer()
+ {
+ txtAddress.Text = "";
+ txtPort.Text = "";
+ txtId.Text = "";
+ cmbSecurity.Text = Global.DefaultSecurity;
+ txtRemarks.Text = "";
+ }
+
+ private void btnOK_Click(object sender, EventArgs e)
+ {
+ string address = txtAddress.Text;
+ string port = txtPort.Text;
+ string id = txtId.Text;
+ string security = cmbSecurity.Text;
+ string remarks = txtRemarks.Text;
+
+ if (Utils.IsNullOrEmpty(address))
+ {
+ UI.Show(UIRes.I18N("FillServerAddress"));
+ return;
+ }
+ if (Utils.IsNullOrEmpty(port) || !Utils.IsNumberic(port))
+ {
+ UI.Show(UIRes.I18N("FillCorrectServerPort"));
+ return;
+ }
+ if (Utils.IsNullOrEmpty(id))
+ {
+ UI.Show(UIRes.I18N("FillPassword"));
+ return;
+ }
+ if (Utils.IsNullOrEmpty(security))
+ {
+ UI.Show(UIRes.I18N("PleaseSelectEncryption"));
+ return;
+ }
+
+ vmessItem.address = address;
+ vmessItem.port = Utils.ToInt(port);
+ vmessItem.id = id;
+ vmessItem.security = security;
+ vmessItem.remarks = remarks;
+
+ if (ConfigHandler.AddShadowsocksServer(ref config, vmessItem, EditIndex) == 0)
+ {
+ this.DialogResult = DialogResult.OK;
+ }
+ else
+ {
+ UI.Show(UIRes.I18N("OperationFailed"));
+ }
+ }
+ private void btnClose_Click(object sender, EventArgs e)
+ {
+ this.DialogResult = DialogResult.Cancel;
+ }
+
+
+ #region 导入配置
+
+ ///
+ /// 从剪贴板导入URL
+ ///
+ ///
+ ///
+ private void menuItemImportClipboard_Click(object sender, EventArgs e)
+ {
+ ImportConfig();
+ }
+
+ private void ImportConfig()
+ {
+ ClearServer();
+
+ string msg;
+ VmessItem vmessItem = V2rayConfigHandler.ImportFromClipboardConfig(Utils.GetClipboardData(), out msg);
+ if (vmessItem == null)
+ {
+ UI.Show(msg);
+ return;
+ }
+
+ txtAddress.Text = vmessItem.address;
+ txtPort.Text = vmessItem.port.ToString();
+ cmbSecurity.Text = vmessItem.security;
+ txtId.Text = vmessItem.id;
+ txtRemarks.Text = vmessItem.remarks;
+ }
+
+ #endregion
+
+
+ }
+}
diff --git a/v2rayN/v2rayN/Forms/AddServer3Form.resx b/v2rayN/v2rayN/Forms/AddServer3Form.resx
new file mode 100644
index 00000000..f2f23bba
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServer3Form.resx
@@ -0,0 +1,606 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+ 396, 17
+
+
+ 75, 23
+
+
+
+ 4
+
+
+ &Cancel
+
+
+ btnClose
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel2
+
+
+ 0
+
+
+ True
+
+
+ 337, 158
+
+
+ 113, 12
+
+
+ 22
+
+
+ * Fill in manually
+
+
+ label13
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 0
+
+
+ aes-256-cfb
+
+
+ aes-128-cfb
+
+
+ chacha20
+
+
+ chacha20-ietf
+
+
+ aes-256-gcm
+
+
+ aes-128-gcm
+
+
+ chacha20-poly1305
+
+
+ chacha20-ietf-poly1305
+
+
+ 127, 120
+
+
+ 194, 20
+
+
+ 6
+
+
+ cmbSecurity
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 1
+
+
+ 127, 154
+
+
+ 194, 21
+
+
+ 11
+
+
+ txtRemarks
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 2
+
+
+ True
+
+
+ 12, 158
+
+
+ 95, 12
+
+
+ 10
+
+
+ Alias (remarks)
+
+
+ label6
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 3
+
+
+ True
+
+
+ 12, 124
+
+
+ 65, 12
+
+
+ 8
+
+
+ Encryption
+
+
+ label5
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 4
+
+
+ 127, 85
+
+
+ *
+
+
+ 278, 21
+
+
+ 5
+
+
+ txtId
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 5
+
+
+ True
+
+
+ 12, 89
+
+
+ 53, 12
+
+
+ 4
+
+
+ Password
+
+
+ label3
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 6
+
+
+ 127, 56
+
+
+ 194, 21
+
+
+ 3
+
+
+ txtPort
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 7
+
+
+ True
+
+
+ 12, 60
+
+
+ 71, 12
+
+
+ 2
+
+
+ Server port
+
+
+ label2
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 8
+
+
+ 127, 27
+
+
+ 359, 21
+
+
+ 1
+
+
+ txtAddress
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 9
+
+
+ True
+
+
+ 12, 31
+
+
+ 89, 12
+
+
+ 0
+
+
+ Server address
+
+
+ label1
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 10
+
+
+
+ Fill
+
+
+ 0, 35
+
+
+ 547, 196
+
+
+ 3
+
+
+ Server
+
+
+ groupBox1
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 0
+
+
+ 303, 17
+
+
+ 75, 23
+
+
+ 5
+
+
+ &OK
+
+
+ btnOK
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel2
+
+
+ 1
+
+
+ Bottom
+
+
+ 0, 231
+
+
+ 547, 60
+
+
+ 7
+
+
+ panel2
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 1
+
+
+ Top
+
+
+ 0, 25
+
+
+ 547, 10
+
+
+ 6
+
+
+ panel1
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 2
+
+
+ 17, 17
+
+
+ 235, 22
+
+
+ Import URL from clipboard
+
+
+ 162, 21
+
+
+ Import configuration file
+
+
+ 0, 0
+
+
+ 547, 25
+
+
+ 8
+
+
+ menuServer
+
+
+ System.Windows.Forms.MenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 3
+
+
+ True
+
+
+ 6, 12
+
+
+ 547, 291
+
+
+ Edit or add a [Shadowsocks] server
+
+
+ MenuItem1
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuItemImportClipboard
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ AddServer3Form
+
+
+ v2rayN.Forms.BaseForm, v2rayN, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/AddServer3Form.zh-Hans.resx b/v2rayN/v2rayN/Forms/AddServer3Form.zh-Hans.resx
new file mode 100644
index 00000000..2a5968ca
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServer3Form.zh-Hans.resx
@@ -0,0 +1,159 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 取消(&C)
+
+
+ *手填,方便识别管理
+
+
+ 别名(remarks)
+
+
+ 加密方式
+
+
+ 密码
+
+
+ 服务器端口
+
+
+ 服务器地址
+
+
+ 服务器
+
+
+ 确定(&O)
+
+
+ 从剪贴板导入URL
+
+
+ 扫描屏幕上的二维码
+
+
+ 导入配置文件
+
+
+ 编辑或添加[Shadowsocks]服务器
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/AddServer4Form.Designer.cs b/v2rayN/v2rayN/Forms/AddServer4Form.Designer.cs
new file mode 100644
index 00000000..3ae98f0b
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServer4Form.Designer.cs
@@ -0,0 +1,220 @@
+namespace v2rayN.Forms
+{
+ partial class AddServer4Form
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AddServer4Form));
+ this.btnClose = new System.Windows.Forms.Button();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.txtSecurity = new System.Windows.Forms.TextBox();
+ this.label4 = new System.Windows.Forms.Label();
+ this.txtId = new System.Windows.Forms.TextBox();
+ this.label3 = new System.Windows.Forms.Label();
+ this.label13 = new System.Windows.Forms.Label();
+ this.txtRemarks = new System.Windows.Forms.TextBox();
+ this.label6 = new System.Windows.Forms.Label();
+ this.txtPort = new System.Windows.Forms.TextBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.txtAddress = new System.Windows.Forms.TextBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.panel2 = new System.Windows.Forms.Panel();
+ this.btnOK = new System.Windows.Forms.Button();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.menuServer = new System.Windows.Forms.MenuStrip();
+ this.MenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuItemImportClipboard = new System.Windows.Forms.ToolStripMenuItem();
+ this.groupBox1.SuspendLayout();
+ this.panel2.SuspendLayout();
+ this.menuServer.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // btnClose
+ //
+ this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ resources.ApplyResources(this.btnClose, "btnClose");
+ this.btnClose.Name = "btnClose";
+ this.btnClose.UseVisualStyleBackColor = true;
+ this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
+ //
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.txtSecurity);
+ this.groupBox1.Controls.Add(this.label4);
+ this.groupBox1.Controls.Add(this.txtId);
+ this.groupBox1.Controls.Add(this.label3);
+ this.groupBox1.Controls.Add(this.label13);
+ this.groupBox1.Controls.Add(this.txtRemarks);
+ this.groupBox1.Controls.Add(this.label6);
+ this.groupBox1.Controls.Add(this.txtPort);
+ this.groupBox1.Controls.Add(this.label2);
+ this.groupBox1.Controls.Add(this.txtAddress);
+ this.groupBox1.Controls.Add(this.label1);
+ resources.ApplyResources(this.groupBox1, "groupBox1");
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.TabStop = false;
+ //
+ // txtSecurity
+ //
+ resources.ApplyResources(this.txtSecurity, "txtSecurity");
+ this.txtSecurity.Name = "txtSecurity";
+ //
+ // label4
+ //
+ resources.ApplyResources(this.label4, "label4");
+ this.label4.Name = "label4";
+ //
+ // txtId
+ //
+ resources.ApplyResources(this.txtId, "txtId");
+ this.txtId.Name = "txtId";
+ //
+ // label3
+ //
+ resources.ApplyResources(this.label3, "label3");
+ this.label3.Name = "label3";
+ //
+ // label13
+ //
+ resources.ApplyResources(this.label13, "label13");
+ this.label13.Name = "label13";
+ //
+ // txtRemarks
+ //
+ resources.ApplyResources(this.txtRemarks, "txtRemarks");
+ this.txtRemarks.Name = "txtRemarks";
+ //
+ // label6
+ //
+ resources.ApplyResources(this.label6, "label6");
+ this.label6.Name = "label6";
+ //
+ // txtPort
+ //
+ resources.ApplyResources(this.txtPort, "txtPort");
+ this.txtPort.Name = "txtPort";
+ //
+ // label2
+ //
+ resources.ApplyResources(this.label2, "label2");
+ this.label2.Name = "label2";
+ //
+ // txtAddress
+ //
+ resources.ApplyResources(this.txtAddress, "txtAddress");
+ this.txtAddress.Name = "txtAddress";
+ //
+ // label1
+ //
+ resources.ApplyResources(this.label1, "label1");
+ this.label1.Name = "label1";
+ //
+ // panel2
+ //
+ this.panel2.Controls.Add(this.btnClose);
+ this.panel2.Controls.Add(this.btnOK);
+ resources.ApplyResources(this.panel2, "panel2");
+ this.panel2.Name = "panel2";
+ //
+ // btnOK
+ //
+ resources.ApplyResources(this.btnOK, "btnOK");
+ this.btnOK.Name = "btnOK";
+ this.btnOK.UseVisualStyleBackColor = true;
+ this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
+ //
+ // panel1
+ //
+ resources.ApplyResources(this.panel1, "panel1");
+ this.panel1.Name = "panel1";
+ //
+ // menuServer
+ //
+ this.menuServer.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.MenuItem1});
+ resources.ApplyResources(this.menuServer, "menuServer");
+ this.menuServer.Name = "menuServer";
+ //
+ // MenuItem1
+ //
+ this.MenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.menuItemImportClipboard});
+ this.MenuItem1.Name = "MenuItem1";
+ resources.ApplyResources(this.MenuItem1, "MenuItem1");
+ //
+ // menuItemImportClipboard
+ //
+ this.menuItemImportClipboard.Name = "menuItemImportClipboard";
+ resources.ApplyResources(this.menuItemImportClipboard, "menuItemImportClipboard");
+ this.menuItemImportClipboard.Click += new System.EventHandler(this.menuItemImportClipboard_Click);
+ //
+ // AddServer4Form
+ //
+ resources.ApplyResources(this, "$this");
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.btnClose;
+ this.Controls.Add(this.groupBox1);
+ this.Controls.Add(this.panel2);
+ this.Controls.Add(this.panel1);
+ this.Controls.Add(this.menuServer);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MinimizeBox = true;
+ this.Name = "AddServer4Form";
+ this.Load += new System.EventHandler(this.AddServer4Form_Load);
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.panel2.ResumeLayout(false);
+ this.menuServer.ResumeLayout(false);
+ this.menuServer.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.Button btnClose;
+ private System.Windows.Forms.Button btnOK;
+ private System.Windows.Forms.TextBox txtRemarks;
+ private System.Windows.Forms.Label label6;
+ private System.Windows.Forms.TextBox txtPort;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.TextBox txtAddress;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Panel panel1;
+ private System.Windows.Forms.Panel panel2;
+ private System.Windows.Forms.Label label13;
+ private System.Windows.Forms.MenuStrip menuServer;
+ private System.Windows.Forms.ToolStripMenuItem MenuItem1;
+ private System.Windows.Forms.ToolStripMenuItem menuItemImportClipboard;
+ private System.Windows.Forms.TextBox txtId;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.TextBox txtSecurity;
+ private System.Windows.Forms.Label label4;
+ }
+}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/AddServer4Form.cs b/v2rayN/v2rayN/Forms/AddServer4Form.cs
new file mode 100644
index 00000000..d331bec2
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServer4Form.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Windows.Forms;
+using v2rayN.Handler;
+using v2rayN.Mode;
+
+namespace v2rayN.Forms
+{
+ public partial class AddServer4Form : BaseForm
+ {
+ public int EditIndex { get; set; }
+ VmessItem vmessItem = null;
+
+ public AddServer4Form()
+ {
+ InitializeComponent();
+ }
+
+ private void AddServer4Form_Load(object sender, EventArgs e)
+ {
+ if (EditIndex >= 0)
+ {
+ vmessItem = config.vmess[EditIndex];
+ BindingServer();
+ }
+ else
+ {
+ vmessItem = new VmessItem();
+ ClearServer();
+ }
+ }
+
+ ///
+ /// 绑定数据
+ ///
+ private void BindingServer()
+ {
+ txtAddress.Text = vmessItem.address;
+ txtPort.Text = vmessItem.port.ToString();
+ txtId.Text = vmessItem.id;
+ txtSecurity.Text = vmessItem.security;
+ txtRemarks.Text = vmessItem.remarks;
+ }
+
+
+ ///
+ /// 清除设置
+ ///
+ private void ClearServer()
+ {
+ txtAddress.Text = "";
+ txtPort.Text = "";
+ txtId.Text = "";
+ txtSecurity.Text = "";
+ txtRemarks.Text = "";
+ }
+
+ private void btnOK_Click(object sender, EventArgs e)
+ {
+ string address = txtAddress.Text;
+ string port = txtPort.Text;
+ string id = txtId.Text;
+ string security = txtSecurity.Text;
+ string remarks = txtRemarks.Text;
+
+ if (Utils.IsNullOrEmpty(address))
+ {
+ UI.Show(UIRes.I18N("FillServerAddress"));
+ return;
+ }
+ if (Utils.IsNullOrEmpty(port) || !Utils.IsNumberic(port))
+ {
+ UI.Show(UIRes.I18N("FillCorrectServerPort"));
+ return;
+ }
+
+ vmessItem.address = address;
+ vmessItem.port = Utils.ToInt(port);
+ vmessItem.id = id;
+ vmessItem.security = security;
+ vmessItem.remarks = remarks;
+
+ if (ConfigHandler.AddSocksServer(ref config, vmessItem, EditIndex) == 0)
+ {
+ this.DialogResult = DialogResult.OK;
+ }
+ else
+ {
+ UI.Show(UIRes.I18N("OperationFailed"));
+ }
+ }
+ private void btnClose_Click(object sender, EventArgs e)
+ {
+ this.DialogResult = DialogResult.Cancel;
+ }
+
+
+ #region 导入配置
+
+ ///
+ /// 从剪贴板导入URL
+ ///
+ ///
+ ///
+ private void menuItemImportClipboard_Click(object sender, EventArgs e)
+ {
+ ImportConfig();
+ }
+
+ private void ImportConfig()
+ {
+ ClearServer();
+
+ string msg;
+ VmessItem vmessItem = V2rayConfigHandler.ImportFromClipboardConfig(Utils.GetClipboardData(), out msg);
+ if (vmessItem == null)
+ {
+ UI.Show(msg);
+ return;
+ }
+
+ txtAddress.Text = vmessItem.address;
+ txtPort.Text = vmessItem.port.ToString();
+ txtSecurity.Text = vmessItem.security;
+ txtId.Text = vmessItem.id;
+ txtRemarks.Text = vmessItem.remarks;
+ }
+
+ #endregion
+
+
+ }
+}
diff --git a/v2rayN/v2rayN/Forms/AddServer4Form.resx b/v2rayN/v2rayN/Forms/AddServer4Form.resx
new file mode 100644
index 00000000..566de4b3
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServer4Form.resx
@@ -0,0 +1,588 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+ 396, 17
+
+
+ 75, 23
+
+
+
+ 4
+
+
+ &Cancel
+
+
+ btnClose
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel2
+
+
+ 0
+
+
+ 127, 84
+
+
+ 278, 21
+
+
+ 26
+
+
+ txtSecurity
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 0
+
+
+ True
+
+
+
+ NoControl
+
+
+ 12, 88
+
+
+ 89, 12
+
+
+ 25
+
+
+ User(Optional)
+
+
+ label4
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 1
+
+
+ 127, 117
+
+
+ *
+
+
+ 278, 21
+
+
+ 24
+
+
+ txtId
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 2
+
+
+ True
+
+
+ NoControl
+
+
+ 12, 121
+
+
+ 113, 12
+
+
+ 23
+
+
+ Password(Optional)
+
+
+ label3
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 3
+
+
+ True
+
+
+ 337, 158
+
+
+ 113, 12
+
+
+ 22
+
+
+ * Fill in manually
+
+
+ label13
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 4
+
+
+ 127, 154
+
+
+ 194, 21
+
+
+ 11
+
+
+ txtRemarks
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 5
+
+
+ True
+
+
+ 12, 158
+
+
+ 95, 12
+
+
+ 10
+
+
+ Alias (remarks)
+
+
+ label6
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 6
+
+
+ 127, 56
+
+
+ 194, 21
+
+
+ 3
+
+
+ txtPort
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 7
+
+
+ True
+
+
+ 12, 60
+
+
+ 71, 12
+
+
+ 2
+
+
+ Server port
+
+
+ label2
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 8
+
+
+ 127, 27
+
+
+ 359, 21
+
+
+ 1
+
+
+ txtAddress
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 9
+
+
+ True
+
+
+ 12, 31
+
+
+ 89, 12
+
+
+ 0
+
+
+ Server address
+
+
+ label1
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 10
+
+
+ Fill
+
+
+ 0, 35
+
+
+ 547, 196
+
+
+ 3
+
+
+ Server
+
+
+ groupBox1
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 0
+
+
+ 303, 17
+
+
+ 75, 23
+
+
+ 5
+
+
+ &OK
+
+
+ btnOK
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel2
+
+
+ 1
+
+
+ Bottom
+
+
+ 0, 231
+
+
+ 547, 60
+
+
+ 7
+
+
+ panel2
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 1
+
+
+ Top
+
+
+ 0, 25
+
+
+ 547, 10
+
+
+ 6
+
+
+ panel1
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 2
+
+
+ 17, 17
+
+
+ 235, 22
+
+
+ Import URL from clipboard
+
+
+ 162, 21
+
+
+ Import configuration file
+
+
+ 0, 0
+
+
+ 547, 25
+
+
+ 8
+
+
+ menuServer
+
+
+ System.Windows.Forms.MenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 3
+
+
+ True
+
+
+ 6, 12
+
+
+ 547, 291
+
+
+ Edit or add a [Socks] server
+
+
+ MenuItem1
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuItemImportClipboard
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ AddServer4Form
+
+
+ v2rayN.Forms.BaseForm, v2rayN, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/AddServer4Form.zh-Hans.resx b/v2rayN/v2rayN/Forms/AddServer4Form.zh-Hans.resx
new file mode 100644
index 00000000..6a3cc081
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServer4Form.zh-Hans.resx
@@ -0,0 +1,190 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 取消(&C)
+
+
+ 服务器
+
+
+
+ 127, 85
+
+
+ 12, 89
+
+
+ 77, 12
+
+
+ 用户名(可选)
+
+
+ 127, 115
+
+
+ 12, 119
+
+
+ 65, 12
+
+
+ 密码(可选)
+
+
+ *手填,方便识别管理
+
+
+ 83, 12
+
+
+ 别名(remarks)
+
+
+ 65, 12
+
+
+ 服务器端口
+
+
+ 65, 12
+
+
+ 服务器地址
+
+
+ 确定(&O)
+
+
+ 92, 21
+
+
+ 导入配置文件
+
+
+ 171, 22
+
+
+ 从剪贴板导入URL
+
+
+ 编辑或添加[Socks]服务器
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/AddServerForm.Designer.cs b/v2rayN/v2rayN/Forms/AddServerForm.Designer.cs
new file mode 100644
index 00000000..c398397b
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServerForm.Designer.cs
@@ -0,0 +1,516 @@
+namespace v2rayN.Forms
+{
+ partial class AddServerForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AddServerForm));
+ this.btnClose = new System.Windows.Forms.Button();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.btnGUID = new System.Windows.Forms.Button();
+ this.label13 = new System.Windows.Forms.Label();
+ this.groupBox2 = new System.Windows.Forms.GroupBox();
+ this.label24 = new System.Windows.Forms.Label();
+ this.label23 = new System.Windows.Forms.Label();
+ this.panTlsMore = new System.Windows.Forms.Panel();
+ this.label22 = new System.Windows.Forms.Label();
+ this.label21 = new System.Windows.Forms.Label();
+ this.cmbAllowInsecure = new System.Windows.Forms.ComboBox();
+ this.label20 = new System.Windows.Forms.Label();
+ this.txtPath = new System.Windows.Forms.TextBox();
+ this.label19 = new System.Windows.Forms.Label();
+ this.label18 = new System.Windows.Forms.Label();
+ this.label17 = new System.Windows.Forms.Label();
+ this.label16 = new System.Windows.Forms.Label();
+ this.label14 = new System.Windows.Forms.Label();
+ this.label15 = new System.Windows.Forms.Label();
+ this.cmbStreamSecurity = new System.Windows.Forms.ComboBox();
+ this.label12 = new System.Windows.Forms.Label();
+ this.txtRequestHost = new System.Windows.Forms.TextBox();
+ this.label11 = new System.Windows.Forms.Label();
+ this.label10 = new System.Windows.Forms.Label();
+ this.cmbHeaderType = new System.Windows.Forms.ComboBox();
+ this.label9 = new System.Windows.Forms.Label();
+ this.label8 = new System.Windows.Forms.Label();
+ this.cmbNetwork = new System.Windows.Forms.ComboBox();
+ this.label7 = new System.Windows.Forms.Label();
+ this.cmbSecurity = new System.Windows.Forms.ComboBox();
+ this.txtRemarks = new System.Windows.Forms.TextBox();
+ this.label6 = new System.Windows.Forms.Label();
+ this.label5 = new System.Windows.Forms.Label();
+ this.txtAlterId = new System.Windows.Forms.TextBox();
+ this.label4 = new System.Windows.Forms.Label();
+ this.txtId = new System.Windows.Forms.TextBox();
+ this.label3 = new System.Windows.Forms.Label();
+ this.txtPort = new System.Windows.Forms.TextBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.txtAddress = new System.Windows.Forms.TextBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.panel2 = new System.Windows.Forms.Panel();
+ this.btnOK = new System.Windows.Forms.Button();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.menuServer = new System.Windows.Forms.MenuStrip();
+ this.MenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
+ this.MenuItemImportClient = new System.Windows.Forms.ToolStripMenuItem();
+ this.MenuItemImportServer = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
+ this.MenuItemImportClipboard = new System.Windows.Forms.ToolStripMenuItem();
+ this.groupBox1.SuspendLayout();
+ this.groupBox2.SuspendLayout();
+ this.panTlsMore.SuspendLayout();
+ this.panel2.SuspendLayout();
+ this.menuServer.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // btnClose
+ //
+ this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ resources.ApplyResources(this.btnClose, "btnClose");
+ this.btnClose.Name = "btnClose";
+ this.btnClose.UseVisualStyleBackColor = true;
+ this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
+ //
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.btnGUID);
+ this.groupBox1.Controls.Add(this.label13);
+ this.groupBox1.Controls.Add(this.groupBox2);
+ this.groupBox1.Controls.Add(this.label9);
+ this.groupBox1.Controls.Add(this.label8);
+ this.groupBox1.Controls.Add(this.cmbNetwork);
+ this.groupBox1.Controls.Add(this.label7);
+ this.groupBox1.Controls.Add(this.cmbSecurity);
+ this.groupBox1.Controls.Add(this.txtRemarks);
+ this.groupBox1.Controls.Add(this.label6);
+ this.groupBox1.Controls.Add(this.label5);
+ this.groupBox1.Controls.Add(this.txtAlterId);
+ this.groupBox1.Controls.Add(this.label4);
+ this.groupBox1.Controls.Add(this.txtId);
+ this.groupBox1.Controls.Add(this.label3);
+ this.groupBox1.Controls.Add(this.txtPort);
+ this.groupBox1.Controls.Add(this.label2);
+ this.groupBox1.Controls.Add(this.txtAddress);
+ this.groupBox1.Controls.Add(this.label1);
+ resources.ApplyResources(this.groupBox1, "groupBox1");
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.TabStop = false;
+ //
+ // btnGUID
+ //
+ resources.ApplyResources(this.btnGUID, "btnGUID");
+ this.btnGUID.Name = "btnGUID";
+ this.btnGUID.UseVisualStyleBackColor = true;
+ this.btnGUID.Click += new System.EventHandler(this.btnGUID_Click);
+ //
+ // label13
+ //
+ resources.ApplyResources(this.label13, "label13");
+ this.label13.Name = "label13";
+ //
+ // groupBox2
+ //
+ this.groupBox2.Controls.Add(this.label24);
+ this.groupBox2.Controls.Add(this.label23);
+ this.groupBox2.Controls.Add(this.panTlsMore);
+ this.groupBox2.Controls.Add(this.label20);
+ this.groupBox2.Controls.Add(this.txtPath);
+ this.groupBox2.Controls.Add(this.label19);
+ this.groupBox2.Controls.Add(this.label18);
+ this.groupBox2.Controls.Add(this.label17);
+ this.groupBox2.Controls.Add(this.label16);
+ this.groupBox2.Controls.Add(this.label14);
+ this.groupBox2.Controls.Add(this.label15);
+ this.groupBox2.Controls.Add(this.cmbStreamSecurity);
+ this.groupBox2.Controls.Add(this.label12);
+ this.groupBox2.Controls.Add(this.txtRequestHost);
+ this.groupBox2.Controls.Add(this.label11);
+ this.groupBox2.Controls.Add(this.label10);
+ this.groupBox2.Controls.Add(this.cmbHeaderType);
+ resources.ApplyResources(this.groupBox2, "groupBox2");
+ this.groupBox2.Name = "groupBox2";
+ this.groupBox2.TabStop = false;
+ //
+ // label24
+ //
+ resources.ApplyResources(this.label24, "label24");
+ this.label24.Name = "label24";
+ //
+ // label23
+ //
+ resources.ApplyResources(this.label23, "label23");
+ this.label23.Name = "label23";
+ //
+ // panTlsMore
+ //
+ this.panTlsMore.Controls.Add(this.label22);
+ this.panTlsMore.Controls.Add(this.label21);
+ this.panTlsMore.Controls.Add(this.cmbAllowInsecure);
+ resources.ApplyResources(this.panTlsMore, "panTlsMore");
+ this.panTlsMore.Name = "panTlsMore";
+ //
+ // label22
+ //
+ resources.ApplyResources(this.label22, "label22");
+ this.label22.Name = "label22";
+ //
+ // label21
+ //
+ resources.ApplyResources(this.label21, "label21");
+ this.label21.Name = "label21";
+ //
+ // cmbAllowInsecure
+ //
+ this.cmbAllowInsecure.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cmbAllowInsecure.FormattingEnabled = true;
+ this.cmbAllowInsecure.Items.AddRange(new object[] {
+ resources.GetString("cmbAllowInsecure.Items"),
+ resources.GetString("cmbAllowInsecure.Items1"),
+ resources.GetString("cmbAllowInsecure.Items2")});
+ resources.ApplyResources(this.cmbAllowInsecure, "cmbAllowInsecure");
+ this.cmbAllowInsecure.Name = "cmbAllowInsecure";
+ //
+ // label20
+ //
+ resources.ApplyResources(this.label20, "label20");
+ this.label20.Name = "label20";
+ //
+ // txtPath
+ //
+ resources.ApplyResources(this.txtPath, "txtPath");
+ this.txtPath.Name = "txtPath";
+ //
+ // label19
+ //
+ resources.ApplyResources(this.label19, "label19");
+ this.label19.Name = "label19";
+ //
+ // label18
+ //
+ resources.ApplyResources(this.label18, "label18");
+ this.label18.Name = "label18";
+ //
+ // label17
+ //
+ resources.ApplyResources(this.label17, "label17");
+ this.label17.Name = "label17";
+ //
+ // label16
+ //
+ resources.ApplyResources(this.label16, "label16");
+ this.label16.Name = "label16";
+ //
+ // label14
+ //
+ resources.ApplyResources(this.label14, "label14");
+ this.label14.Name = "label14";
+ //
+ // label15
+ //
+ resources.ApplyResources(this.label15, "label15");
+ this.label15.Name = "label15";
+ //
+ // cmbStreamSecurity
+ //
+ this.cmbStreamSecurity.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cmbStreamSecurity.FormattingEnabled = true;
+ this.cmbStreamSecurity.Items.AddRange(new object[] {
+ resources.GetString("cmbStreamSecurity.Items"),
+ resources.GetString("cmbStreamSecurity.Items1")});
+ resources.ApplyResources(this.cmbStreamSecurity, "cmbStreamSecurity");
+ this.cmbStreamSecurity.Name = "cmbStreamSecurity";
+ this.cmbStreamSecurity.SelectedIndexChanged += new System.EventHandler(this.cmbStreamSecurity_SelectedIndexChanged);
+ //
+ // label12
+ //
+ resources.ApplyResources(this.label12, "label12");
+ this.label12.Name = "label12";
+ //
+ // txtRequestHost
+ //
+ resources.ApplyResources(this.txtRequestHost, "txtRequestHost");
+ this.txtRequestHost.Name = "txtRequestHost";
+ //
+ // label11
+ //
+ resources.ApplyResources(this.label11, "label11");
+ this.label11.Name = "label11";
+ //
+ // label10
+ //
+ resources.ApplyResources(this.label10, "label10");
+ this.label10.Name = "label10";
+ //
+ // cmbHeaderType
+ //
+ this.cmbHeaderType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cmbHeaderType.FormattingEnabled = true;
+ this.cmbHeaderType.Items.AddRange(new object[] {
+ resources.GetString("cmbHeaderType.Items"),
+ resources.GetString("cmbHeaderType.Items1"),
+ resources.GetString("cmbHeaderType.Items2"),
+ resources.GetString("cmbHeaderType.Items3"),
+ resources.GetString("cmbHeaderType.Items4"),
+ resources.GetString("cmbHeaderType.Items5"),
+ resources.GetString("cmbHeaderType.Items6")});
+ resources.ApplyResources(this.cmbHeaderType, "cmbHeaderType");
+ this.cmbHeaderType.Name = "cmbHeaderType";
+ //
+ // label9
+ //
+ resources.ApplyResources(this.label9, "label9");
+ this.label9.Name = "label9";
+ //
+ // label8
+ //
+ resources.ApplyResources(this.label8, "label8");
+ this.label8.Name = "label8";
+ //
+ // cmbNetwork
+ //
+ this.cmbNetwork.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cmbNetwork.FormattingEnabled = true;
+ this.cmbNetwork.Items.AddRange(new object[] {
+ resources.GetString("cmbNetwork.Items"),
+ resources.GetString("cmbNetwork.Items1"),
+ resources.GetString("cmbNetwork.Items2"),
+ resources.GetString("cmbNetwork.Items3"),
+ resources.GetString("cmbNetwork.Items4")});
+ resources.ApplyResources(this.cmbNetwork, "cmbNetwork");
+ this.cmbNetwork.Name = "cmbNetwork";
+ this.cmbNetwork.SelectedIndexChanged += new System.EventHandler(this.cmbNetwork_SelectedIndexChanged);
+ //
+ // label7
+ //
+ resources.ApplyResources(this.label7, "label7");
+ this.label7.Name = "label7";
+ //
+ // cmbSecurity
+ //
+ this.cmbSecurity.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cmbSecurity.FormattingEnabled = true;
+ this.cmbSecurity.Items.AddRange(new object[] {
+ resources.GetString("cmbSecurity.Items"),
+ resources.GetString("cmbSecurity.Items1"),
+ resources.GetString("cmbSecurity.Items2"),
+ resources.GetString("cmbSecurity.Items3")});
+ resources.ApplyResources(this.cmbSecurity, "cmbSecurity");
+ this.cmbSecurity.Name = "cmbSecurity";
+ //
+ // txtRemarks
+ //
+ resources.ApplyResources(this.txtRemarks, "txtRemarks");
+ this.txtRemarks.Name = "txtRemarks";
+ //
+ // label6
+ //
+ resources.ApplyResources(this.label6, "label6");
+ this.label6.Name = "label6";
+ //
+ // label5
+ //
+ resources.ApplyResources(this.label5, "label5");
+ this.label5.Name = "label5";
+ //
+ // txtAlterId
+ //
+ resources.ApplyResources(this.txtAlterId, "txtAlterId");
+ this.txtAlterId.Name = "txtAlterId";
+ //
+ // label4
+ //
+ resources.ApplyResources(this.label4, "label4");
+ this.label4.Name = "label4";
+ //
+ // txtId
+ //
+ resources.ApplyResources(this.txtId, "txtId");
+ this.txtId.Name = "txtId";
+ //
+ // label3
+ //
+ resources.ApplyResources(this.label3, "label3");
+ this.label3.Name = "label3";
+ //
+ // txtPort
+ //
+ resources.ApplyResources(this.txtPort, "txtPort");
+ this.txtPort.Name = "txtPort";
+ //
+ // label2
+ //
+ resources.ApplyResources(this.label2, "label2");
+ this.label2.Name = "label2";
+ //
+ // txtAddress
+ //
+ resources.ApplyResources(this.txtAddress, "txtAddress");
+ this.txtAddress.Name = "txtAddress";
+ //
+ // label1
+ //
+ resources.ApplyResources(this.label1, "label1");
+ this.label1.Name = "label1";
+ //
+ // panel2
+ //
+ this.panel2.Controls.Add(this.btnClose);
+ this.panel2.Controls.Add(this.btnOK);
+ resources.ApplyResources(this.panel2, "panel2");
+ this.panel2.Name = "panel2";
+ //
+ // btnOK
+ //
+ resources.ApplyResources(this.btnOK, "btnOK");
+ this.btnOK.Name = "btnOK";
+ this.btnOK.UseVisualStyleBackColor = true;
+ this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
+ //
+ // panel1
+ //
+ resources.ApplyResources(this.panel1, "panel1");
+ this.panel1.Name = "panel1";
+ //
+ // menuServer
+ //
+ this.menuServer.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.MenuItem1});
+ resources.ApplyResources(this.menuServer, "menuServer");
+ this.menuServer.Name = "menuServer";
+ //
+ // MenuItem1
+ //
+ this.MenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.MenuItemImportClient,
+ this.MenuItemImportServer,
+ this.toolStripSeparator1,
+ this.MenuItemImportClipboard});
+ this.MenuItem1.Name = "MenuItem1";
+ resources.ApplyResources(this.MenuItem1, "MenuItem1");
+ //
+ // MenuItemImportClient
+ //
+ this.MenuItemImportClient.Name = "MenuItemImportClient";
+ resources.ApplyResources(this.MenuItemImportClient, "MenuItemImportClient");
+ this.MenuItemImportClient.Click += new System.EventHandler(this.MenuItemImportClient_Click);
+ //
+ // MenuItemImportServer
+ //
+ this.MenuItemImportServer.Name = "MenuItemImportServer";
+ resources.ApplyResources(this.MenuItemImportServer, "MenuItemImportServer");
+ this.MenuItemImportServer.Click += new System.EventHandler(this.MenuItemImportServer_Click);
+ //
+ // toolStripSeparator1
+ //
+ this.toolStripSeparator1.Name = "toolStripSeparator1";
+ resources.ApplyResources(this.toolStripSeparator1, "toolStripSeparator1");
+ //
+ // MenuItemImportClipboard
+ //
+ this.MenuItemImportClipboard.Name = "MenuItemImportClipboard";
+ resources.ApplyResources(this.MenuItemImportClipboard, "MenuItemImportClipboard");
+ this.MenuItemImportClipboard.Click += new System.EventHandler(this.MenuItemImportClipboard_Click);
+ //
+ // AddServerForm
+ //
+ resources.ApplyResources(this, "$this");
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.btnClose;
+ this.Controls.Add(this.groupBox1);
+ this.Controls.Add(this.panel2);
+ this.Controls.Add(this.panel1);
+ this.Controls.Add(this.menuServer);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.Name = "AddServerForm";
+ this.Load += new System.EventHandler(this.AddServerForm_Load);
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.groupBox2.ResumeLayout(false);
+ this.groupBox2.PerformLayout();
+ this.panTlsMore.ResumeLayout(false);
+ this.panTlsMore.PerformLayout();
+ this.panel2.ResumeLayout(false);
+ this.menuServer.ResumeLayout(false);
+ this.menuServer.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.Button btnClose;
+ private System.Windows.Forms.Button btnOK;
+ private System.Windows.Forms.TextBox txtRemarks;
+ private System.Windows.Forms.Label label6;
+ private System.Windows.Forms.Label label5;
+ private System.Windows.Forms.TextBox txtAlterId;
+ private System.Windows.Forms.Label label4;
+ private System.Windows.Forms.TextBox txtId;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.TextBox txtPort;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.TextBox txtAddress;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.ComboBox cmbSecurity;
+ private System.Windows.Forms.ComboBox cmbNetwork;
+ private System.Windows.Forms.Label label7;
+ private System.Windows.Forms.Label label9;
+ private System.Windows.Forms.Label label8;
+ private System.Windows.Forms.Panel panel1;
+ private System.Windows.Forms.Panel panel2;
+ private System.Windows.Forms.TextBox txtRequestHost;
+ private System.Windows.Forms.Label label10;
+ private System.Windows.Forms.Label label11;
+ private System.Windows.Forms.ComboBox cmbHeaderType;
+ private System.Windows.Forms.Label label12;
+ private System.Windows.Forms.GroupBox groupBox2;
+ private System.Windows.Forms.Label label13;
+ private System.Windows.Forms.MenuStrip menuServer;
+ private System.Windows.Forms.ToolStripMenuItem MenuItem1;
+ private System.Windows.Forms.ToolStripMenuItem MenuItemImportClient;
+ private System.Windows.Forms.ToolStripMenuItem MenuItemImportServer;
+ private System.Windows.Forms.Label label15;
+ private System.Windows.Forms.ComboBox cmbStreamSecurity;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
+ private System.Windows.Forms.ToolStripMenuItem MenuItemImportClipboard;
+ private System.Windows.Forms.Button btnGUID;
+ private System.Windows.Forms.Label label16;
+ private System.Windows.Forms.Label label14;
+ private System.Windows.Forms.Label label17;
+ private System.Windows.Forms.Label label18;
+ private System.Windows.Forms.Label label19;
+ private System.Windows.Forms.TextBox txtPath;
+ private System.Windows.Forms.Label label20;
+ private System.Windows.Forms.Label label21;
+ private System.Windows.Forms.ComboBox cmbAllowInsecure;
+ private System.Windows.Forms.Label label22;
+ private System.Windows.Forms.Panel panTlsMore;
+ private System.Windows.Forms.Label label24;
+ private System.Windows.Forms.Label label23;
+ }
+}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/AddServerForm.cs b/v2rayN/v2rayN/Forms/AddServerForm.cs
new file mode 100644
index 00000000..816b7013
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServerForm.cs
@@ -0,0 +1,293 @@
+using System;
+using System.Windows.Forms;
+using v2rayN.Handler;
+using v2rayN.Mode;
+
+namespace v2rayN.Forms
+{
+ public partial class AddServerForm : BaseForm
+ {
+ public int EditIndex { get; set; }
+ VmessItem vmessItem = null;
+
+ public AddServerForm()
+ {
+ InitializeComponent();
+ }
+
+ private void AddServerForm_Load(object sender, EventArgs e)
+ {
+ if (EditIndex >= 0)
+ {
+ vmessItem = config.vmess[EditIndex];
+ BindingServer();
+ }
+ else
+ {
+ vmessItem = new VmessItem();
+ ClearServer();
+ }
+ }
+
+ ///
+ /// 绑定数据
+ ///
+ private void BindingServer()
+ {
+ txtAddress.Text = vmessItem.address;
+ txtPort.Text = vmessItem.port.ToString();
+ txtId.Text = vmessItem.id;
+ txtAlterId.Text = vmessItem.alterId.ToString();
+ cmbSecurity.Text = vmessItem.security;
+ cmbNetwork.Text = vmessItem.network;
+ txtRemarks.Text = vmessItem.remarks;
+
+ cmbHeaderType.Text = vmessItem.headerType;
+ txtRequestHost.Text = vmessItem.requestHost;
+ txtPath.Text = vmessItem.path;
+ cmbStreamSecurity.Text = vmessItem.streamSecurity;
+ cmbAllowInsecure.Text = vmessItem.allowInsecure;
+ }
+
+
+ ///
+ /// 清除设置
+ ///
+ private void ClearServer()
+ {
+ txtAddress.Text = "";
+ txtPort.Text = "";
+ txtId.Text = "";
+ txtAlterId.Text = "0";
+ cmbSecurity.Text = Global.DefaultSecurity;
+ cmbNetwork.Text = Global.DefaultNetwork;
+ txtRemarks.Text = "";
+
+ cmbHeaderType.Text = Global.None;
+ txtRequestHost.Text = "";
+ cmbStreamSecurity.Text = "";
+ cmbAllowInsecure.Text = "";
+ txtPath.Text = "";
+ }
+
+
+ private void cmbNetwork_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ SetHeaderType();
+ }
+
+ ///
+ /// 设置伪装选项
+ ///
+ private void SetHeaderType()
+ {
+ cmbHeaderType.Items.Clear();
+
+ string network = cmbNetwork.Text;
+ if (Utils.IsNullOrEmpty(network))
+ {
+ cmbHeaderType.Items.Add(Global.None);
+ return;
+ }
+
+ cmbHeaderType.Items.Add(Global.None);
+ if (network.Equals(Global.DefaultNetwork))
+ {
+ cmbHeaderType.Items.Add(Global.TcpHeaderHttp);
+ }
+ else if (network.Equals("kcp") || network.Equals("quic"))
+ {
+ cmbHeaderType.Items.Add("srtp");
+ cmbHeaderType.Items.Add("utp");
+ cmbHeaderType.Items.Add("wechat-video");
+ cmbHeaderType.Items.Add("dtls");
+ cmbHeaderType.Items.Add("wireguard");
+ }
+ else
+ {
+ }
+ cmbHeaderType.Text = Global.None;
+ }
+
+ private void btnOK_Click(object sender, EventArgs e)
+ {
+ string address = txtAddress.Text;
+ string port = txtPort.Text;
+ string id = txtId.Text;
+ string alterId = txtAlterId.Text;
+ string security = cmbSecurity.Text;
+ string network = cmbNetwork.Text;
+ string remarks = txtRemarks.Text;
+
+ string headerType = cmbHeaderType.Text;
+ string requestHost = txtRequestHost.Text;
+ string path = txtPath.Text;
+ string streamSecurity = cmbStreamSecurity.Text;
+ string allowInsecure = cmbAllowInsecure.Text;
+
+ if (Utils.IsNullOrEmpty(address))
+ {
+ UI.Show(UIRes.I18N("FillServerAddress"));
+ return;
+ }
+ if (Utils.IsNullOrEmpty(port) || !Utils.IsNumberic(port))
+ {
+ UI.Show(UIRes.I18N("FillCorrectServerPort"));
+ return;
+ }
+ if (Utils.IsNullOrEmpty(id))
+ {
+ UI.Show(UIRes.I18N("FillUUID"));
+ return;
+ }
+ if (Utils.IsNullOrEmpty(alterId) || !Utils.IsNumberic(alterId))
+ {
+ UI.Show(UIRes.I18N("FillCorrectAlterId"));
+ return;
+ }
+
+ vmessItem.address = address;
+ vmessItem.port = Utils.ToInt(port);
+ vmessItem.id = id;
+ vmessItem.alterId = Utils.ToInt(alterId);
+ vmessItem.security = security;
+ vmessItem.network = network;
+ vmessItem.remarks = remarks;
+
+ vmessItem.headerType = headerType;
+ vmessItem.requestHost = requestHost.Replace(" ", "");
+ vmessItem.path = path.Replace(" ", "");
+ vmessItem.streamSecurity = streamSecurity;
+ vmessItem.allowInsecure = allowInsecure;
+
+ if (ConfigHandler.AddServer(ref config, vmessItem, EditIndex) == 0)
+ {
+ this.DialogResult = DialogResult.OK;
+ }
+ else
+ {
+ UI.Show(UIRes.I18N("OperationFailed"));
+ }
+ }
+
+ private void btnGUID_Click(object sender, EventArgs e)
+ {
+ txtId.Text = Utils.GetGUID();
+ }
+
+ private void btnClose_Click(object sender, EventArgs e)
+ {
+ this.DialogResult = DialogResult.Cancel;
+ }
+
+
+ #region 导入客户端/服务端配置
+
+ ///
+ /// 导入客户端
+ ///
+ ///
+ ///
+ private void MenuItemImportClient_Click(object sender, EventArgs e)
+ {
+ MenuItemImport(1);
+ }
+
+ ///
+ /// 导入服务端
+ ///
+ ///
+ ///
+ private void MenuItemImportServer_Click(object sender, EventArgs e)
+ {
+ MenuItemImport(2);
+ }
+
+ private void MenuItemImport(int type)
+ {
+ ClearServer();
+
+ OpenFileDialog fileDialog = new OpenFileDialog();
+ fileDialog.Multiselect = false;
+ fileDialog.Filter = "Config|*.json|All|*.*";
+ if (fileDialog.ShowDialog() != DialogResult.OK)
+ {
+ return;
+ }
+ string fileName = fileDialog.FileName;
+ if (Utils.IsNullOrEmpty(fileName))
+ {
+ return;
+ }
+ string msg;
+ VmessItem vmessItem;
+ if (type.Equals(1))
+ {
+ vmessItem = V2rayConfigHandler.ImportFromClientConfig(fileName, out msg);
+ }
+ else
+ {
+ vmessItem = V2rayConfigHandler.ImportFromServerConfig(fileName, out msg);
+ }
+ if (vmessItem == null)
+ {
+ UI.Show(msg);
+ return;
+ }
+
+ txtAddress.Text = vmessItem.address;
+ txtPort.Text = vmessItem.port.ToString();
+ txtId.Text = vmessItem.id;
+ txtAlterId.Text = vmessItem.alterId.ToString();
+ txtRemarks.Text = vmessItem.remarks;
+ cmbNetwork.Text = vmessItem.network;
+ cmbHeaderType.Text = vmessItem.headerType;
+ txtRequestHost.Text = vmessItem.requestHost;
+ txtPath.Text = vmessItem.path;
+ cmbStreamSecurity.Text = vmessItem.streamSecurity;
+ }
+
+ ///
+ /// 从剪贴板导入URL
+ ///
+ ///
+ ///
+ private void MenuItemImportClipboard_Click(object sender, EventArgs e)
+ {
+ ClearServer();
+
+ string msg;
+ VmessItem vmessItem = V2rayConfigHandler.ImportFromClipboardConfig(Utils.GetClipboardData(), out msg);
+ if (vmessItem == null)
+ {
+ UI.Show(msg);
+ return;
+ }
+
+ txtAddress.Text = vmessItem.address;
+ txtPort.Text = vmessItem.port.ToString();
+ txtId.Text = vmessItem.id;
+ txtAlterId.Text = vmessItem.alterId.ToString();
+ txtRemarks.Text = vmessItem.remarks;
+ cmbNetwork.Text = vmessItem.network;
+ cmbHeaderType.Text = vmessItem.headerType;
+ txtRequestHost.Text = vmessItem.requestHost;
+ txtPath.Text = vmessItem.path;
+ cmbStreamSecurity.Text = vmessItem.streamSecurity;
+ }
+ #endregion
+
+ private void cmbStreamSecurity_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ string security = cmbStreamSecurity.Text;
+ if (Utils.IsNullOrEmpty(security))
+ {
+ panTlsMore.Hide();
+ }
+ else
+ {
+ panTlsMore.Show();
+ }
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/Forms/AddServerForm.resx b/v2rayN/v2rayN/Forms/AddServerForm.resx
new file mode 100644
index 00000000..e519eab6
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServerForm.resx
@@ -0,0 +1,1392 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+ 396, 17
+
+
+ 75, 23
+
+
+
+ 4
+
+
+ &Cancel
+
+
+ btnClose
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel2
+
+
+ 0
+
+
+ 411, 83
+
+
+ 75, 23
+
+
+ 23
+
+
+ &Generate
+
+
+ btnGUID
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 0
+
+
+ True
+
+
+ 285, 203
+
+
+ 113, 12
+
+
+ 22
+
+
+ * Fill in manually
+
+
+ label13
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 1
+
+
+ True
+
+
+
+ NoControl
+
+
+ 526, 165
+
+
+ 65, 12
+
+
+ 35
+
+
+ 3)QUIC key
+
+
+ label24
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 0
+
+
+ True
+
+
+ NoControl
+
+
+ 470, 99
+
+
+ 89, 12
+
+
+ 34
+
+
+ 4)QUIC securty
+
+
+ label23
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 1
+
+
+ True
+
+
+ 205, 11
+
+
+ 113, 12
+
+
+ 32
+
+
+ Default value true
+
+
+ label22
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panTlsMore
+
+
+ 0
+
+
+ True
+
+
+ 12, 11
+
+
+ 83, 12
+
+
+ 31
+
+
+ allowInsecure
+
+
+ label21
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panTlsMore
+
+
+ 1
+
+
+
+
+
+ true
+
+
+ false
+
+
+ 107, 7
+
+
+ 91, 20
+
+
+ 30
+
+
+ cmbAllowInsecure
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panTlsMore
+
+
+ 2
+
+
+ 284, 189
+
+
+ 338, 35
+
+
+ 33
+
+
+ panTlsMore
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 2
+
+
+ True
+
+
+ 469, 83
+
+
+ 203, 12
+
+
+ 29
+
+
+ 3)h2 host Separated by commas (,)
+
+
+ label20
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 3
+
+
+ 124, 125
+
+
+ True
+
+
+ 396, 54
+
+
+ 28
+
+
+ txtPath
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 4
+
+
+ True
+
+
+ 9, 125
+
+
+ 29, 12
+
+
+ 27
+
+
+ Path
+
+
+ label19
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 5
+
+
+ True
+
+
+ 526, 147
+
+
+ 59, 12
+
+
+ 26
+
+
+ 2)h2 path
+
+
+ label18
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 6
+
+
+ True
+
+
+ 469, 68
+
+
+ 59, 12
+
+
+ 25
+
+
+ 2)ws host
+
+
+ label17
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 7
+
+
+ True
+
+
+ 526, 130
+
+
+ 59, 12
+
+
+ 24
+
+
+ 1)ws path
+
+
+ label16
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 8
+
+
+ True
+
+
+ 469, 53
+
+
+ 215, 12
+
+
+ 23
+
+
+ 1)http host Separated by commas (,)
+
+
+ label14
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 9
+
+
+ True
+
+
+ 9, 201
+
+
+ 23, 12
+
+
+ 22
+
+
+ TLS
+
+
+ label15
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 10
+
+
+
+
+
+ tls
+
+
+ 124, 197
+
+
+ 143, 20
+
+
+ 21
+
+
+ cmbStreamSecurity
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 11
+
+
+ True
+
+
+ 282, 34
+
+
+ 299, 12
+
+
+ 20
+
+
+ *tcp or kcp or QUIC camouflage type, default none
+
+
+ label12
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 12
+
+
+ 158, 58
+
+
+ True
+
+
+ 300, 53
+
+
+ 16
+
+
+ txtRequestHost
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 13
+
+
+ True
+
+
+ 9, 34
+
+
+ 95, 12
+
+
+ 19
+
+
+ Camouflage type
+
+
+ label11
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 14
+
+
+ True
+
+
+ 9, 62
+
+
+ 143, 12
+
+
+ 17
+
+
+ Camouflage domain(host)
+
+
+ label10
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 15
+
+
+ none
+
+
+ http
+
+
+ srtp
+
+
+ utp
+
+
+ wechat-video
+
+
+ dtls
+
+
+ wireguard
+
+
+ 124, 30
+
+
+ 143, 20
+
+
+ 18
+
+
+ cmbHeaderType
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 16
+
+
+ Bottom
+
+
+ 3, 237
+
+
+ 723, 234
+
+
+ 21
+
+
+ Keep the default value if it is not clear
+
+
+ groupBox2
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 2
+
+
+ True
+
+
+ 353, 175
+
+
+ 113, 12
+
+
+ 15
+
+
+ *Default value tcp
+
+
+ label9
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 3
+
+
+ True
+
+
+ 353, 147
+
+
+ 119, 12
+
+
+ 14
+
+
+ *Recommended (auto)
+
+
+ label8
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 4
+
+
+ tcp
+
+
+ kcp
+
+
+ ws
+
+
+ h2
+
+
+ quic
+
+
+ 195, 171
+
+
+ 143, 20
+
+
+ 12
+
+
+ cmbNetwork
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 5
+
+
+ True
+
+
+ 12, 175
+
+
+ 167, 12
+
+
+ 13
+
+
+ Transport protocol(network)
+
+
+ label7
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 6
+
+
+ aes-128-gcm
+
+
+ chacha20-poly1305
+
+
+ auto
+
+
+ none
+
+
+ 195, 143
+
+
+ 143, 20
+
+
+ 6
+
+
+ cmbSecurity
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 7
+
+
+ 127, 199
+
+
+ 143, 21
+
+
+ 11
+
+
+ txtRemarks
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 8
+
+
+ True
+
+
+ 12, 203
+
+
+ 95, 12
+
+
+ 10
+
+
+ Alias (remarks)
+
+
+ label6
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 9
+
+
+ True
+
+
+ 12, 147
+
+
+ 173, 12
+
+
+ 8
+
+
+ Encryption method (security)
+
+
+ label5
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 10
+
+
+ 127, 114
+
+
+ 143, 21
+
+
+ 7
+
+
+ txtAlterId
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 11
+
+
+ True
+
+
+ 12, 118
+
+
+ 47, 12
+
+
+ 6
+
+
+ AlterId
+
+
+ label4
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 12
+
+
+ 127, 85
+
+
+ 278, 21
+
+
+ 5
+
+
+ txtId
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 13
+
+
+ True
+
+
+ 12, 89
+
+
+ 53, 12
+
+
+ 4
+
+
+ UUID(id)
+
+
+ label3
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 14
+
+
+ 127, 56
+
+
+ 143, 21
+
+
+ 3
+
+
+ txtPort
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 15
+
+
+ True
+
+
+ 12, 60
+
+
+ 29, 12
+
+
+ 2
+
+
+ Port
+
+
+ label2
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 16
+
+
+ 127, 27
+
+
+ 359, 21
+
+
+ 1
+
+
+ txtAddress
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 17
+
+
+ True
+
+
+ 12, 31
+
+
+ 47, 12
+
+
+ 0
+
+
+ Address
+
+
+ label1
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 18
+
+
+ Fill
+
+
+ 0, 35
+
+
+ 729, 474
+
+
+ 3
+
+
+ Server
+
+
+ groupBox1
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 0
+
+
+ 303, 17
+
+
+ 75, 23
+
+
+ 5
+
+
+ &OK
+
+
+ btnOK
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel2
+
+
+ 1
+
+
+ Bottom
+
+
+ 0, 509
+
+
+ 729, 60
+
+
+ 7
+
+
+ panel2
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 1
+
+
+ Top
+
+
+ 0, 25
+
+
+ 729, 10
+
+
+ 6
+
+
+ panel1
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 2
+
+
+ 17, 17
+
+
+ 237, 22
+
+
+ Import client configuration
+
+
+ 237, 22
+
+
+ Import server configuration
+
+
+ 234, 6
+
+
+ 237, 22
+
+
+ Import URL from clipboard
+
+
+ 162, 21
+
+
+ Import configuration file
+
+
+ 0, 0
+
+
+ 729, 25
+
+
+ 8
+
+
+ menuServer
+
+
+ System.Windows.Forms.MenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 3
+
+
+ True
+
+
+ 6, 12
+
+
+ 729, 569
+
+
+ Edit or add a [VMess] server
+
+
+ MenuItem1
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ MenuItemImportClient
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ MenuItemImportServer
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripSeparator1
+
+
+ System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ MenuItemImportClipboard
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ AddServerForm
+
+
+ v2rayN.Forms.BaseForm, v2rayN, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/AddServerForm.zh-Hans.resx b/v2rayN/v2rayN/Forms/AddServerForm.zh-Hans.resx
new file mode 100644
index 00000000..7c5b3623
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/AddServerForm.zh-Hans.resx
@@ -0,0 +1,301 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 取消(&C)
+
+
+ 服务器
+
+
+ 生成(&G)
+
+
+ *手填,方便识别管理
+
+
+ 不清楚则保持默认值
+
+
+
+ 95, 12
+
+
+ 3)QUIC 加密密钥
+
+
+ 95, 12
+
+
+ 4)QUIC 加密方式
+
+
+ 53, 12
+
+
+ 默认true
+
+
+ 149, 12
+
+
+ 3)h2 host中间逗号(,)隔开
+
+
+ 65, 12
+
+
+ 路径(path)
+
+
+ 161, 12
+
+
+ 1)http host中间逗号(,)隔开
+
+
+ 77, 12
+
+
+ 底层传输安全
+
+
+ 197, 12
+
+
+ *tcp或kcp或QUIC伪装类型,默认none
+
+
+ 124, 58
+
+
+ 334, 51
+
+
+ 89, 12
+
+
+ 伪装类型(type)
+
+
+ 89, 12
+
+
+ 伪装域名(host)
+
+
+ 143, 12
+
+
+ *默认tcp,选错会无法连接
+
+
+ 113, 12
+
+
+ *随便选,建议(auto)
+
+
+ 127, 171
+
+
+ 211, 20
+
+
+ 107, 12
+
+
+ 传输协议(network)
+
+
+ 127, 143
+
+
+ 211, 20
+
+
+ 83, 12
+
+
+ 别名(remarks)
+
+
+ 113, 12
+
+
+ 加密方式(security)
+
+
+ 95, 12
+
+
+ 额外ID(alterId)
+
+
+ 65, 12
+
+
+ 用户ID(id)
+
+
+ 65, 12
+
+
+ 端口(port)
+
+
+ 83, 12
+
+
+ 地址(address)
+
+
+ 确定(&O)
+
+
+ 92, 21
+
+
+ 导入配置文件
+
+
+ 171, 22
+
+
+ 导入客户端配置
+
+
+ 171, 22
+
+
+ 导入服务端配置
+
+
+ 168, 6
+
+
+ 171, 22
+
+
+ 从剪贴板导入URL
+
+
+ 编辑或添加[VMess]服务器
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/BaseForm.Designer.cs b/v2rayN/v2rayN/Forms/BaseForm.Designer.cs
new file mode 100644
index 00000000..f23103bb
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/BaseForm.Designer.cs
@@ -0,0 +1,51 @@
+namespace v2rayN.Forms
+{
+ partial class BaseForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BaseForm));
+ this.SuspendLayout();
+ //
+ // BaseForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(292, 273);
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "BaseForm";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "BaseForm";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/BaseForm.cs b/v2rayN/v2rayN/Forms/BaseForm.cs
new file mode 100644
index 00000000..4ea789b1
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/BaseForm.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Windows.Forms;
+using v2rayN.Mode;
+
+namespace v2rayN.Forms
+{
+ public partial class BaseForm : Form
+ {
+ protected static Config config;
+ protected static System.Drawing.Icon icon;
+
+ public BaseForm()
+ {
+ InitializeComponent();
+ LoadCustomIcon();
+ }
+
+ private void LoadCustomIcon()
+ {
+ try
+ {
+ if (icon == null)
+ {
+ string file = Utils.GetPath(Global.CustomIconName);
+ if (!System.IO.File.Exists(file))
+ {
+ return;
+ }
+ icon = new System.Drawing.Icon(file);
+ }
+ this.Icon = icon;
+ }
+ catch (Exception e)
+ {
+ Utils.SaveLog($"Loading custom icon failed: {e.Message}");
+ }
+ }
+
+ }
+}
diff --git a/v2rayN/v2rayN/Forms/BaseForm.resx b/v2rayN/v2rayN/Forms/BaseForm.resx
new file mode 100644
index 00000000..61360d3d
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/BaseForm.resx
@@ -0,0 +1,1253 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+
+ AAABAAEAgIAAAAEAIAAoCAEAFgAAACgAAACAAAAAAAEAAAEAIAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAgAAAAIAAAACAAAAAwAA
+ AAMAAAADAAAAAwAAAAQAAAAEAAAABAAAAAQAAAADAAAAAwAAAAMAAAADAAAAAgAAAAIAAAACAAAAAQAA
+ AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAA
+ AAIAAAADAAAABAAAAAUAAAAGAAAACAAAAAgAAAAKAAAACgAAAAsAAAAMAAAADQAAAA0AAAANAAAADQAA
+ AAwAAAALAAAACgAAAAoAAAAIAAAACAAAAAYAAAAFAAAABAAAAAMAAAACAAAAAQAAAAEAAAABAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAQAAAAIAAAACAAAABAAAAAUAAAAHAAAACQAAAAwAAAAOAAAAEQAAABMAAAAVAAAAFwAA
+ ABgAAAAaAAAAGwAAABwAAAAcAAAAHQAAAB0AAAAcAAAAHAAAABsAAAAaAAAAGAAAABcAAAAVAAAAEwAA
+ ABEAAAAOAAAADAAAAAkAAAAHAAAABQAAAAQAAAACAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAAEAAAABwAAAAkAAAAMAAAAEAAA
+ ABMAAAAXAAAAGgAAAB4BAQAgAgEBIwMDASUDAgEmAwMBKAUEASkGAwMrCAUDKwgFAysIBQMsCAUDLAgF
+ AysIBQMrBgMDKwUEASkDAwEoAwIBJgMDASUCAQEjAQEAIAAAAB4AAAAaAAAAFwAAABMAAAAQAAAADAAA
+ AAkAAAAHAAAABAAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAA
+ AAQAAAAHAAAACgAAAA4AAAASAAAAFwAAABwAAAAgAwIBJAUDAicGBAIqBQUCKwICAi0FAwMvCQcEMQgH
+ BjACAwQwAAECMQYFBTURDgg5GRMJPBwWCz0cFgs9GRMJPBEOCDkGBQU1AAECMQICBDAIBwYwCQcEMQUD
+ Ay8CAgItBQUCKwYEAioFAwInAwIBJAAAACAAAAAcAAAAFwAAABIAAAAOAAAACgAAAAcAAAAEAAAAAgAA
+ AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAUAAAAIAAAADQAAABIAAAAXAQAAHQIBASIDAgEmBgMDKgQD
+ AywAAAEtBQQEMRYRCTckHA0+OCoTSlU/G19sUCF1elomhoZjKZWOaCufkmstqphwL7Kccy+3nnQwup51
+ MLqccy+3mXEvspNsLaqOaSufh2QqlHtbJ4ZtTyJ1Vj8cXzgpE0okHA0+FhEJNwUEBDEAAAEtBAMDLAYD
+ AyoDAgEmAgEBIgAAAB0AAAAXAAAAEgAAAA0AAAAIAAAABQAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAYAAAAKAAAADwAA
+ ABUAAAAcAgIAIgQCAicFBAErBAMDLgUEBDAWEQo5QjEWT2BHH2d6WiaHkGssq6B2MMWtfzTbt4Y367+M
+ OfXEjzv5yZM8/M2WPv7PmD7/0Zk//9KaP//Tmz//05s//9OaP//Smj//0Jg+/82WPv3KlD37xZA7+cCM
+ OvW4iDjrroA126F2McWRbCyre1smh2FHH2dCMRZPFhEKOQUEBDAEAwMuBQQBKwQCAicCAgAiAAAAHAAA
+ ABUAAAAPAAAACgAAAAYAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAABAAAAAwAAAAYAAAAKAAAAEAAAABcBAQAeAwIBJAYDAyoBAAEsBwUEMSIaDDxSPBtaelomhpRt
+ LbGoezPVt4Y37MSQO/nMlj3/0Zk//9WcQP/YnkH/2J5B/9ieQP/XnkD/155A/9eeQP7XnkD+155A/tee
+ QP7XnkD+155A/teeQP7XnkD+155A/9eeQP/YnkD/2J5B/9ieQf/WnED/0po//82WPf/FkTv5uog47Kp8
+ M9WVbi6xelomh1E8GlshGQw8BwUFMgEAASwGAwMqAwIBJAEBAB4AAAAXAAAAEAAAAAoAAAAGAAAAAwAA
+ AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAYAAAAKAAAAEQAAABgBAQAgBAMBJgUD
+ AysDAgMvGRIKOVQ+G1p+XSiKm3MvvrKDNubCjjr5zZY+/tWcQP/XnUD/2J9B/tieQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/2J5A/9ifQf7XnUD/1ZxA/8+YPv7Djzv5s4M25pxyL799XCeLUj0bWhkT
+ CzkDAgMvBQMDKwQDASYBAQAfAAAAGAAAABEAAAAKAAAABgAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAA
+ AAQAAAAJAAAADwAAABcBAQAfBAMBJgMCASsIBgQwMSQRQ2xQIXOUbS2xr4A14cOOO/nPmD7/1p1A/9ie
+ QP/XnkD+155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/tieQP/WnUD/0Jg+/8SPO/mvgTXhlG0usWtOInQwIxJDCAYEMAMCASsEAwEnAQEAHwAA
+ ABcAAAAPAAAACQAAAAQAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAHAAAADQAAABQBAQAdBQQBJQUFAiwGBQQwRDMXTXxc
+ J4ahdjHKuog48syVPf7VnED/155B/9ieQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/2J5B/9Wc
+ QP/Nlj3+uok486B2Mcp6WiaGQjIWTgYFBDAEAwIsBAMBJQEBAB0AAAAUAAAADQAAAAcAAAADAAAAAQAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAEAAAACgAA
+ ABEAAAAaAwIBIwUDAioHBgQvQDAVSoFeKIynejLTv4w6+NCYPv/XnkD/155A/teeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP7XnkD/0Jk+/8CNOvimejLTfl0njT0u
+ FEoGBQQvBQMCKgMCASMAAAAaAAAAEQAAAAoAAAAEAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAEAAAADAAAABwAAAA0AAAAWAQAAHwQDASgDAgIuNScSRHxbJoOnejPSwY06+dKa
+ P//YnkD+2J5A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/2J5B/tObP//Bjjr5pXky03hZJoQzJhJEAwMCLgQDASgBAAAfAAAAFgAA
+ AA0AAAAHAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAgAAAAQAAAAGQQC
+ AiQDAQIqFBAINWlOIWuedDDBvos59dGZP//XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ie
+ Qf/Smj//vYs59ZtyL8JlSh9sEw8INQMBAioEAgIkAAAAGQAAABAAAAAIAAAAAwAAAAEAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAgAAAAQAAAAKAAAAEwIBAR0FAwInAQECLUg1GE2QaiyjtoU3686WPf/XnUD/2J5A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/zpc+/7SEN+yLZiqlRTMXTwEB
+ Ai4FAwInAgEBHQAAABMAAAAKAAAABAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAFAAAADAAAABUDAgEgBAIBKBoU
+ CTVxUyNxpnkyzcWQO/zVnED/2J5A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/1ZxA/8WQO/yidzHPak8hcxkTCTUEAgEoAwIBIAAAABUAAAAMAAAABQAA
+ AAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAACAAAABgAAAA0AAAAXAwMBIgIBAis4KhNDj2ksm7iHN+7QmD7/155A/teeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/2J5B/tCZ
+ Pv+2hTfviGQqnTUnEkUDAgIrAwMBIwAAABcAAAANAAAABgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAYAAAAOAQEAGQQCAiQIBgMsXEQdWaB2
+ Mb3Djzr51ZxA/9ieQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/tacQP/Cjjr5mnAvv1U/G1sIBgMtBAICJAEB
+ ABkAAAAOAAAABgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAIAAAAHAAAADwEBABkFAwIlCQcDLnVWJHCvgDXZzJY9/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/LlT3/qHwz2m1QInIJBwMvBQMCJgEBABkAAAAPAAAABwAAAAIAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABgAAAA8CAQAaAwIBJhIOBjJ/Xid+toY35tGZ
+ P//YnkD+155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ieQP7RmT7/sYI26HZX
+ JYARDQYzBAIBJgIBABoAAAAPAAAABgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAA
+ AAYAAAAOAQEAGgYFASYjGgw4jGcrkLuJOO7Tmz//2J5A/teeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP7UnD//toY374FeKJIgGAs5BgUBJwEBABoAAAAOAAAABgAA
+ AAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAFAAAADQIBABkBAQEkLCENOpJrLZnAjTrz1Js//9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/VnED/u4k49IdjKZwpHw07AgEBJAIBABkAAAANAAAABQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABQAA
+ AAwBAQAXBgQBJSwiDjmXby2fw4469tadQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/WnUD/vYs594tmKqEqHg07BwUBJQEB
+ ABcAAAAMAAAABQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAKAQEAFgMCASImHAw2lm4umMSPO/bVnED+155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/VnED+vos59ohkKZsiGgw4AwIBIgEBABYAAAAKAAAABAAAAAEAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAACQEB
+ ABMGBAIhFQ8IMJJrLY/Djzrz1p1A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/WnUD/vIo59INh
+ KZMUDggxBgQCIQEBABMAAAAJAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAYAAAAQBQICHQgGAyqHYyl8wI067tWcQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/VnED/uIc38HhYJYAIBgMrBQICHQAAABAAAAAGAAAAAgAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFAAAADQQD
+ ARoEAwEnf10mbr2LOebVnED/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/UnD//s4M26HBSInEFAwEnBAQBGgAAAA0AAAAFAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAoFAwIWAQABI2hNIFW5hzjY05o//9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/RmT//qn0021tCHFoDAQEjBAMCFgAA
+ AAoAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAHAwICEgAA
+ AB9GNBU/roA0vdCZPv7XnkD+155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP7Mlj3/nXIwwTwsEkEAAAEfAwICEgAAAAcAAAACAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAABAAAABQAAAA0GBAMbHRUJLaF2MJnMlT35155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeP//XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP7Djzv6jGcrnhoT
+ CC8HBAMbAAAADQAAAAUAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAJBgQDFgAA
+ ACOGYiluxpE779adQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ifQ//cq1n/2qVN/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9adQP+5hzfwc1QjcwAAACQGAwMWAAAACQAAAAMAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAABAAAABgIBARAAAAEdW0MbR7mIN83Um0D/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/2KFH/+XCiP/pypf/26dS/9eeP//XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/tGZ
+ P/+nejPRTjkYSgAAAR0CAQEQAAAABgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMBAAEKBgMDGBwU
+ CSypfDOh0Jg+/deeQf7XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeP//Zokf/6cqX//jw5P/qzZ7/2aNL/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155B/seSPP2SayynGBEILQcDAxgBAAELAAAAAwAA
+ AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAACAAAABwcEAxECAAIghWEoZciSPOvXnUD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/154//9iiR//pyZf//Pr3//n06//mw4v/2aRM/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/1p1A/reHN+1uUSFqBAICIAcEAhEAAAAHAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMCAwALAAAAGE05
+ Fzm6iDe/1ZtA/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xnj//2KJH/+nJl//8+vj//f7+//jv
+ 4//nxY7/2aJJ/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/0Jg+/6F3McVBMBQ9AgIAGAID
+ AAsAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAABAAAABggGAhIHBQMgnHMvf8+YPvbXnkH/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeP//Yokf/6cmX//z69//9/f7//f39//jw4v/kvX//2aJI/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/YnkH/wY4694JhKIQIBgMhCAYCEgAAAAYAAAABAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMEBAELAQEAGFxC
+ G0DCjjrR151A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/154//9iiR//pyZf//Pr4//39
+ /f/9/f3//f39//bs3P/kv4L/2KFG/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Tmz//q3401Us3
+ F0MCAgAYBQMBCwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAABAAAABQkHARACAgEgpXgxh9KaP/rYnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/Xnj//2KJH/+nJl//8+vj//f39//39/f/9/f3//fz8//br2f/huHX/2KFF/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/FkDv7iWQpjQQCASEJBwERAAAABQAAAAEAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIDAwAJAAAAFWhL
+ H0HGkTzS2J5B/9eeQP7XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeP//Yokf/6cmX//z6
+ +P/9/f3//f39//39/f/9/f3//f39//Xo1P/iuXf/2KBE/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/tSb
+ QP+tfzTWVD0ZRQAAABUDAwAJAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAABAAAABAsIAw4HBQIdpnkygNObP/nYnkH+155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/154//9iiR//pyZf//Pr4//39/f/9/f3//f39//39/f/9/f3//fz6//Tl
+ zv/fs2v/159C/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/2J5B/sSQO/qJZCmHCQYCHgsIAw4AAAAEAAAAAQAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIGBQEHBgYAE1Q+
+ GTTFkTvI155B/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xnj//2KJH/+nJ
+ l//8+vj//f39//39/f/9/f3//f39//39/f/9/f3//fz7//Pky//gtW3/159C/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/0po//6p8M85FMRQ4BwcBEwYFAQcAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwkGBAsCAAEZnHMvatObP/LYnkH/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeP//Yokf/6cmX//z6+P/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//Pv4//Hfwf/er2H/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/wI069H5cJnIDAgIZCQYECwAA
+ AAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFCgQFDzUn
+ ESfAjTqt155B/9eeQP7XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/154//9ii
+ R//pyZf//Pr4//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//Pv5//Hfwv/esWb/155B/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP7QmD7/n3YwtCwhDioLBQYQAAAABQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQoJAQgAAAAShmIoTM+YPt/YnkH/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xnj//2KJH/+nJl//8+vj//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//Pn1/+/Ztv/drFz/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9adQP+2hjfkaE0gUgAA
+ ABIJCQEIAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADEw0GCw4K
+ BRmygjWC1p1A+teeQP7XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ P//Yokf/6cmX//z6+P/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f7//Pn2/+/Y
+ tf/drV3/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/2J5B/siTPPuOaSuKDwsFGxMNBgsAAAADAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQUEAAQEBAANRjQVKMiSPLrYnkH/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/154//9iiR//pyZf//Pr4//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f7/+/fx/+3Uq//bqVX/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/0po//6h7
+ M8I2JxErBgUADQUEAAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDgoFBgYE
+ AhGOaCpK05s/5tieQf/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/Xnj//2KJH/+nJl//8+vj//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f7/+/fy/+zSqP/bqVX/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnUD/vIk56m1PIVMJBQMSDgoEBgAAAAEAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIUEQMIAAAAFLSENnvXnUH5155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeP//Yokf/6cmX//z6+P/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f7/+vTs/+rOof/apk//154//9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ie
+ QP/Ikzz6jWgrhAAAABUUEQMIAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxcP
+ Bws+LBMhyJI8rdieQf/XnkD+155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/154//9iiR//pyZf//Pr4//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3/+vTs/+rMnP/apU7/154//9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/2J5A/tKZP/+keDK0MSMPJRcPBwsAAAADAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQADAAAADIRgJznRmT/S2J9B/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xnj//2KJH/+nJl//8+vj//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3/+fHm/+jJ
+ lv/Zo0r/154//9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/1p1A/7SFNthlSh5AAAAADAABAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARsV
+ BgUAAAAMpXkyV9acQOvYnkH/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeP//Yokf/6cmX//z6+P/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3/+PLm/+fGj//Zo0r/154//9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/YnkH/wY06735cJl4AAAANGRQFBgAA
+ AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIxcMBwwHBRK7iTl82J5B/NeeQf7XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/154//9iiR//pyZf//Pr4//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/fz/9+7g/+bDi//YoUb/154//9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9ieQf7LlT38lGwthg8KBhQiFgsHAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAEQCAcIQS4UG8iSPKLZn0H/155A/teeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/Xnj//2KJH/+nJl//8+vj//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/Pz/9+7g/+S/gv/YoUf/154//9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/2J5A/tGZPv+leTGsMyQPHRMK
+ CAgAAAABAAAAAAAAAAAAAAAAAAAAAAAAAABkVw0ACwoAAgAAAAhcQxwizpg+wdmfQf/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeP//Yokf/6cmX//z6
+ +P/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/Pz/9erX/+S+gP/YoEP/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/1ZxA/7CBNchCMBQmAgEACAoKAAJLQQoAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAcEQsCBwAFCodiKTPUmz/c2J5B/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/154//9iiR//pyZf//Pr4//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/Pv/9uvZ/+K5
+ dv/YoEX/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnUH/uog34GRK
+ HjoLBAYKGxALAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8VCgMLBgQLpXkxTNadQO7YnkH/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xnj//2KJH/+nJ
+ l//8+vj//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/Pv/8+TM/+G3c//Xn0L/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9ieQf/Cjjrwf10mVQ4IBQweFAoDAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAIBcJAwsIAg21hDZj155A9deeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeP//Yokf/6cmX//z6+P/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/8+/r/9ObR/9+zaf/YoEP/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/8eS
+ PPeOaCtsDgoEDR8WCQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVDgcEAAABDL+MOXfXnkH4155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/154//9ii
+ R//pyZf//Pr4//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/Pv/8d/C/9+yaf/Xn0H/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/y5U9+phwLoAAAAIMFQ4HBAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAASAfAQQAAAAMxpA7idieQfzXnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xnj//2KJH/+nJl//8+vj//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/8+/n/8uDF/92vYv/Xn0L/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/Plz79oHYwkAAAAAwfHgEEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABKxoQBQwKBQ/JkzyX2J5B/tee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ P//Yokf/6cmX//z6+P/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/8+/n/79m2/92t
+ X//XnkH/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/tGZP/+leTKeDAkFEigYDwUAAAABAAAAAAAA
+ AAAAAAAAAAAAAAAAAAE4IxUFRC8UE82WPaTYnkH/155A/teeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/154//9iiR//pyZf//Pr4//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/8+vf/8Nu6/9ysW//Xn0H/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD+05s//6x+M6s0JBEYNiMTBgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAS8eEAZcQhwXz5g+rtie
+ Qf/XnkD+155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/Xnj//2KJH/+nJl//8+vj//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/7+fX/7NOq/9upV//XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP7Um0D/sIE0tEYzFhwvHhEGAAAAAQAA
+ AAAAAAAAAAAAAAAAAAAAAAABKRoPBmlMIBnQmT+12J5B/9eeQP7XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeP//Yokf/6cmX//z6+P/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/v/7+PP/7dWu/9uoVf/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/tWcQP+0gza7UzoYHioaDwYAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAE5Kg4FcVMiGtGZ
+ PrjYnkH/155A/teeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/154//9iiR//pyZf//Pr4//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/69u//6s2d/9qmT//Xnj//155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD+1ZxA/7WENr5aQBkfOSsPBgAA
+ AAEAAAAAAAAAAAAAAAAAAAAAAAAAADwsDwV1VSIa0Zk+uNieQf/XnkD+155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xnj//2KJH/+nJl//8+vj//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/v/69vD/69Ci/9qm
+ UP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP7VnED/tYU2vltCGh89LRAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCATBHNU
+ IhjSmj+12J5B/9eeQP7XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeP//Yokf/6cmX//z6+P/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/58+n/6MiU/9qkTP/Xnj//155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/tWcQP+1hTa6WUAaHTUh
+ EwUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBKRcEa04gFdGZP67YnkH/155A/teeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/154//9iiR//pyZf//Pr4//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /v/58uj/6MiU/9mkS//XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD+1ZtA/7ODNbRSPRcaPSYWBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFM0
+ HgRbQhwQ0Jg+pdieQf/XnkD+155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/Xnj//2KJH/+nJl//8+vj//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/v/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/37+H/5cGH/9miSP/Xnj//155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP7Tmz//sIE0q0Uy
+ FhVKLxoEAAAAAAAAAAAAAAAAAAAAAAAAAACCRD4AYC4xAyQXDArPlz6W2J5B/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeP//YoUf/6cmX//z6
+ 9//9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/v/7+PT/+fLo//38+//9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/37uD/5cKI/9iiSP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/tKaP/+rfTOdHRMKDlQpKwNpNzIAAAAAAAAAAAAAAAAAAAAAACQb
+ CgBVPhcCAAAABs2WPYfYnkH8155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/154//9ihR//pyZf//Pr3//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f7///ft3v/pypn/9ejT//38+//9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/P/27Nv/471//9ih
+ Rf/Xnj//155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/YnkD/0Jg+/ah7
+ Mo4AAAAHUDsWAiMaCQAAAAAAAAAAAAAAAAAAAAAAPzMNADUvCgEAAAAFyZM9ddieQfnYnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xnj//2KJH/+nJ
+ l//8+vj//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/v//9urZ/96wZP/ht3P/8+TM//z7
+ +v/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/P/26tj/47x9/9igRP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP7Nlj36pHgxfQAAAAU2MAoBPzMNAAAAAAAAAAAAAAAAAAAA
+ AABuUB4AVj8XARsTBQbGkDte2J5B9deeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeP//Yokf/6cmX//z6+P/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//3+///26tn/3a5f/9igQ//htnD/8+LJ//z7+f/9/f7//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//38
+ +v/159P/4rh0/9ifQ//XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/8mT
+ PPadcy9nIBcHBlE7FgFmShsAAAAAAAAAAAAAAAAAAAAAAH1bIgBrTh0BKB0JBcCMOkbYnkHu2J5B/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/154//9ii
+ R//pyZf//Pr4//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f7///bq2f/drmD/150+/9ef
+ Qv/gs2v/8d/B//z6+P/9/f7//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//38+//05c7/4bdy/9efQv/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/YnkH/xZE78JduLU8rHwoFYEYaAW1QHgAAAAAAAAAAAAAA
+ AAAAAAAAi1M4ALluSwASABEDsYI2LNedQN3Zn0H/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xnj//2KJH/+nJl//8+vj//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/v//9urZ/92uYP/XnT//155A/9efQv/fsWf/8d6///z59v/9/f7//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//z7+P/z48r/37Nq/9eeQf/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ie
+ Qf/AjTnghGIoMhsGEgOPVToAckQuAAAAAAAAAAAAAAAAAAAAAAB/dAsAvasRAAARAAKacC4Y1ZxAwdmf
+ Qf/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ P//Yokf/6cmX//z6+P/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//3+///26tn/3a5g/9ed
+ P//XnkD/155A/9eeQf/esGT/79m3//v49P/9/f7//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//z7+f/x4MP/37Np/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/1ZxA/7mHN8dwUiIbCh4AArGgEAB6bwoAAAAAAAAA
+ AAAAAAAAAAAAAEZHAAAADwAATT8MAolkKQ7Smj+g2Z9B/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/154//9iiR//pyZf//Pr4//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f7///bq2f/drmD/150//9eeQP/XnkD/155A/9efQf/drV7/7tex//v3
+ 8P/9/f7//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//z59v/w3sD/3a5g/9eeQf/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/Smj//soI2qWhMIBBZSA8CABAAAEdIAAAAAAAAAAAAAAAAAAAAAAAAAAAAALR4PACfZzcBRTAXBs+Y
+ PnjZn0H92J5A/teeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/Xnj//2KJH/+nJl//8+vj//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/v//9urZ/92u
+ YP/XnT//155A/9eeQP/XnkD/155A/9eeQP/cq1n/69Gl//r28P/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//v6
+ 9v/v2rf/3q5h/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/2J9A/s6XPf2pfDOBOygVCIpZMAKVYzIAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAt25JAL9yTQEAAAAAyJI8TtieQezYn0H/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeP//Yokf/6cmX//z6+P/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//3+///26tn/3a5g/9edP//XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/bqVT/69Gl//r17P/9/f7//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f3+//v48//u2LT/26lW/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/YnkH+yJI87590MFQAAAABlVk8AY5WOQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADixB0A/+AeAAAA
+ AADAjDkt151A0tmfQf/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/154//9iiR//pyZf//Pr4//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f7///bq
+ 2f/drmD/150//9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/aqFP/6cuZ//n07P/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//v49P/s0qj/3KpY/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9edQP+/jDnXlGwsMgAAAADjyBsAy7AaAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcPx4AfU8rAqF1MBHVnD+r2Z9B/9ieQP7XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xnj//2KJH/+nJl//8+vj//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/v//9urZ/92uYP/XnT//155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/apU3/6cyb//nx5v/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f3+//r27v/s0af/2qVO/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/YnkD+1JtA/7eGNrF3VyQWdksoAlM5GwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGdO
+ GQCMdxUBAAAAAtGZPnTZn0H52J5A/teeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeP//Yokf/6cmX//z6+P/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//3+
+ ///26tn/3a5g/9edP//XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeP//apEz/5sSL//ny
+ 5//9/Pz//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f3+//v48v/py5r/2qdS/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ifQP7Olz76rX40fAAAAAONeBUBZU0ZAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArXY3AMqKQQAtFhICyJM9PtieQejYnkH/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/154//9iiR//pyZf//Pr4//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f7///bq2f/drmD/150//9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Yokj/58eR//fv4f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f3+//nz
+ 6f/pyZf/2aNL/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/2J5B/8aRO+ueczBGOSAVAq53OACZaDEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AACSghAAtrAHAAADAAGwgDYV1p1AutmfQf/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/Xnj//2KJH/+nJl//8+vj//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/v//9urZ/92uYP/XnT//155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ P//Yokf/5L6B//ft3v/8/Pr//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//r17f/nxpH/2qVN/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/VnED/u4k4wIJfKBgbGAABop0GAId4
+ DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+dEsAvWpTAXdSJgXSmj972Z9B/Nie
+ QP7XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeP//Yokf/6cmX//z6
+ +P/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//3+///26tn/3a5g/9edP//XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/YoEX/5cGF//br2f/9/fz//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//jw4//mxIz/2KJH/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/2J5B/s+YPv2xgjWDWz0cB6pgSQGkZEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAO+CbgD+iXYA//+JAMuUPTvYnkHf2J9B/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/154//9iiR//pyZf//Pr4//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f7///bq2f/drmD/150//9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/YoET/4bh1//Xo1P/8+/n//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//ny6P/lwof/2aNJ/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/xZA746J3MUH//4YA8oJxAd55
+ ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJMKACQVDgBtIM3Etad
+ QKvZn0H/155A/teeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xnj//2KFH/+nJ
+ l//8+vf//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/v//9urZ/92uYP/XnT//155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/YoET/4rp5//Tn
+ 0P/9/Pv//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//bs3P/kvX//2KBE/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/2J5A/tObP/+6iDiwiGMrFZpcOQFrRyYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAnVxAALlxSAEAABMB0po/XtmfQfTYnkH/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ Qf/Xn0L/159C/9efQv/Xn0L/159C/9efQv/Zo0n/6cqY//z6+P/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//3+///26tn/3a5g/9edP//XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xn0L/37Jn//Lgxf/8+vf//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//fu
+ 4P/kvX7/2KFG/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/YnkH+y5U99q6ANGUGABcCn2E+AY1T
+ OgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyiycAyJ0rAB4k
+ AAHDjzse155BydmfQf/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/2qZQ/+K5dv/kvoH/5L6A/+S+gP/kvoD/5L6A/+XA
+ hf/v27r//Pv5//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f7///bq2f/drmD/150//9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/Yn0L/4LNr//LgxP/8+/n//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//fz7//Tn0v/iuXb/2J9D/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9WdQP/AjTrNmXEuITk1AAGphSUAm3kiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADKfU4AynRVAaNvNQPUmz922Z9B+tifQP7XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ P//gtGz/9OjU//r38P/69u//+vbv//r27//69u//+vbw//v59f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/v//9urZ/92uYP/XnT//155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xn0H/3a5g/+/auP/8+fT//f3+//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//fz8//Xo1P/iuHT/2KBE/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Yn0D+zpc9+7OENn10UCYFv25PAbRw
+ RQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+B
+ gwD/i5AA//91AMuWPSzYnkHS2Z9B/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/150//+C2b//37uD//f7+//39/v/9/f7//f3+//39
+ /v/9/f7//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//3+///26tn/3a5g/9ed
+ P//XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/Xn0H/3a9h/+/Ztv/7+fX//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//Pv6//LiyP/fs2v/159B/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9adQP/EkDrWo3gxMf//ZAC2Wl0AqlVWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJZaPQDLZWYBjmcpBdWcP37Zn0H62J9A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnT//4LZv//fu3//9/f7//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f7///bq2f/drmD/150//9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/3KtZ/+3U
+ rf/69/D//f3+//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//Pv5//Lhxv/fsmj/159C/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/YnkD/z5g++7eGNoRoSx4GolBQAX9L
+ MwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAwXFRANB5VwBGAEQBzZc+KNieQdLZn0H/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9edP//gtm//9+7f//39/v/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/v//9urZ/92u
+ YP/XnT//155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/3KpZ/+zSqf/69vD//f3+//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//Pr3//Dd
+ vf/er2P/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9adQP/FkDvVpnozLFoORQG3a00ArGRJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/mswA87wPAP/AWgDCjzUD1p1Ac9mf
+ QfjYn0D+155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/150//+C2b//37t///f3+//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//3+///26tn/3a5g/9edP//XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/26hT/+rPov/69Oz//f3+//39/f/9/f3//f39//39/f/9/f3//f39//39/f/9/f3//f39//39
+ /f/9/f3//f39//39/f/9/f3//f39//39/f/9/f7//Pr2/+/bu//drV//155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xn0D+z5g++bmIN3mMaSUE/+FqAPSv
+ DgD/v/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAD//wAA//8AAP/+agDTmkEf2J5Bv9mfQf/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnT//4LZv//fu4P/9/v7//f3+//39
+ /v/9/f7//f3+//39/v/9/f7//f3+//39/v/9/f7//f3+//39/v/9/f7//f3+//39/v/9/f7//v7///br
+ 2f/drmD/150//9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/26hU/+rMnf/59Or//f3+//39
+ /v/9/f7//f3+//39/v/9/f7//f3+//39/v/9/f7//f3+//39/v/9/f7//f3+//39/v/9/f7//f3+//39
+ /v/9/f7/+/n1/+7Xs//drFz/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9WdQP/EkDvDrH00Iv//dwD//wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADGdVEA1YJTAF4h
+ PQHVnEBW2Z9B7difQf7XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeP//gtW3/9erY//z59v/8+fX//Pn1//z59f/8+fX//Pn1//z59f/8+fX//Pn1//z5
+ 9f/8+fX//Pn1//z59f/8+fX//Pn1//z59f/8+vf/9OfS/92tX//XnT//155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/2qVP/+nJlv/37+H//Pn1//z59f/8+fX//Pn1//z59f/8+fX//Pn1//z5
+ 9f/8+fX//Pn1//z59f/8+fX//Pn1//z59f/8+fX//Pn1//z59f/8+fX/+fPq/+zSqP/bp1P/154//9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD+zZY97riHN1pbJTECtm9HAbBo
+ SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+sVQD/3nIAwXpDAceROw3XnkGd2Z9B/tifQP7XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9upV//mxYz/6syb/+rM
+ m//qzJv/6syb/+rMm//qzJv/6syb/+rMm//qzJv/6syb/+rMm//qzJv/6syb/+rMm//qzJv/6syb/+rM
+ nP/mw4n/2qZP/9eeP//XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Xnj//2qVO/+O9
+ f//pzJr/6syb/+rMm//qzJv/6syb/+rMm//qzJv/6syb/+rMm//qzJv/6syb/+rMm//qzJv/6syb/+rM
+ m//qzJv/6syb/+rMm//qzJv/58WO/9yrW//Xnj//155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/tObP//CjjqhnnIvD7RzPgHLh0UAwIFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOfK
+ HgDu0xsA5aVJANKZPy7YnkHO2Z9B/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155B/9igQ//YoET/2KBD/9igQ//YoEP/2KBD/9igQ//YoEP/2KBD/9ig
+ Q//YoEP/2KBD/9igQ//YoEP/2KBD/9igQ//YoEP/2KBE/9ifQ//XnkH/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/159C/9igQ//YoEP/2KBD/9igQ//YoEP/2KBD/9ig
+ Q//YoEP/2KBD/9igQ//YoEP/2KBD/9igQ//YoEP/2KBD/9igQ//YoEP/2KBD/9igRP/YoET/159C/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/WnkD/yZM80bKCNjHVmkcA9tkcAOfK
+ HgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMaSNADwpkgBpXwvA9acP2HZn0Hy2J9B/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/2J5B/8+YPvO9iThliGQpBMuNPQG8ijEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAA6s8bAOXPFgD//wAAzZc8C9edQJPZn0H62J9B/teeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9efQP7Tmz/7xJA7l6h9MQz//wAA5ccWAOrP
+ GwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/6pWAP+wWQD//0MA0Jg/JNif
+ Qb/Zn0H/2J5A/teeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/YnkD+1p1A/8qUPcG0hDcn//9RAP+0WwD/qlYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAwIs2AMaKPABOQBEB151AP9mfQdrZn0H/2J5A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQf/Plz7cwIw5QlxRGwHWlEAAyJE4AAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP+7
+ dgDXik8B151BW9mfQejZn0H/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/Yn0D/0Zo/6cSPO16dYz0C/+KKAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/gIAA/3yEAP+6egDVmj8H2J5Ac9mfQfHYn0H+155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/tSbP/LJkjx2sYA1CP/ikQD/fIQA/4CAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AADAgEAAxIVAAKJbQAHOlj4O2J5AitmfQfbYn0H+155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9if
+ QP7VnD/3ypQ9jbKAOA++bkkBwoRAAMGBQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/gEAAxYRCAP///wDOmD4U2J9Bldmf
+ QfrYn0H+155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Yn0H+155A+82XPZi3hzgW//9PAMeGQwC/gEAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAADSpiwA0qoqAMabGQDUmj8Z2J5BntmfQfrYn0H+155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/2J9A/tee
+ QPrRmT6gwo07GvrDIgDUrCoA1qktAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD/4CcA/+seAMN8
+ TwDZnkEY2Z9BltmfQffYn0H+155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9ieQP7XnkD30po/mMiTPBm6dUkA/+0eAP/gJwD//wAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3SsA//YVAPHUHgDVm0EU2Z5Bi9mfQfLZn0H/2J5A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/Yn0D/2J5A8tOa
+ P4zGkD0V//8qAP/4FQD/4iwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//
+ AAB+AIEAyZQ3AP//SADUmkAO2Z9BdNmfQejZn0H/2J5A/teeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD+2J5B/9edQOnTmj91xo88D///KgDKlTcAfgCBAP//AAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6ekAAv4FAAJ5YPwHJlj4G2Z5BXNmf
+ QdvZn0H/2J9B/teeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/159A/tifQf/YnkHb1Js/XbiI
+ NwepYUMBwoNAAL19QQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAC/gEAAv4BAALdxQQHXnEED2J9BQNmfQcHZn0H72J9B/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9ifQf/Zn0H72J9BwdSdQEHPlz0DvXVEAb+AQAC/gEAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/qlUA/6pVAP+t
+ WQDBjC4A2Z5BJdmfQZTZn0Hy2Z9B/9ifQP7XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP7Yn0H/2Z9B8tmfQZTXnUAlqHoqAP+v
+ WQD/q1UA/6tVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAOCaRQAIAEwA155AC9ieQWLZn0HQ2Z9B/dif
+ Qf7XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/Yn0H+2Z9B/dmfQdDYnkFi155ACwoAUwDinEUA//8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAA/6tWAP+sVgD/k2MAx4tCA9ieQS/YnkGg2Z9B7tmfQf/Yn0D+155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD+2J9B/9mfQe7YnkGg2J5BL8eLQgP/k2MA/6xWAP+r
+ VgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAypc1APXnDwC4eD4Bn1w2ANab
+ Qg/Zn0FZ2Z9BxNmfQfjZn0H/2J5B/teeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD+2J9B/9mf
+ QfjZn0HE2Z9BWdabQg+fXDYAuHg+AfXnDwDKlzUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMaVMQDjzRMAxopOAeGlUAHZoEEh2J5Bd9mfQdXZn0H72Z9B/9if
+ QP7XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD+2J9B/9mfQfvZn0HV2Z9BdtmgQSHhpVABxopOAePNEwDGlTEAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+q
+ VQD/q1gA7dAbAYdJLQDbnUUE2J9CKtmfQYLZn0HV2Z9B+tmfQf/Yn0D/155A/teeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP7YnkD/2J9B/9ifQfrZn0HV2Z9Bg9if
+ QirgoEYEh0ktAO3QGwH/q1gA/6pVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/f4EA/3+BAP+fcgEMAIwA1pxIBNme
+ Qi7Zn0F72Z9BztmfQffZn0H/2J9B/tieQP7XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ie
+ QP7Yn0D+2J9B/9mfQffZn0HO2Z9Be9qfQi7ZlkMFAgCRAP+ecgH/f4EA/3+BAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAD/gIAA/4CqANp/XADzpFQB/9emAN6gQQTZn0Ae2Z9CY9mfQbDZn0Hj2Z9B/dif
+ Qf/YnkH/2J5A/9eeQP7XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD+2J5A/9ieQf/Yn0H/2Z9B/dmfQePZn0Gw2Z9CY9mfQB7eoEEE/+ezAPOm
+ VQHaf1wA/4CqAP+AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP9+
+ hAD/foQA/6BzAY5EQwC6cUYB2Z9DEtmfQT7Zn0GB2Z9Bv9mfQezZn0H62Z9B/9ifQf/Yn0H+155A/tee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9ee
+ QP/XnkD/155A/9eeQP/XnkD/155A/9eeQP/XnkD/155A/9eeQP7YnkD+2J5B/9ifQf/Zn0H62Z9B7Nmf
+ Qb/Zn0GB2Z9BPtmfQxK6cUYBjkRDAP+gcwH/foQA/36EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA0KMtAN+pPwD/uGIAAAAAAOGi
+ SATbnkMV2aBBQtmfQXnZn0Gx2Z9B1tmfQfDZn0H+2Z9B/9mfQf/YnkH/2J5A/9eeQP/YnkD+155A/tee
+ QP7XnkD+155A/teeQP7XnkD+155A/teeQP7XnkD+155A/teeQP7XnkD+155A/teeQP/XnkD/2J5B/9if
+ Qf/Zn0H/2Z9B/tmfQfDZn0HW2Z9BsdmfQXnZoEFC255DFeGiSAQAAAAA/7hiAN+pPwDQoy0A//8AAP//
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+ZbAD/iHsA/6BoAbohkgCBMUIA3aFBAdmeQBHYnkEt2Z9AUtqf
+ QX/Zn0Gm2Z9ByNmfQePZn0Hx2Z9B9tmfQfrZn0H+2Z9B/9ieQf/YnkH/2J5B/9ieQf/YnkH/2J5B/9ie
+ Qf/YnkH/2Z9B/9mfQf7Zn0H62Z9B9tmfQfHZn0Hj2Z9ByNmfQabZn0F+2Z9AUtieQS3ZnkAR3aFBAYEx
+ QgC6IZIA/6BoAf+IewD/mWwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AADSgFMA635uANaMSgD/jXgB7qBwAQAAIAD//2kA46NHBNueRAvYn0MW2Z9CLtmfQEnZn0Fj2Z9Bedie
+ QYzZn0Ge2Z9BrNmfQbbZn0G82Z9Bv9mfQb/Zn0G82Z9BttmfQazZn0Ge2J5BjNmfQXnZn0Fj2Z9ASdmf
+ Qi7Yn0MW255EC+GkSgP///8AAAAbAO6gcAH/jXgB1oxKAOt+bgDSgFMAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/p1oA/94hAP+Z
+ awH/rGAB/2SnAP/B6gC9f2oAqngnAcCcGgDRpzoA0ao7AdudPwfZnD8M2KBBEdmgQxTaoEIX2qBCF9mg
+ QxTYoEER2Zw/DNudPwfRqjsB0ac6AMCcGgCqeCcBvX9qAP/B6gD/Y6YA/6xgAf+ZagH/3iEA/6daAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA/6NgAOOUUADLkzkB951ZAP/P
+ MQD/mW4B9qlcAbJxQwGhWz8Bj0U8AX0yOgF9MjoBj0U8AaFbPwGycUMB9qlcAf+ZbgH/zzEA951ZAMuT
+ OQHjlFAA/6NgAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAA////////4AAAB///////////////+AAAAAAf/////////////+AAAAAA
+ B/////////////8AAAAAAAD////////////8AAAAAAAAP///////////4AAAAAAAAAf//////////8AA
+ AAAAAAAD//////////8AAAAAAAAAAP/////////+AAAAAAAAAAB/////////+AAAAAAAAAAAH///////
+ //AAAAAAAAAAAA/////////AAAAAAAAAAAAD////////wAAAAAAAAAAAA////////wAAAAAAAAAAAAD/
+ //////4AAAAAAAAAAAAAf//////8AAAAAAAAAAAAAD//////+AAAAAAAAAAAAAAf//////AAAAAAAAAA
+ AAAAD//////gAAAAAAAAAAAAAAf/////wAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAAf////8AAAAA
+ AAAAAAAAAAD////+AAAAAAAAAAAAAAAAf////AAAAAAAAAAAAAAAAD////gAAAAAAAAAAAAAAAAf///4
+ AAAAAAAAAAAAAAAAH///8AAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAP///gAAAAAAAAAAAAAAAA
+ B///wAAAAAAAAAAAAAAAAAP//8AAAAAAAAAAAAAAAAAD//+AAAAAAAAAAAAAAAAAAf//gAAAAAAAAAAA
+ AAAAAAH//wAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAH/+AAAAAAAAAAAAAAAAAAB//gAAAAAA
+ AAAAAAAAAAAAf/wAAAAAAAAAAAAAAAAAAD/8AAAAAAAAAAAAAAAAAAA//AAAAAAAAAAAAAAAAAAAP/gA
+ AAAAAAAAAAAAAAAAAB/4AAAAAAAAAAAAAAAAAAAf+AAAAAAAAAAAAAAAAAAAH/gAAAAAAAAAAAAAAAAA
+ AB/wAAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAD+AAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAA
+ AAAAAAAH4AAAAAAAAAAAAAAAAAAAB+AAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAH4AAAAAAA
+ AAAAAAAAAAAAB+AAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAHwAAAAAAAAAAAAAAAAAAAA8AA
+ AAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAA
+ AAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAA
+ AAAAAAADwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAA
+ AAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAPgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB+AA
+ AAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB+AAAAAAAAAAAAAAAAAA
+ AAfgAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAB/AAAAAAAAAAAAAAAAAAAA/wAAAAAAAAAAAA
+ AAAAAAAP8AAAAAAAAAAAAAAAAAAAD/gAAAAAAAAAAAAAAAAAAB/4AAAAAAAAAAAAAAAAAAAf+AAAAAAA
+ AAAAAAAAAAAAH/gAAAAAAAAAAAAAAAAAAB/8AAAAAAAAAAAAAAAAAAA//QAAAAAAAAAAAAAAAAAAv/4A
+ AAAAAAAAAAAAAAAAAH/+AAAAAAAAAAAAAAAAAAB//gAAAAAAAAAAAAAAAAAAf/8AAAAAAAAAAAAAAAAA
+ AP//QAAAAAAAAAAAAAAAAAL//4AAAAAAAAAAAAAAAAAB//+AAAAAAAAAAAAAAAAAAf//wAAAAAAAAAAA
+ AAAAAAP//9AAAAAAAAAAAAAAAAAL///gAAAAAAAAAAAAAAAAB///4AAAAAAAAAAAAAAAAAf///QAAAAA
+ AAAAAAAAAAAv///4AAAAAAAAAAAAAAAAH///+AAAAAAAAAAAAAAAAB////0AAAAAAAAAAAAAAAC////+
+ AAAAAAAAAAAAAAAAf////gAAAAAAAAAAAAAAAH////8AAAAAAAAAAAAAAAD/////gAAAAAAAAAAAAAAB
+ /////9AAAAAAAAAAAAAAC//////gAAAAAAAAAAAAAAf/////9AAAAAAAAAAAAAAv//////gAAAAAAAAA
+ AAAAH//////9AAAAAAAAAAAAAL///////gAAAAAAAAAAAAB///////8AAAAAAAAAAAAA////////gAAA
+ AAAAAAAAAf///////8AAAAAAAAAAAAP////////wAAAAAAAAAAAP////////+AAAAAAAAAAAH///////
+ //4AAAAAAAAAAH//////////AAAAAAAAAAD//////////8AAAAAAAAAD///////////gAAAAAAAAB///
+ /////////AAAAAAAAD////////////4QAAAAAAh/////////////4AAAAAAH//////////////gAAAAA
+ H///////////////gEACAf////////////////AAAA//////////////////////////////////////
+ //////////////////////////////////8=
+
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/ListViewFlickerFree.cs b/v2rayN/v2rayN/Forms/ListViewFlickerFree.cs
new file mode 100644
index 00000000..6b7cb451
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/ListViewFlickerFree.cs
@@ -0,0 +1,56 @@
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace v2rayN.Forms
+{
+ class ListViewFlickerFree : ListView
+ {
+ public ListViewFlickerFree()
+ {
+ SetStyle(ControlStyles.OptimizedDoubleBuffer
+ | ControlStyles.AllPaintingInWmPaint
+ , true);
+ UpdateStyles();
+ }
+
+
+ public void AutoResizeColumns()
+ {
+ try
+ {
+ int count = this.Columns.Count;
+ int MaxWidth = 0;
+ Graphics graphics = this.CreateGraphics();
+ Font font = this.Font;
+ ListView.ListViewItemCollection items = this.Items;
+
+ string str;
+ int width;
+
+ this.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
+
+ for (int i = 0; i < count; i++)
+ {
+ str = this.Columns[i].Text;
+ MaxWidth = this.Columns[i].Width;
+
+ foreach (ListViewItem item in items)
+ {
+ str = item.SubItems[i].Text;
+ width = (int)graphics.MeasureString(str, font).Width;
+ if (width > MaxWidth)
+ {
+ MaxWidth = width;
+ }
+ }
+ if (i == 0)
+ {
+ this.Columns[i].Width = MaxWidth;
+ }
+ this.Columns[i].Width = MaxWidth;
+ }
+ }
+ catch { }
+ }
+ }
+}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/MainForm.Designer.cs b/v2rayN/v2rayN/Forms/MainForm.Designer.cs
new file mode 100644
index 00000000..5f161aba
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/MainForm.Designer.cs
@@ -0,0 +1,873 @@
+namespace v2rayN.Forms
+{
+ partial class MainForm
+ {
+ ///
+ /// 必需的设计器变量。
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 清理所有正在使用的资源。
+ ///
+ /// 如果应释放托管资源,为 true;否则为 false。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows 窗体设计器生成的代码
+
+ ///
+ /// 设计器支持所需的方法 - 不要
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.lvServers = new v2rayN.Forms.ListViewFlickerFree();
+ this.cmsLv = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.menuAddVmessServer = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuAddShadowsocksServer = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuAddSocksServer = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuAddCustomServer = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuAddServers = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuScanScreen = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
+ this.menuRemoveServer = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuRemoveDuplicateServer = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuCopyServer = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuSetDefaultServer = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
+ this.menuMoveTop = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuMoveUp = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuMoveDown = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuMoveBottom = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuSelectAll = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator();
+ this.menuPingServer = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuTcpingServer = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuRealPingServer = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuSpeedServer = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
+ this.menuExport2ClientConfig = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuExport2ServerConfig = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuExport2ShareUrl = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuExport2SubContent = new System.Windows.Forms.ToolStripMenuItem();
+ this.qrCodeControl = new v2rayN.Forms.QRCodeControl();
+ this.tsbServer = new System.Windows.Forms.ToolStripDropDownButton();
+ this.notifyMain = new System.Windows.Forms.NotifyIcon(this.components);
+ this.cmsMain = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.menuSysAgentEnabled = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuSysAgentMode = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuGlobal = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuGlobalPAC = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuKeep = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuKeepPAC = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuServers = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuAddServers2 = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuScanScreen2 = new System.Windows.Forms.ToolStripMenuItem();
+ this.menuCopyPACUrl = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
+ this.menuExit = new System.Windows.Forms.ToolStripMenuItem();
+ this.bgwScan = new System.ComponentModel.BackgroundWorker();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.groupBox2 = new System.Windows.Forms.GroupBox();
+ this.txtMsgBox = new System.Windows.Forms.TextBox();
+ this.ssMain = new System.Windows.Forms.StatusStrip();
+ this.toolSslSocksPortLab = new System.Windows.Forms.ToolStripStatusLabel();
+ this.toolSslSocksPort = new System.Windows.Forms.ToolStripStatusLabel();
+ this.toolSslBlank1 = new System.Windows.Forms.ToolStripStatusLabel();
+ this.toolSslHttpPortLab = new System.Windows.Forms.ToolStripStatusLabel();
+ this.toolSslHttpPort = new System.Windows.Forms.ToolStripStatusLabel();
+ this.toolSslBlank2 = new System.Windows.Forms.ToolStripStatusLabel();
+ this.toolSslPacPortLab = new System.Windows.Forms.ToolStripStatusLabel();
+ this.toolSslPacPort = new System.Windows.Forms.ToolStripStatusLabel();
+ this.toolSslBlank3 = new System.Windows.Forms.ToolStripStatusLabel();
+ this.toolSslServerSpeed = new System.Windows.Forms.ToolStripStatusLabel();
+ this.toolSslBlank4 = new System.Windows.Forms.ToolStripStatusLabel();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.tsMain = new System.Windows.Forms.ToolStrip();
+ this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
+ this.tsbSub = new System.Windows.Forms.ToolStripDropDownButton();
+ this.tsbSubSetting = new System.Windows.Forms.ToolStripMenuItem();
+ this.tsbSubUpdate = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator();
+ this.tsbOptionSetting = new System.Windows.Forms.ToolStripButton();
+ this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
+ this.tsbReload = new System.Windows.Forms.ToolStripButton();
+ this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator();
+ this.tsbCheckUpdate = new System.Windows.Forms.ToolStripDropDownButton();
+ this.tsbCheckUpdateN = new System.Windows.Forms.ToolStripMenuItem();
+ this.tsbCheckUpdateCore = new System.Windows.Forms.ToolStripMenuItem();
+ this.tsbCheckUpdatePACList = new System.Windows.Forms.ToolStripMenuItem();
+ this.tsbCheckClearPACList = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSeparator10 = new System.Windows.Forms.ToolStripSeparator();
+ this.tsbHelp = new System.Windows.Forms.ToolStripDropDownButton();
+ this.tsbAbout = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSeparator12 = new System.Windows.Forms.ToolStripSeparator();
+ this.tsbLanguageDef = new System.Windows.Forms.ToolStripMenuItem();
+ this.tsbLanguageZhHans = new System.Windows.Forms.ToolStripMenuItem();
+ this.tsbPromotion = new System.Windows.Forms.ToolStripButton();
+ this.toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator();
+ this.tsbClose = new System.Windows.Forms.ToolStripButton();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.cmsLv.SuspendLayout();
+ this.cmsMain.SuspendLayout();
+ this.groupBox1.SuspendLayout();
+ this.groupBox2.SuspendLayout();
+ this.ssMain.SuspendLayout();
+ this.tsMain.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // splitContainer1
+ //
+ resources.ApplyResources(this.splitContainer1, "splitContainer1");
+ this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
+ this.splitContainer1.Name = "splitContainer1";
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.Controls.Add(this.lvServers);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.Controls.Add(this.qrCodeControl);
+ this.splitContainer1.SplitterMoved += new System.Windows.Forms.SplitterEventHandler(this.splitContainer1_SplitterMoved);
+ //
+ // lvServers
+ //
+ this.lvServers.ContextMenuStrip = this.cmsLv;
+ resources.ApplyResources(this.lvServers, "lvServers");
+ this.lvServers.FullRowSelect = true;
+ this.lvServers.GridLines = true;
+ this.lvServers.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
+ this.lvServers.HideSelection = false;
+ this.lvServers.Items.AddRange(new System.Windows.Forms.ListViewItem[] {
+ ((System.Windows.Forms.ListViewItem)(resources.GetObject("lvServers.Items")))});
+ this.lvServers.MultiSelect = false;
+ this.lvServers.Name = "lvServers";
+ this.lvServers.UseCompatibleStateImageBehavior = false;
+ this.lvServers.View = System.Windows.Forms.View.Details;
+ this.lvServers.SelectedIndexChanged += new System.EventHandler(this.lvServers_SelectedIndexChanged);
+ this.lvServers.DoubleClick += new System.EventHandler(this.lvServers_DoubleClick);
+ this.lvServers.KeyDown += new System.Windows.Forms.KeyEventHandler(this.lvServers_KeyDown);
+ //
+ // cmsLv
+ //
+ this.cmsLv.ImageScalingSize = new System.Drawing.Size(20, 20);
+ this.cmsLv.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.menuAddVmessServer,
+ this.menuAddShadowsocksServer,
+ this.menuAddSocksServer,
+ this.menuAddCustomServer,
+ this.menuAddServers,
+ this.menuScanScreen,
+ this.toolStripSeparator1,
+ this.menuRemoveServer,
+ this.menuRemoveDuplicateServer,
+ this.menuCopyServer,
+ this.menuSetDefaultServer,
+ this.toolStripSeparator3,
+ this.menuMoveTop,
+ this.menuMoveUp,
+ this.menuMoveDown,
+ this.menuMoveBottom,
+ this.menuSelectAll,
+ this.toolStripSeparator9,
+ this.menuPingServer,
+ this.menuTcpingServer,
+ this.menuRealPingServer,
+ this.menuSpeedServer,
+ this.toolStripSeparator6,
+ this.menuExport2ClientConfig,
+ this.menuExport2ServerConfig,
+ this.menuExport2ShareUrl,
+ this.menuExport2SubContent});
+ this.cmsLv.Name = "cmsLv";
+ this.cmsLv.OwnerItem = this.tsbServer;
+ resources.ApplyResources(this.cmsLv, "cmsLv");
+ //
+ // menuAddVmessServer
+ //
+ this.menuAddVmessServer.Name = "menuAddVmessServer";
+ resources.ApplyResources(this.menuAddVmessServer, "menuAddVmessServer");
+ this.menuAddVmessServer.Click += new System.EventHandler(this.menuAddVmessServer_Click);
+ //
+ // menuAddShadowsocksServer
+ //
+ this.menuAddShadowsocksServer.Name = "menuAddShadowsocksServer";
+ resources.ApplyResources(this.menuAddShadowsocksServer, "menuAddShadowsocksServer");
+ this.menuAddShadowsocksServer.Click += new System.EventHandler(this.menuAddShadowsocksServer_Click);
+ //
+ // menuAddSocksServer
+ //
+ this.menuAddSocksServer.Name = "menuAddSocksServer";
+ resources.ApplyResources(this.menuAddSocksServer, "menuAddSocksServer");
+ this.menuAddSocksServer.Click += new System.EventHandler(this.menuAddSocksServer_Click);
+ //
+ // menuAddCustomServer
+ //
+ this.menuAddCustomServer.Name = "menuAddCustomServer";
+ resources.ApplyResources(this.menuAddCustomServer, "menuAddCustomServer");
+ this.menuAddCustomServer.Click += new System.EventHandler(this.menuAddCustomServer_Click);
+ //
+ // menuAddServers
+ //
+ this.menuAddServers.Name = "menuAddServers";
+ resources.ApplyResources(this.menuAddServers, "menuAddServers");
+ this.menuAddServers.Click += new System.EventHandler(this.menuAddServers_Click);
+ //
+ // menuScanScreen
+ //
+ this.menuScanScreen.Name = "menuScanScreen";
+ resources.ApplyResources(this.menuScanScreen, "menuScanScreen");
+ this.menuScanScreen.Click += new System.EventHandler(this.menuScanScreen_Click);
+ //
+ // toolStripSeparator1
+ //
+ this.toolStripSeparator1.Name = "toolStripSeparator1";
+ resources.ApplyResources(this.toolStripSeparator1, "toolStripSeparator1");
+ //
+ // menuRemoveServer
+ //
+ this.menuRemoveServer.Name = "menuRemoveServer";
+ resources.ApplyResources(this.menuRemoveServer, "menuRemoveServer");
+ this.menuRemoveServer.Click += new System.EventHandler(this.menuRemoveServer_Click);
+ //
+ // menuRemoveDuplicateServer
+ //
+ this.menuRemoveDuplicateServer.Name = "menuRemoveDuplicateServer";
+ resources.ApplyResources(this.menuRemoveDuplicateServer, "menuRemoveDuplicateServer");
+ this.menuRemoveDuplicateServer.Click += new System.EventHandler(this.menuRemoveDuplicateServer_Click);
+ //
+ // menuCopyServer
+ //
+ this.menuCopyServer.Name = "menuCopyServer";
+ resources.ApplyResources(this.menuCopyServer, "menuCopyServer");
+ this.menuCopyServer.Click += new System.EventHandler(this.menuCopyServer_Click);
+ //
+ // menuSetDefaultServer
+ //
+ this.menuSetDefaultServer.Name = "menuSetDefaultServer";
+ resources.ApplyResources(this.menuSetDefaultServer, "menuSetDefaultServer");
+ this.menuSetDefaultServer.Click += new System.EventHandler(this.menuSetDefaultServer_Click);
+ //
+ // toolStripSeparator3
+ //
+ this.toolStripSeparator3.Name = "toolStripSeparator3";
+ resources.ApplyResources(this.toolStripSeparator3, "toolStripSeparator3");
+ //
+ // menuMoveTop
+ //
+ this.menuMoveTop.Name = "menuMoveTop";
+ resources.ApplyResources(this.menuMoveTop, "menuMoveTop");
+ this.menuMoveTop.Click += new System.EventHandler(this.menuMoveTop_Click);
+ //
+ // menuMoveUp
+ //
+ this.menuMoveUp.Name = "menuMoveUp";
+ resources.ApplyResources(this.menuMoveUp, "menuMoveUp");
+ this.menuMoveUp.Click += new System.EventHandler(this.menuMoveUp_Click);
+ //
+ // menuMoveDown
+ //
+ this.menuMoveDown.Name = "menuMoveDown";
+ resources.ApplyResources(this.menuMoveDown, "menuMoveDown");
+ this.menuMoveDown.Click += new System.EventHandler(this.menuMoveDown_Click);
+ //
+ // menuMoveBottom
+ //
+ this.menuMoveBottom.Name = "menuMoveBottom";
+ resources.ApplyResources(this.menuMoveBottom, "menuMoveBottom");
+ this.menuMoveBottom.Click += new System.EventHandler(this.menuMoveBottom_Click);
+ //
+ // menuSelectAll
+ //
+ this.menuSelectAll.Name = "menuSelectAll";
+ resources.ApplyResources(this.menuSelectAll, "menuSelectAll");
+ this.menuSelectAll.Click += new System.EventHandler(this.menuSelectAll_Click);
+ //
+ // toolStripSeparator9
+ //
+ this.toolStripSeparator9.Name = "toolStripSeparator9";
+ resources.ApplyResources(this.toolStripSeparator9, "toolStripSeparator9");
+ //
+ // menuPingServer
+ //
+ this.menuPingServer.Name = "menuPingServer";
+ resources.ApplyResources(this.menuPingServer, "menuPingServer");
+ this.menuPingServer.Click += new System.EventHandler(this.menuPingServer_Click);
+ //
+ // menuTcpingServer
+ //
+ this.menuTcpingServer.Name = "menuTcpingServer";
+ resources.ApplyResources(this.menuTcpingServer, "menuTcpingServer");
+ this.menuTcpingServer.Click += new System.EventHandler(this.menuTcpingServer_Click);
+ //
+ // menuRealPingServer
+ //
+ this.menuRealPingServer.Name = "menuRealPingServer";
+ resources.ApplyResources(this.menuRealPingServer, "menuRealPingServer");
+ this.menuRealPingServer.Click += new System.EventHandler(this.menuRealPingServer_Click);
+ //
+ // menuSpeedServer
+ //
+ this.menuSpeedServer.Name = "menuSpeedServer";
+ resources.ApplyResources(this.menuSpeedServer, "menuSpeedServer");
+ this.menuSpeedServer.Click += new System.EventHandler(this.menuSpeedServer_Click);
+ //
+ // toolStripSeparator6
+ //
+ this.toolStripSeparator6.Name = "toolStripSeparator6";
+ resources.ApplyResources(this.toolStripSeparator6, "toolStripSeparator6");
+ //
+ // menuExport2ClientConfig
+ //
+ this.menuExport2ClientConfig.Name = "menuExport2ClientConfig";
+ resources.ApplyResources(this.menuExport2ClientConfig, "menuExport2ClientConfig");
+ this.menuExport2ClientConfig.Click += new System.EventHandler(this.menuExport2ClientConfig_Click);
+ //
+ // menuExport2ServerConfig
+ //
+ this.menuExport2ServerConfig.Name = "menuExport2ServerConfig";
+ resources.ApplyResources(this.menuExport2ServerConfig, "menuExport2ServerConfig");
+ this.menuExport2ServerConfig.Click += new System.EventHandler(this.menuExport2ServerConfig_Click);
+ //
+ // menuExport2ShareUrl
+ //
+ this.menuExport2ShareUrl.Name = "menuExport2ShareUrl";
+ resources.ApplyResources(this.menuExport2ShareUrl, "menuExport2ShareUrl");
+ this.menuExport2ShareUrl.Click += new System.EventHandler(this.menuExport2ShareUrl_Click);
+ //
+ // menuExport2SubContent
+ //
+ this.menuExport2SubContent.Name = "menuExport2SubContent";
+ resources.ApplyResources(this.menuExport2SubContent, "menuExport2SubContent");
+ this.menuExport2SubContent.Click += new System.EventHandler(this.menuExport2SubContent_Click);
+ //
+ // qrCodeControl
+ //
+ resources.ApplyResources(this.qrCodeControl, "qrCodeControl");
+ this.qrCodeControl.Name = "qrCodeControl";
+ //
+ // tsbServer
+ //
+ this.tsbServer.DropDown = this.cmsLv;
+ this.tsbServer.Image = global::v2rayN.Properties.Resources.server;
+ resources.ApplyResources(this.tsbServer, "tsbServer");
+ this.tsbServer.Name = "tsbServer";
+ //
+ // notifyMain
+ //
+ this.notifyMain.ContextMenuStrip = this.cmsMain;
+ resources.ApplyResources(this.notifyMain, "notifyMain");
+ this.notifyMain.MouseClick += new System.Windows.Forms.MouseEventHandler(this.notifyMain_MouseClick);
+ //
+ // cmsMain
+ //
+ this.cmsMain.ImageScalingSize = new System.Drawing.Size(20, 20);
+ resources.ApplyResources(this.cmsMain, "cmsMain");
+ this.cmsMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.menuSysAgentEnabled,
+ this.menuSysAgentMode,
+ this.menuServers,
+ this.menuAddServers2,
+ this.menuScanScreen2,
+ this.menuCopyPACUrl,
+ this.toolStripSeparator2,
+ this.menuExit});
+ this.cmsMain.Name = "contextMenuStrip1";
+ this.cmsMain.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;
+ this.cmsMain.ShowCheckMargin = true;
+ this.cmsMain.ShowImageMargin = false;
+ //
+ // menuSysAgentEnabled
+ //
+ this.menuSysAgentEnabled.Name = "menuSysAgentEnabled";
+ resources.ApplyResources(this.menuSysAgentEnabled, "menuSysAgentEnabled");
+ this.menuSysAgentEnabled.Click += new System.EventHandler(this.menuSysAgentEnabled_Click);
+ //
+ // menuSysAgentMode
+ //
+ this.menuSysAgentMode.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.menuGlobal,
+ this.menuGlobalPAC,
+ this.menuKeep,
+ this.menuKeepPAC});
+ this.menuSysAgentMode.Name = "menuSysAgentMode";
+ resources.ApplyResources(this.menuSysAgentMode, "menuSysAgentMode");
+ //
+ // menuGlobal
+ //
+ this.menuGlobal.Name = "menuGlobal";
+ resources.ApplyResources(this.menuGlobal, "menuGlobal");
+ this.menuGlobal.Click += new System.EventHandler(this.menuGlobal_Click);
+ //
+ // menuGlobalPAC
+ //
+ this.menuGlobalPAC.Name = "menuGlobalPAC";
+ resources.ApplyResources(this.menuGlobalPAC, "menuGlobalPAC");
+ this.menuGlobalPAC.Click += new System.EventHandler(this.menuGlobalPAC_Click);
+ //
+ // menuKeep
+ //
+ this.menuKeep.Name = "menuKeep";
+ resources.ApplyResources(this.menuKeep, "menuKeep");
+ this.menuKeep.Click += new System.EventHandler(this.menuKeep_Click);
+ //
+ // menuKeepPAC
+ //
+ this.menuKeepPAC.Name = "menuKeepPAC";
+ resources.ApplyResources(this.menuKeepPAC, "menuKeepPAC");
+ this.menuKeepPAC.Click += new System.EventHandler(this.menuKeepPAC_Click);
+ //
+ // menuServers
+ //
+ this.menuServers.Name = "menuServers";
+ resources.ApplyResources(this.menuServers, "menuServers");
+ //
+ // menuAddServers2
+ //
+ this.menuAddServers2.Name = "menuAddServers2";
+ resources.ApplyResources(this.menuAddServers2, "menuAddServers2");
+ this.menuAddServers2.Click += new System.EventHandler(this.menuAddServers_Click);
+ //
+ // menuScanScreen2
+ //
+ this.menuScanScreen2.Name = "menuScanScreen2";
+ resources.ApplyResources(this.menuScanScreen2, "menuScanScreen2");
+ this.menuScanScreen2.Click += new System.EventHandler(this.menuScanScreen_Click);
+ //
+ // menuCopyPACUrl
+ //
+ this.menuCopyPACUrl.Name = "menuCopyPACUrl";
+ resources.ApplyResources(this.menuCopyPACUrl, "menuCopyPACUrl");
+ this.menuCopyPACUrl.Click += new System.EventHandler(this.menuCopyPACUrl_Click);
+ //
+ // toolStripSeparator2
+ //
+ this.toolStripSeparator2.Name = "toolStripSeparator2";
+ resources.ApplyResources(this.toolStripSeparator2, "toolStripSeparator2");
+ //
+ // menuExit
+ //
+ this.menuExit.Name = "menuExit";
+ resources.ApplyResources(this.menuExit, "menuExit");
+ this.menuExit.Click += new System.EventHandler(this.menuExit_Click);
+ //
+ // bgwScan
+ //
+ this.bgwScan.WorkerReportsProgress = true;
+ this.bgwScan.DoWork += new System.ComponentModel.DoWorkEventHandler(this.bgwScan_DoWork);
+ this.bgwScan.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.bgwScan_ProgressChanged);
+ //
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.splitContainer1);
+ resources.ApplyResources(this.groupBox1, "groupBox1");
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.TabStop = false;
+ //
+ // groupBox2
+ //
+ this.groupBox2.Controls.Add(this.txtMsgBox);
+ this.groupBox2.Controls.Add(this.ssMain);
+ resources.ApplyResources(this.groupBox2, "groupBox2");
+ this.groupBox2.Name = "groupBox2";
+ this.groupBox2.TabStop = false;
+ //
+ // txtMsgBox
+ //
+ this.txtMsgBox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(41)))), ((int)(((byte)(49)))), ((int)(((byte)(52)))));
+ this.txtMsgBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
+ resources.ApplyResources(this.txtMsgBox, "txtMsgBox");
+ this.txtMsgBox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(226)))), ((int)(((byte)(228)))));
+ this.txtMsgBox.Name = "txtMsgBox";
+ this.txtMsgBox.ReadOnly = true;
+ //
+ // ssMain
+ //
+ this.ssMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.toolSslSocksPortLab,
+ this.toolSslSocksPort,
+ this.toolSslBlank1,
+ this.toolSslHttpPortLab,
+ this.toolSslHttpPort,
+ this.toolSslBlank2,
+ this.toolSslPacPortLab,
+ this.toolSslPacPort,
+ this.toolSslBlank3,
+ this.toolSslServerSpeed,
+ this.toolSslBlank4});
+ resources.ApplyResources(this.ssMain, "ssMain");
+ this.ssMain.Name = "ssMain";
+ this.ssMain.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.ssMain_ItemClicked);
+ //
+ // toolSslSocksPortLab
+ //
+ resources.ApplyResources(this.toolSslSocksPortLab, "toolSslSocksPortLab");
+ this.toolSslSocksPortLab.Name = "toolSslSocksPortLab";
+ //
+ // toolSslSocksPort
+ //
+ this.toolSslSocksPort.Name = "toolSslSocksPort";
+ resources.ApplyResources(this.toolSslSocksPort, "toolSslSocksPort");
+ //
+ // toolSslBlank1
+ //
+ resources.ApplyResources(this.toolSslBlank1, "toolSslBlank1");
+ this.toolSslBlank1.Name = "toolSslBlank1";
+ this.toolSslBlank1.Spring = true;
+ //
+ // toolSslHttpPortLab
+ //
+ resources.ApplyResources(this.toolSslHttpPortLab, "toolSslHttpPortLab");
+ this.toolSslHttpPortLab.Name = "toolSslHttpPortLab";
+ //
+ // toolSslHttpPort
+ //
+ this.toolSslHttpPort.Name = "toolSslHttpPort";
+ resources.ApplyResources(this.toolSslHttpPort, "toolSslHttpPort");
+ //
+ // toolSslBlank2
+ //
+ resources.ApplyResources(this.toolSslBlank2, "toolSslBlank2");
+ this.toolSslBlank2.Name = "toolSslBlank2";
+ this.toolSslBlank2.Spring = true;
+ //
+ // toolSslPacPortLab
+ //
+ resources.ApplyResources(this.toolSslPacPortLab, "toolSslPacPortLab");
+ this.toolSslPacPortLab.Name = "toolSslPacPortLab";
+ //
+ // toolSslPacPort
+ //
+ this.toolSslPacPort.Name = "toolSslPacPort";
+ resources.ApplyResources(this.toolSslPacPort, "toolSslPacPort");
+ //
+ // toolSslBlank3
+ //
+ resources.ApplyResources(this.toolSslBlank3, "toolSslBlank3");
+ this.toolSslBlank3.Name = "toolSslBlank3";
+ this.toolSslBlank3.Spring = true;
+ //
+ // toolSslServerSpeed
+ //
+ resources.ApplyResources(this.toolSslServerSpeed, "toolSslServerSpeed");
+ this.toolSslServerSpeed.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+ this.toolSslServerSpeed.Name = "toolSslServerSpeed";
+ //
+ // toolSslBlank4
+ //
+ this.toolSslBlank4.Name = "toolSslBlank4";
+ resources.ApplyResources(this.toolSslBlank4, "toolSslBlank4");
+ //
+ // panel1
+ //
+ resources.ApplyResources(this.panel1, "panel1");
+ this.panel1.Name = "panel1";
+ //
+ // tsMain
+ //
+ this.tsMain.ImageScalingSize = new System.Drawing.Size(32, 32);
+ this.tsMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.tsbServer,
+ this.toolStripSeparator4,
+ this.tsbSub,
+ this.toolStripSeparator8,
+ this.tsbOptionSetting,
+ this.toolStripSeparator5,
+ this.tsbReload,
+ this.toolStripSeparator7,
+ this.tsbCheckUpdate,
+ this.toolStripSeparator10,
+ this.tsbHelp,
+ this.tsbPromotion,
+ this.toolStripSeparator11,
+ this.tsbClose});
+ resources.ApplyResources(this.tsMain, "tsMain");
+ this.tsMain.Name = "tsMain";
+ //
+ // toolStripSeparator4
+ //
+ this.toolStripSeparator4.Name = "toolStripSeparator4";
+ resources.ApplyResources(this.toolStripSeparator4, "toolStripSeparator4");
+ //
+ // tsbSub
+ //
+ this.tsbSub.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.tsbSubSetting,
+ this.tsbSubUpdate});
+ this.tsbSub.Image = global::v2rayN.Properties.Resources.sub;
+ resources.ApplyResources(this.tsbSub, "tsbSub");
+ this.tsbSub.Name = "tsbSub";
+ //
+ // tsbSubSetting
+ //
+ this.tsbSubSetting.Name = "tsbSubSetting";
+ resources.ApplyResources(this.tsbSubSetting, "tsbSubSetting");
+ this.tsbSubSetting.Click += new System.EventHandler(this.tsbSubSetting_Click);
+ //
+ // tsbSubUpdate
+ //
+ this.tsbSubUpdate.Name = "tsbSubUpdate";
+ resources.ApplyResources(this.tsbSubUpdate, "tsbSubUpdate");
+ this.tsbSubUpdate.Click += new System.EventHandler(this.tsbSubUpdate_Click);
+ //
+ // toolStripSeparator8
+ //
+ this.toolStripSeparator8.Name = "toolStripSeparator8";
+ resources.ApplyResources(this.toolStripSeparator8, "toolStripSeparator8");
+ //
+ // tsbOptionSetting
+ //
+ this.tsbOptionSetting.Image = global::v2rayN.Properties.Resources.option;
+ resources.ApplyResources(this.tsbOptionSetting, "tsbOptionSetting");
+ this.tsbOptionSetting.Name = "tsbOptionSetting";
+ this.tsbOptionSetting.Click += new System.EventHandler(this.tsbOptionSetting_Click);
+ //
+ // toolStripSeparator5
+ //
+ this.toolStripSeparator5.Name = "toolStripSeparator5";
+ resources.ApplyResources(this.toolStripSeparator5, "toolStripSeparator5");
+ //
+ // tsbReload
+ //
+ resources.ApplyResources(this.tsbReload, "tsbReload");
+ this.tsbReload.Name = "tsbReload";
+ this.tsbReload.Click += new System.EventHandler(this.tsbReload_Click);
+ //
+ // toolStripSeparator7
+ //
+ this.toolStripSeparator7.Name = "toolStripSeparator7";
+ resources.ApplyResources(this.toolStripSeparator7, "toolStripSeparator7");
+ //
+ // tsbCheckUpdate
+ //
+ this.tsbCheckUpdate.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.tsbCheckUpdateN,
+ this.tsbCheckUpdateCore,
+ this.tsbCheckUpdatePACList,
+ this.tsbCheckClearPACList});
+ this.tsbCheckUpdate.Image = global::v2rayN.Properties.Resources.checkupdate;
+ resources.ApplyResources(this.tsbCheckUpdate, "tsbCheckUpdate");
+ this.tsbCheckUpdate.Name = "tsbCheckUpdate";
+ //
+ // tsbCheckUpdateN
+ //
+ this.tsbCheckUpdateN.Name = "tsbCheckUpdateN";
+ resources.ApplyResources(this.tsbCheckUpdateN, "tsbCheckUpdateN");
+ this.tsbCheckUpdateN.Click += new System.EventHandler(this.tsbCheckUpdateN_Click);
+ //
+ // tsbCheckUpdateCore
+ //
+ this.tsbCheckUpdateCore.Name = "tsbCheckUpdateCore";
+ resources.ApplyResources(this.tsbCheckUpdateCore, "tsbCheckUpdateCore");
+ this.tsbCheckUpdateCore.Click += new System.EventHandler(this.tsbCheckUpdateCore_Click);
+ //
+ // tsbCheckUpdatePACList
+ //
+ this.tsbCheckUpdatePACList.Name = "tsbCheckUpdatePACList";
+ resources.ApplyResources(this.tsbCheckUpdatePACList, "tsbCheckUpdatePACList");
+ this.tsbCheckUpdatePACList.Click += new System.EventHandler(this.tsbCheckUpdatePACList_Click);
+ //
+ // tsbCheckClearPACList
+ //
+ this.tsbCheckClearPACList.Name = "tsbCheckClearPACList";
+ resources.ApplyResources(this.tsbCheckClearPACList, "tsbCheckClearPACList");
+ this.tsbCheckClearPACList.Click += new System.EventHandler(this.tsbCheckClearPACList_Click);
+ //
+ // toolStripSeparator10
+ //
+ this.toolStripSeparator10.Name = "toolStripSeparator10";
+ resources.ApplyResources(this.toolStripSeparator10, "toolStripSeparator10");
+ //
+ // tsbHelp
+ //
+ this.tsbHelp.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.tsbAbout,
+ this.toolStripSeparator12,
+ this.tsbLanguageDef,
+ this.tsbLanguageZhHans});
+ this.tsbHelp.Image = global::v2rayN.Properties.Resources.help;
+ resources.ApplyResources(this.tsbHelp, "tsbHelp");
+ this.tsbHelp.Name = "tsbHelp";
+ //
+ // tsbAbout
+ //
+ this.tsbAbout.Name = "tsbAbout";
+ resources.ApplyResources(this.tsbAbout, "tsbAbout");
+ this.tsbAbout.Click += new System.EventHandler(this.tsbAbout_Click);
+ //
+ // toolStripSeparator12
+ //
+ this.toolStripSeparator12.Name = "toolStripSeparator12";
+ resources.ApplyResources(this.toolStripSeparator12, "toolStripSeparator12");
+ //
+ // tsbLanguageDef
+ //
+ this.tsbLanguageDef.Name = "tsbLanguageDef";
+ resources.ApplyResources(this.tsbLanguageDef, "tsbLanguageDef");
+ this.tsbLanguageDef.Click += new System.EventHandler(this.tsbLanguageDef_Click);
+ //
+ // tsbLanguageZhHans
+ //
+ this.tsbLanguageZhHans.Name = "tsbLanguageZhHans";
+ resources.ApplyResources(this.tsbLanguageZhHans, "tsbLanguageZhHans");
+ this.tsbLanguageZhHans.Click += new System.EventHandler(this.tsbLanguageZhHans_Click);
+ //
+ // tsbPromotion
+ //
+ this.tsbPromotion.ForeColor = System.Drawing.Color.Black;
+ this.tsbPromotion.Image = global::v2rayN.Properties.Resources.promotion;
+ resources.ApplyResources(this.tsbPromotion, "tsbPromotion");
+ this.tsbPromotion.Name = "tsbPromotion";
+ this.tsbPromotion.Click += new System.EventHandler(this.tsbPromotion_Click);
+ //
+ // toolStripSeparator11
+ //
+ this.toolStripSeparator11.Name = "toolStripSeparator11";
+ resources.ApplyResources(this.toolStripSeparator11, "toolStripSeparator11");
+ //
+ // tsbClose
+ //
+ resources.ApplyResources(this.tsbClose, "tsbClose");
+ this.tsbClose.Name = "tsbClose";
+ this.tsbClose.Click += new System.EventHandler(this.tsbClose_Click);
+ //
+ // MainForm
+ //
+ resources.ApplyResources(this, "$this");
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.groupBox1);
+ this.Controls.Add(this.groupBox2);
+ this.Controls.Add(this.panel1);
+ this.Controls.Add(this.tsMain);
+ this.MaximizeBox = true;
+ this.MinimizeBox = true;
+ this.Name = "MainForm";
+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
+ this.Load += new System.EventHandler(this.MainForm_Load);
+ this.Shown += new System.EventHandler(this.MainForm_Shown);
+ this.VisibleChanged += new System.EventHandler(this.MainForm_VisibleChanged);
+ this.Resize += new System.EventHandler(this.MainForm_Resize);
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
+ this.splitContainer1.ResumeLayout(false);
+ this.cmsLv.ResumeLayout(false);
+ this.cmsMain.ResumeLayout(false);
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox2.ResumeLayout(false);
+ this.groupBox2.PerformLayout();
+ this.ssMain.ResumeLayout(false);
+ this.ssMain.PerformLayout();
+ this.tsMain.ResumeLayout(false);
+ this.tsMain.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.GroupBox groupBox2;
+ private System.Windows.Forms.TextBox txtMsgBox;
+ private v2rayN.Forms.ListViewFlickerFree lvServers;
+ private System.Windows.Forms.NotifyIcon notifyMain;
+ private System.Windows.Forms.ContextMenuStrip cmsMain;
+ private System.Windows.Forms.ToolStripMenuItem menuExit;
+ private System.Windows.Forms.Panel panel1;
+ private System.Windows.Forms.ToolStripMenuItem menuServers;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
+ private System.Windows.Forms.ContextMenuStrip cmsLv;
+ private System.Windows.Forms.ToolStripMenuItem menuAddVmessServer;
+ private System.Windows.Forms.ToolStripMenuItem menuRemoveServer;
+ private System.Windows.Forms.ToolStripMenuItem menuSetDefaultServer;
+ private System.Windows.Forms.ToolStripMenuItem menuCopyServer;
+ private System.Windows.Forms.ToolStripMenuItem menuPingServer;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
+ private System.Windows.Forms.ToolStripMenuItem menuExport2ClientConfig;
+ private System.Windows.Forms.ToolStripMenuItem menuExport2ServerConfig;
+ private System.Windows.Forms.ToolStrip tsMain;
+ private System.Windows.Forms.ToolStripDropDownButton tsbServer;
+ private System.Windows.Forms.ToolStripButton tsbOptionSetting;
+ private System.Windows.Forms.ToolStripButton tsbReload;
+ private System.Windows.Forms.ToolStripButton tsbClose;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
+ private System.Windows.Forms.ToolStripMenuItem menuMoveTop;
+ private System.Windows.Forms.ToolStripMenuItem menuMoveUp;
+ private System.Windows.Forms.ToolStripMenuItem menuMoveDown;
+ private System.Windows.Forms.ToolStripMenuItem menuMoveBottom;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator9;
+ private System.Windows.Forms.ToolStripMenuItem menuSysAgentMode;
+ private System.Windows.Forms.ToolStripMenuItem menuGlobal;
+ private System.Windows.Forms.ToolStripMenuItem menuGlobalPAC;
+ private System.Windows.Forms.ToolStripMenuItem menuKeep;
+ private System.Windows.Forms.ToolStripMenuItem menuSysAgentEnabled;
+ private System.Windows.Forms.ToolStripMenuItem menuCopyPACUrl;
+ private System.Windows.Forms.ToolStripMenuItem menuAddCustomServer;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
+ private System.Windows.Forms.ToolStripMenuItem menuAddShadowsocksServer;
+ private System.Windows.Forms.SplitContainer splitContainer1;
+ private QRCodeControl qrCodeControl;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator10;
+ private System.Windows.Forms.ToolStripDropDownButton tsbCheckUpdate;
+ private System.Windows.Forms.ToolStripMenuItem tsbCheckUpdateN;
+ private System.Windows.Forms.ToolStripMenuItem tsbCheckUpdateCore;
+ private System.Windows.Forms.ToolStripMenuItem tsbCheckUpdatePACList;
+ private System.Windows.Forms.ToolStripMenuItem menuAddServers;
+ private System.Windows.Forms.ToolStripMenuItem menuExport2ShareUrl;
+ private System.Windows.Forms.ToolStripMenuItem menuSpeedServer;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator11;
+ private System.Windows.Forms.ToolStripDropDownButton tsbHelp;
+ private System.Windows.Forms.ToolStripMenuItem tsbAbout;
+ private System.Windows.Forms.ToolStripMenuItem menuAddServers2;
+ private System.ComponentModel.BackgroundWorker bgwScan;
+ private System.Windows.Forms.ToolStripMenuItem menuScanScreen;
+ private System.Windows.Forms.ToolStripMenuItem menuScanScreen2;
+ private System.Windows.Forms.ToolStripDropDownButton tsbSub;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator8;
+ private System.Windows.Forms.ToolStripMenuItem tsbSubSetting;
+ private System.Windows.Forms.ToolStripMenuItem tsbSubUpdate;
+ private System.Windows.Forms.ToolStripMenuItem tsbCheckClearPACList;
+ private System.Windows.Forms.ToolStripMenuItem menuKeepPAC;
+ private System.Windows.Forms.ToolStripMenuItem menuSelectAll;
+ private System.Windows.Forms.ToolStripMenuItem menuExport2SubContent;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator12;
+ private System.Windows.Forms.ToolStripMenuItem tsbLanguageDef;
+ private System.Windows.Forms.ToolStripMenuItem tsbLanguageZhHans;
+ private System.Windows.Forms.ToolStripButton tsbPromotion;
+ private System.Windows.Forms.ToolStripMenuItem menuAddSocksServer;
+ private System.Windows.Forms.StatusStrip ssMain;
+ private System.Windows.Forms.ToolStripStatusLabel toolSslSocksPort;
+ private System.Windows.Forms.ToolStripStatusLabel toolSslHttpPort;
+ private System.Windows.Forms.ToolStripStatusLabel toolSslBlank2;
+ private System.Windows.Forms.ToolStripStatusLabel toolSslBlank1;
+ private System.Windows.Forms.ToolStripStatusLabel toolSslPacPort;
+ private System.Windows.Forms.ToolStripStatusLabel toolSslBlank3;
+ private System.Windows.Forms.ToolStripStatusLabel toolSslSocksPortLab;
+ private System.Windows.Forms.ToolStripStatusLabel toolSslHttpPortLab;
+ private System.Windows.Forms.ToolStripStatusLabel toolSslPacPortLab;
+ private System.Windows.Forms.ToolStripStatusLabel toolSslServerSpeed;
+ private System.Windows.Forms.ToolStripStatusLabel toolSslBlank4;
+ private System.Windows.Forms.ToolStripMenuItem menuRemoveDuplicateServer;
+ private System.Windows.Forms.ToolStripMenuItem menuTcpingServer;
+ private System.Windows.Forms.ToolStripMenuItem menuRealPingServer;
+ }
+}
+
diff --git a/v2rayN/v2rayN/Forms/MainForm.cs b/v2rayN/v2rayN/Forms/MainForm.cs
new file mode 100644
index 00000000..11ec3fdd
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/MainForm.cs
@@ -0,0 +1,1542 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.IO.Compression;
+using System.Text;
+using System.Windows.Forms;
+using v2rayN.Handler;
+using v2rayN.HttpProxyHandler;
+using v2rayN.Mode;
+
+namespace v2rayN.Forms
+{
+ public partial class MainForm : BaseForm
+ {
+ private V2rayHandler v2rayHandler;
+ private PACListHandle pacListHandle;
+ private V2rayUpdateHandle v2rayUpdateHandle;
+ private List lvSelecteds = new List();
+ private StatisticsHandler statistics = null;
+
+ #region Window 事件
+
+ public MainForm()
+ {
+ InitializeComponent();
+ this.ShowInTaskbar = false;
+ this.WindowState = FormWindowState.Minimized;
+ HideForm();
+ this.Text = Utils.GetVersion();
+
+ Application.ApplicationExit += (sender, args) =>
+ {
+ Utils.ClearTempPath();
+ statistics?.Close();
+ };
+ }
+
+ private void MainForm_Load(object sender, EventArgs e)
+ {
+ ConfigHandler.LoadConfig(ref config);
+ v2rayHandler = new V2rayHandler();
+ v2rayHandler.ProcessEvent += v2rayHandler_ProcessEvent;
+
+ if (config.enableStatistics)
+ {
+ statistics = new StatisticsHandler(config, UpdateStatisticsHandler);
+ }
+ }
+
+ private void MainForm_VisibleChanged(object sender, EventArgs e)
+ {
+ if (statistics == null || !statistics.Enable) return;
+ if ((sender as Form).Visible)
+ {
+ statistics.UpdateUI = true;
+ }
+ else
+ {
+ statistics.UpdateUI = false;
+ }
+ }
+
+ private void MainForm_Shown(object sender, EventArgs e)
+ {
+ InitServersView();
+ RefreshServers();
+ lvServers.AutoResizeColumns();
+
+ LoadV2ray();
+
+ HideForm();
+
+ }
+
+ private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ if (e.CloseReason == CloseReason.UserClosing)
+ {
+ e.Cancel = true;
+
+ statistics?.SaveToFile();
+
+ HideForm();
+ return;
+ }
+ if (e.CloseReason == CloseReason.ApplicationExitCall)
+ {
+ ConfigHandler.SaveConfig(ref config);
+ statistics?.SaveToFile();
+ statistics?.Close();
+ }
+ }
+
+ private void MainForm_Resize(object sender, EventArgs e)
+ {
+ //if (this.WindowState == FormWindowState.Minimized)
+ //{
+ // HideForm();
+ //}
+ //else
+ //{
+ // //this.splitContainer1.SplitterDistance = config.uiItem.mainQRCodeWidth;
+ //}
+ }
+
+ private void splitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
+ {
+ //config.uiItem.mainQRCodeWidth = splitContainer1.SplitterDistance;
+ }
+
+ private const int WM_QUERYENDSESSION = 0x0011;
+ protected override void WndProc(ref Message m)
+ {
+ switch (m.Msg)
+ {
+ case WM_QUERYENDSESSION:
+ Utils.SaveLog("Windows shutdown UnsetProxy");
+ //CloseV2ray();
+ ConfigHandler.ToJsonFile(config);
+ statistics?.SaveToFile();
+ ProxySetting.UnsetProxy();
+ m.Result = (IntPtr)1;
+ break;
+ default:
+ base.WndProc(ref m);
+ break;
+ }
+ }
+ #endregion
+
+ #region 显示服务器 listview 和 menu
+
+ ///
+ /// 刷新服务器
+ ///
+ private void RefreshServers()
+ {
+ RefreshServersView();
+ RefreshServersMenu();
+ }
+
+ ///
+ /// 初始化服务器列表
+ ///
+ private void InitServersView()
+ {
+ lvServers.Items.Clear();
+
+ lvServers.GridLines = true;
+ lvServers.FullRowSelect = true;
+ lvServers.View = View.Details;
+ lvServers.Scrollable = true;
+ lvServers.MultiSelect = true;
+ lvServers.HeaderStyle = ColumnHeaderStyle.Nonclickable;
+
+ lvServers.Columns.Add("", 30, HorizontalAlignment.Center);
+ lvServers.Columns.Add(UIRes.I18N("LvServiceType"), 80, HorizontalAlignment.Left);
+ lvServers.Columns.Add(UIRes.I18N("LvAlias"), 100, HorizontalAlignment.Left);
+ lvServers.Columns.Add(UIRes.I18N("LvAddress"), 120, HorizontalAlignment.Left);
+ lvServers.Columns.Add(UIRes.I18N("LvPort"), 50, HorizontalAlignment.Left);
+ lvServers.Columns.Add(UIRes.I18N("LvEncryptionMethod"), 90, HorizontalAlignment.Left);
+ lvServers.Columns.Add(UIRes.I18N("LvTransportProtocol"), 70, HorizontalAlignment.Left);
+ lvServers.Columns.Add(UIRes.I18N("LvSubscription"), 50, HorizontalAlignment.Left);
+ lvServers.Columns.Add(UIRes.I18N("LvTestResults"), 70, HorizontalAlignment.Left);
+
+ if (statistics != null && statistics.Enable)
+ {
+ lvServers.Columns.Add(UIRes.I18N("LvTotalUploadDataAmount"), 70, HorizontalAlignment.Left);
+ lvServers.Columns.Add(UIRes.I18N("LvTotalDownloadDataAmount"), 70, HorizontalAlignment.Left);
+ lvServers.Columns.Add(UIRes.I18N("LvTodayUploadDataAmount"), 70, HorizontalAlignment.Left);
+ lvServers.Columns.Add(UIRes.I18N("LvTodayDownloadDataAmount"), 70, HorizontalAlignment.Left);
+ }
+ }
+
+ ///
+ /// 刷新服务器列表
+ ///
+ private void RefreshServersView()
+ {
+ lvServers.Items.Clear();
+
+ for (int k = 0; k < config.vmess.Count; k++)
+ {
+ string def = string.Empty;
+ string totalUp = string.Empty,
+ totalDown = string.Empty,
+ todayUp = string.Empty,
+ todayDown = string.Empty;
+ if (config.index.Equals(k))
+ {
+ def = "√";
+ }
+
+ VmessItem item = config.vmess[k];
+
+ ListViewItem lvItem = null;
+ if (statistics != null && statistics.Enable)
+ {
+ var index = statistics.Statistic.FindIndex(item_ => item_.address == item.address);
+ if (index != -1)
+ {
+ totalUp = Utils.HumanFy(statistics.Statistic[index].totalUp);
+ totalDown = Utils.HumanFy(statistics.Statistic[index].totalDown);
+ todayUp = Utils.HumanFy(statistics.Statistic[index].todayUp);
+ todayDown = Utils.HumanFy(statistics.Statistic[index].todayDown);
+ }
+
+ lvItem = new ListViewItem(new string[]
+ {
+ def,
+ ((EConfigType)item.configType).ToString(),
+ item.remarks,
+ item.address,
+ item.port.ToString(),
+ //item.id,
+ //item.alterId.ToString(),
+ item.security,
+ item.network,
+ item.getSubRemarks(config),
+ item.testResult,
+ totalUp,
+ totalDown,
+ todayUp,
+ todayDown
+ });
+ }
+ else
+ {
+ lvItem = new ListViewItem(new string[]
+ {
+ def,
+ ((EConfigType)item.configType).ToString(),
+ item.remarks,
+ item.address,
+ item.port.ToString(),
+ //item.id,
+ //item.alterId.ToString(),
+ item.security,
+ item.network,
+ item.getSubRemarks(config),
+ item.testResult
+ //totalUp,
+ //totalDown,
+ //todayUp,
+ //todayDown,
+ });
+ }
+
+ if (lvItem != null) lvServers.Items.Add(lvItem);
+ }
+
+ //if (lvServers.Items.Count > 0)
+ //{
+ // if (lvServers.Items.Count <= testConfigIndex)
+ // {
+ // testConfigIndex = lvServers.Items.Count - 1;
+ // }
+ // lvServers.Items[testConfigIndex].Selected = true;
+ // lvServers.Select();
+ //}
+ }
+
+ ///
+ /// 刷新托盘服务器菜单
+ ///
+ private void RefreshServersMenu()
+ {
+ menuServers.DropDownItems.Clear();
+
+ for (int k = 0; k < config.vmess.Count; k++)
+ {
+ VmessItem item = config.vmess[k];
+ string name = item.getSummary();
+
+ ToolStripMenuItem ts = new ToolStripMenuItem(name);
+ ts.Tag = k;
+ if (config.index.Equals(k))
+ {
+ ts.Checked = true;
+ }
+ ts.Click += new EventHandler(ts_Click);
+ menuServers.DropDownItems.Add(ts);
+ }
+ }
+
+ private void ts_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ ToolStripItem ts = (ToolStripItem)sender;
+ int index = Utils.ToInt(ts.Tag);
+ SetDefaultServer(index);
+ }
+ catch
+ {
+ }
+ }
+
+ private void lvServers_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ int index = -1;
+ try
+ {
+ if (lvServers.SelectedIndices.Count > 0)
+ {
+ index = lvServers.SelectedIndices[0];
+ }
+ }
+ catch
+ {
+ }
+ if (index < 0)
+ {
+ return;
+ }
+ qrCodeControl.showQRCode(index, config);
+ }
+
+ private void DisplayToolStatus()
+ {
+ var localIP = "127.0.0.1";
+ toolSslSocksPort.Text =
+ toolSslHttpPort.Text =
+ toolSslPacPort.Text = "NONE";
+
+ toolSslSocksPort.Text = $"{localIP}:{config.inbound[0].localPort}";
+
+ if (config.sysAgentEnabled)
+ {
+ toolSslHttpPort.Text = $"{localIP}:{Global.sysAgentPort}";
+ if (config.listenerType == 2 || config.listenerType == 4)
+ {
+ if (PACServerHandle.IsRunning)
+ {
+ toolSslPacPort.Text = $"{HttpProxyHandle.GetPacUrl()}";
+ }
+ else
+ {
+ toolSslPacPort.Text = UIRes.I18N("StartPacFailed");
+ }
+ }
+ }
+ notifyMain.Icon = GetNotifyIcon();
+
+ }
+ private void ssMain_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
+ {
+ if (!Utils.IsNullOrEmpty(e.ClickedItem.Text))
+ {
+ Utils.SetClipboardData(e.ClickedItem.Text);
+ }
+ }
+
+ private Icon GetNotifyIcon()
+ {
+ try
+ {
+ var color = ColorTranslator.FromHtml("#3399CC");
+ var index = config.sysAgentEnabled ? config.listenerType : 0;
+ if (index > 0)
+ {
+ color = (new Color[] { Color.Red, Color.Purple, Color.DarkGreen, Color.Orange })[index - 1];
+ //color = ColorTranslator.FromHtml(new string[] { "#CC0066", "#CC6600", "#99CC99", "#666699" }[index - 1]);
+ }
+
+ var width = 128;
+ var height = 128;
+
+ var bitmap = new Bitmap(width, height);
+ var graphics = Graphics.FromImage(bitmap);
+ var drawBrush = new SolidBrush(color);
+
+ graphics.FillEllipse(drawBrush, new Rectangle(0, 0, width, height));
+ var zoom = 16;
+ graphics.DrawImage(new Bitmap(Properties.Resources.notify, width - zoom, width - zoom), zoom / 2, zoom / 2);
+
+ bitmap.Save(Utils.GetPath("temp_icon.ico"), System.Drawing.Imaging.ImageFormat.Icon);
+
+ Icon createdIcon = Icon.FromHandle(bitmap.GetHicon());
+
+ drawBrush.Dispose();
+ graphics.Dispose();
+ bitmap.Dispose();
+
+ return createdIcon;
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ return this.Icon;
+ }
+ }
+ #endregion
+
+ #region v2ray 操作
+
+ ///
+ /// 载入V2ray
+ ///
+ private void LoadV2ray()
+ {
+ if (Global.reloadV2ray)
+ {
+ ClearMsg();
+ }
+ v2rayHandler.LoadV2ray(config);
+ Global.reloadV2ray = false;
+ ConfigHandler.ToJsonFile(config);
+
+ ChangeSysAgent(config.sysAgentEnabled);
+ DisplayToolStatus();
+ }
+
+ ///
+ /// 关闭V2ray
+ ///
+ private void CloseV2ray()
+ {
+ ConfigHandler.ToJsonFile(config);
+
+ ChangeSysAgent(false);
+
+ v2rayHandler.V2rayStop();
+ }
+
+ #endregion
+
+ #region 功能按钮
+
+ private void lvServers_DoubleClick(object sender, EventArgs e)
+ {
+ int index = GetLvSelectedIndex();
+ if (index < 0)
+ {
+ return;
+ }
+
+ if (config.vmess[index].configType == (int)EConfigType.Vmess)
+ {
+ var fm = new AddServerForm();
+ fm.EditIndex = index;
+ if (fm.ShowDialog() == DialogResult.OK)
+ {
+ //刷新
+ RefreshServers();
+ LoadV2ray();
+ }
+ }
+ else if (config.vmess[index].configType == (int)EConfigType.Shadowsocks)
+ {
+ var fm = new AddServer3Form();
+ fm.EditIndex = index;
+ if (fm.ShowDialog() == DialogResult.OK)
+ {
+ RefreshServers();
+ LoadV2ray();
+ }
+ }
+ else if (config.vmess[index].configType == (int)EConfigType.Socks)
+ {
+ var fm = new AddServer4Form();
+ fm.EditIndex = index;
+ if (fm.ShowDialog() == DialogResult.OK)
+ {
+ RefreshServers();
+ LoadV2ray();
+ }
+ }
+ else
+ {
+ var fm2 = new AddServer2Form();
+ fm2.EditIndex = index;
+ if (fm2.ShowDialog() == DialogResult.OK)
+ {
+ //刷新
+ RefreshServers();
+ LoadV2ray();
+ }
+ }
+ }
+
+ private void lvServers_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Control)
+ {
+ switch (e.KeyCode)
+ {
+ case Keys.A:
+ menuSelectAll_Click(null, null);
+ break;
+ case Keys.P:
+ menuPingServer_Click(null, null);
+ break;
+ case Keys.O:
+ menuTcpingServer_Click(null, null);
+ break;
+ case Keys.R:
+ menuRealPingServer_Click(null, null);
+ break;
+ case Keys.T:
+ menuSpeedServer_Click(null, null);
+ break;
+ }
+ }
+ switch (e.KeyCode)
+ {
+ case Keys.Enter:
+ menuSetDefaultServer_Click(null, null);
+ break;
+ case Keys.Delete:
+ menuRemoveServer_Click(null, null);
+ break;
+ case Keys.U:
+ menuMoveUp_Click(null, null);
+ break;
+ case Keys.D:
+ menuMoveDown_Click(null, null);
+ break;
+ }
+ }
+
+ private void menuAddVmessServer_Click(object sender, EventArgs e)
+ {
+ AddServerForm fm = new AddServerForm();
+ fm.EditIndex = -1;
+ if (fm.ShowDialog() == DialogResult.OK)
+ {
+ //刷新
+ RefreshServers();
+ LoadV2ray();
+ }
+ }
+
+ private void menuRemoveServer_Click(object sender, EventArgs e)
+ {
+
+ int index = GetLvSelectedIndex();
+ if (index < 0)
+ {
+ return;
+ }
+ if (UI.ShowYesNo(UIRes.I18N("RemoveServer")) == DialogResult.No)
+ {
+ return;
+ }
+ for (int k = lvSelecteds.Count - 1; k >= 0; k--)
+ {
+ ConfigHandler.RemoveServer(ref config, lvSelecteds[k]);
+ }
+ //刷新
+ RefreshServers();
+ LoadV2ray();
+
+ }
+
+ private void menuRemoveDuplicateServer_Click(object sender, EventArgs e)
+ {
+ List servers = null;
+ Utils.DedupServerList(config.vmess, out servers);
+ if (servers != null)
+ {
+ config.vmess = servers;
+ }
+ //刷新
+ RefreshServers();
+ LoadV2ray();
+ }
+
+ private void menuCopyServer_Click(object sender, EventArgs e)
+ {
+ int index = GetLvSelectedIndex();
+ if (index < 0)
+ {
+ return;
+ }
+ if (ConfigHandler.CopyServer(ref config, index) == 0)
+ {
+ //刷新
+ RefreshServers();
+ }
+ }
+
+ private void menuSetDefaultServer_Click(object sender, EventArgs e)
+ {
+ int index = GetLvSelectedIndex();
+ if (index < 0)
+ {
+ return;
+ }
+ SetDefaultServer(index);
+ }
+
+
+ private void menuPingServer_Click(object sender, EventArgs e)
+ {
+ GetLvSelectedIndex();
+ ClearTestResult();
+ var statistics = new SpeedtestHandler(ref config, ref v2rayHandler, lvSelecteds, "ping", UpdateSpeedtestHandler);
+ }
+ private void menuTcpingServer_Click(object sender, EventArgs e)
+ {
+ GetLvSelectedIndex();
+ ClearTestResult();
+ var statistics = new SpeedtestHandler(ref config, ref v2rayHandler, lvSelecteds, "tcping", UpdateSpeedtestHandler);
+ }
+
+ private void menuRealPingServer_Click(object sender, EventArgs e)
+ {
+ if (!config.sysAgentEnabled || config.listenerType != 1)
+ {
+ UI.Show(UIRes.I18N("NeedHttpGlobalProxy"));
+ return;
+ }
+
+ UI.Show(UIRes.I18N("SpeedServerTips"));
+
+ GetLvSelectedIndex();
+ ClearTestResult();
+ var statistics = new SpeedtestHandler(ref config, ref v2rayHandler, lvSelecteds, "realping", UpdateSpeedtestHandler);
+ }
+
+ private void menuSpeedServer_Click(object sender, EventArgs e)
+ {
+ if (!config.sysAgentEnabled || config.listenerType != 1)
+ {
+ UI.Show(UIRes.I18N("NeedHttpGlobalProxy"));
+ return;
+ }
+
+ UI.Show(UIRes.I18N("SpeedServerTips"));
+
+ GetLvSelectedIndex();
+ var statistics = new SpeedtestHandler(ref config, ref v2rayHandler, lvSelecteds, "speedtest", UpdateSpeedtestHandler);
+ }
+
+ private void menuExport2ClientConfig_Click(object sender, EventArgs e)
+ {
+ int index = GetLvSelectedIndex();
+ if (index < 0)
+ {
+ return;
+ }
+ if (config.vmess[index].configType != (int)EConfigType.Vmess)
+ {
+ UI.Show(UIRes.I18N("NonVmessService"));
+ return;
+ }
+
+ SaveFileDialog fileDialog = new SaveFileDialog();
+ fileDialog.Filter = "Config|*.json";
+ fileDialog.FilterIndex = 2;
+ fileDialog.RestoreDirectory = true;
+ if (fileDialog.ShowDialog() != DialogResult.OK)
+ {
+ return;
+ }
+ string fileName = fileDialog.FileName;
+ if (Utils.IsNullOrEmpty(fileName))
+ {
+ return;
+ }
+ Config configCopy = Utils.DeepCopy(config);
+ configCopy.index = index;
+ string msg;
+ if (V2rayConfigHandler.Export2ClientConfig(configCopy, fileName, out msg) != 0)
+ {
+ UI.Show(msg);
+ }
+ else
+ {
+ UI.Show(string.Format(UIRes.I18N("SaveClientConfigurationIn"), fileName));
+ }
+ }
+
+ private void menuExport2ServerConfig_Click(object sender, EventArgs e)
+ {
+ int index = GetLvSelectedIndex();
+ if (index < 0)
+ {
+ return;
+ }
+ if (config.vmess[index].configType != (int)EConfigType.Vmess)
+ {
+ UI.Show(UIRes.I18N("NonVmessService"));
+ return;
+ }
+
+ SaveFileDialog fileDialog = new SaveFileDialog();
+ fileDialog.Filter = "Config|*.json";
+ fileDialog.FilterIndex = 2;
+ fileDialog.RestoreDirectory = true;
+ if (fileDialog.ShowDialog() != DialogResult.OK)
+ {
+ return;
+ }
+ string fileName = fileDialog.FileName;
+ if (Utils.IsNullOrEmpty(fileName))
+ {
+ return;
+ }
+ Config configCopy = Utils.DeepCopy(config);
+ configCopy.index = index;
+ string msg;
+ if (V2rayConfigHandler.Export2ServerConfig(configCopy, fileName, out msg) != 0)
+ {
+ UI.Show(msg);
+ }
+ else
+ {
+ UI.Show(string.Format(UIRes.I18N("SaveServerConfigurationIn"), fileName));
+ }
+ }
+
+ private void menuExport2ShareUrl_Click(object sender, EventArgs e)
+ {
+ GetLvSelectedIndex();
+
+ StringBuilder sb = new StringBuilder();
+ for (int k = 0; k < lvSelecteds.Count; k++)
+ {
+ string url = ConfigHandler.GetVmessQRCode(config, lvSelecteds[k]);
+ if (Utils.IsNullOrEmpty(url))
+ {
+ continue;
+ }
+ sb.Append(url);
+ sb.AppendLine();
+ }
+ if (sb.Length > 0)
+ {
+ Utils.SetClipboardData(sb.ToString());
+ UI.Show(UIRes.I18N("BatchExportURLSuccessfully"));
+ }
+ }
+
+ private void menuExport2SubContent_Click(object sender, EventArgs e)
+ {
+ GetLvSelectedIndex();
+
+ StringBuilder sb = new StringBuilder();
+ for (int k = 0; k < lvSelecteds.Count; k++)
+ {
+ string url = ConfigHandler.GetVmessQRCode(config, lvSelecteds[k]);
+ if (Utils.IsNullOrEmpty(url))
+ {
+ continue;
+ }
+ sb.Append(url);
+ sb.AppendLine();
+ }
+ if (sb.Length > 0)
+ {
+ Utils.SetClipboardData(Utils.Base64Encode(sb.ToString()));
+ UI.Show(UIRes.I18N("BatchExportSubscriptionSuccessfully"));
+ }
+ }
+
+ private void tsbOptionSetting_Click(object sender, EventArgs e)
+ {
+ OptionSettingForm fm = new OptionSettingForm();
+ if (fm.ShowDialog() == DialogResult.OK)
+ {
+ //刷新
+ RefreshServers();
+ LoadV2ray();
+ }
+ }
+
+ private void tsbReload_Click(object sender, EventArgs e)
+ {
+ Global.reloadV2ray = true;
+ LoadV2ray();
+ }
+
+ private void tsbClose_Click(object sender, EventArgs e)
+ {
+ HideForm();
+ //this.WindowState = FormWindowState.Minimized;
+ }
+
+ ///
+ /// 设置活动服务器
+ ///
+ ///
+ ///
+ private int SetDefaultServer(int index)
+ {
+ if (index < 0)
+ {
+ UI.Show(UIRes.I18N("PleaseSelectServer"));
+ return -1;
+ }
+ if (ConfigHandler.SetDefaultServer(ref config, index) == 0)
+ {
+ //刷新
+ RefreshServers();
+ LoadV2ray();
+ }
+ return 0;
+ }
+
+ ///
+ /// 取得ListView选中的行
+ ///
+ ///
+ private int GetLvSelectedIndex()
+ {
+ int index = -1;
+ lvSelecteds.Clear();
+ try
+ {
+ if (lvServers.SelectedIndices.Count <= 0)
+ {
+ UI.Show(UIRes.I18N("PleaseSelectServer"));
+ return index;
+ }
+
+ index = lvServers.SelectedIndices[0];
+ foreach (int i in lvServers.SelectedIndices)
+ {
+ lvSelecteds.Add(i);
+ }
+ return index;
+ }
+ catch
+ {
+ return index;
+ }
+ }
+
+ private void menuAddCustomServer_Click(object sender, EventArgs e)
+ {
+ UI.Show(UIRes.I18N("CustomServerTips"));
+
+ OpenFileDialog fileDialog = new OpenFileDialog();
+ fileDialog.Multiselect = false;
+ fileDialog.Filter = "Config|*.json|All|*.*";
+ if (fileDialog.ShowDialog() != DialogResult.OK)
+ {
+ return;
+ }
+ string fileName = fileDialog.FileName;
+ if (Utils.IsNullOrEmpty(fileName))
+ {
+ return;
+ }
+
+ if (ConfigHandler.AddCustomServer(ref config, fileName) == 0)
+ {
+ //刷新
+ RefreshServers();
+ LoadV2ray();
+ UI.Show(UIRes.I18N("SuccessfullyImportedCustomServer"));
+ }
+ else
+ {
+ UI.Show(UIRes.I18N("FailedImportedCustomServer"));
+ }
+ }
+
+ private void menuAddShadowsocksServer_Click(object sender, EventArgs e)
+ {
+ var fm = new AddServer3Form();
+ fm.EditIndex = -1;
+ if (fm.ShowDialog() == DialogResult.OK)
+ {
+ //刷新
+ RefreshServers();
+ LoadV2ray();
+ }
+ ShowForm();
+ }
+
+ private void menuAddSocksServer_Click(object sender, EventArgs e)
+ {
+ var fm = new AddServer4Form();
+ fm.EditIndex = -1;
+ if (fm.ShowDialog() == DialogResult.OK)
+ {
+ //刷新
+ RefreshServers();
+ LoadV2ray();
+ }
+ ShowForm();
+ }
+
+ private void menuAddServers_Click(object sender, EventArgs e)
+ {
+ string clipboardData = Utils.GetClipboardData();
+ if (AddBatchServers(clipboardData) == 0)
+ {
+ UI.Show(UIRes.I18N("SuccessfullyImportedServerViaClipboard"));
+ }
+ }
+
+ private void menuScanScreen_Click(object sender, EventArgs e)
+ {
+ HideForm();
+ bgwScan.RunWorkerAsync();
+ }
+
+ private int AddBatchServers(string clipboardData, string subid = "")
+ {
+ if (ConfigHandler.AddBatchServers(ref config, clipboardData, subid) != 0)
+ {
+ clipboardData = Utils.Base64Decode(clipboardData);
+ if (ConfigHandler.AddBatchServers(ref config, clipboardData, subid) != 0)
+ {
+ return -1;
+ }
+ }
+ RefreshServers();
+ return 0;
+ }
+
+ #endregion
+
+
+ #region 提示信息
+
+ ///
+ /// 消息委托
+ ///
+ ///
+ ///
+ void v2rayHandler_ProcessEvent(bool notify, string msg)
+ {
+ AppendText(notify, msg);
+ }
+
+ delegate void AppendTextDelegate(string text);
+ void AppendText(bool notify, string msg)
+ {
+ try
+ {
+ AppendText(msg);
+ if (notify)
+ {
+ notifyMsg(msg);
+ }
+ }
+ catch
+ {
+ }
+ }
+
+ void AppendText(string text)
+ {
+ if (this.txtMsgBox.InvokeRequired)
+ {
+ Invoke(new AppendTextDelegate(AppendText), new object[] { text });
+ }
+ else
+ {
+ //this.txtMsgBox.AppendText(text);
+ ShowMsg(text);
+ }
+ }
+
+ ///
+ /// 提示信息
+ ///
+ ///
+ private void ShowMsg(string msg)
+ {
+ if (txtMsgBox.Lines.Length > 500)
+ {
+ ClearMsg();
+ }
+ this.txtMsgBox.AppendText(msg);
+ if (!msg.EndsWith("\r\n"))
+ {
+ this.txtMsgBox.AppendText("\r\n");
+ }
+ }
+
+ ///
+ /// 清除信息
+ ///
+ private void ClearMsg()
+ {
+ this.txtMsgBox.Clear();
+ }
+
+ ///
+ /// 托盘信息
+ ///
+ ///
+ private void notifyMsg(string msg)
+ {
+ notifyMain.Text = msg;
+ }
+
+ #endregion
+
+
+ #region 托盘事件
+
+ private void notifyMain_MouseClick(object sender, MouseEventArgs e)
+ {
+ if (e.Button == System.Windows.Forms.MouseButtons.Left)
+ {
+ ShowForm();
+ }
+ }
+
+ private void menuExit_Click(object sender, EventArgs e)
+ {
+ CloseV2ray();
+
+ this.Visible = false;
+ this.Close();
+
+ statistics?.Close();
+
+ //this.Dispose();
+ //System.Environment.Exit(System.Environment.ExitCode);
+ Application.Exit();
+ }
+
+
+ private void ShowForm()
+ {
+ this.Show();
+ this.WindowState = FormWindowState.Normal;
+ this.Activate();
+ //this.notifyIcon1.Visible = false;
+ this.ShowInTaskbar = true;
+
+ SetVisibleCore(true);
+ }
+
+ private void HideForm()
+ {
+ //this.WindowState = FormWindowState.Minimized;
+ this.Hide();
+ //this.notifyMain.Icon = this.Icon;
+ this.notifyMain.Visible = true;
+ this.ShowInTaskbar = false;
+
+ SetVisibleCore(false);
+ }
+
+ #endregion
+
+ #region 后台测速
+
+ private void SetTestResult(int k, string txt)
+ {
+ config.vmess[k].testResult = txt;
+ lvServers.Items[k].SubItems[8].Text = txt;
+ }
+ private void ClearTestResult()
+ {
+ for (int k = 0; k < config.vmess.Count; k++)
+ {
+ SetTestResult(k, "");
+ }
+ }
+ private void UpdateSpeedtestHandler(int index, string msg)
+ {
+ lvServers.Invoke((MethodInvoker)delegate
+ {
+ lvServers.SuspendLayout();
+
+ SetTestResult(index, msg);
+
+ lvServers.ResumeLayout();
+ });
+ }
+
+ private void UpdateStatisticsHandler(ulong totalUp, ulong totalDown, ulong up, ulong down, List statistics)
+ {
+ try
+ {
+ up /= (ulong)(config.statisticsFreshRate / 1000f);
+ down /= (ulong)(config.statisticsFreshRate / 1000f);
+ toolSslServerSpeed.Text = string.Format(
+ "{0}/s↑ | {1}/s↓",
+ Utils.HumanFy(up),
+ Utils.HumanFy(down)
+ );
+
+ List datas = new List();
+ for (int i = 0; i < config.vmess.Count; i++)
+ {
+ string totalUp_ = string.Empty,
+ totalDown_ = string.Empty,
+ todayUp_ = string.Empty,
+ todayDown_ = string.Empty;
+ var index = statistics.FindIndex(item_ => Utils.IsIdenticalServer(item_, new ServerStatistics(config.vmess[i].remarks, config.vmess[i].address, config.vmess[i].port, config.vmess[i].path, config.vmess[i].requestHost, 0, 0, 0, 0)));
+ if (index != -1)
+ {
+ totalUp_ = Utils.HumanFy(statistics[index].totalUp);
+ totalDown_ = Utils.HumanFy(statistics[index].totalDown);
+ todayUp_ = Utils.HumanFy(statistics[index].todayUp);
+ todayDown_ = Utils.HumanFy(statistics[index].todayDown);
+ }
+
+ datas.Add(new string[] { totalUp_, totalDown_, todayUp_, todayDown_ });
+ }
+
+ lvServers.Invoke((MethodInvoker)delegate
+ {
+ lvServers.SuspendLayout();
+ for (int i = 0; i < datas.Count; i++)
+ {
+ var indexStart = 9;
+ lvServers.Items[i].SubItems[indexStart++].Text = datas[i][0];
+ lvServers.Items[i].SubItems[indexStart++].Text = datas[i][1];
+ lvServers.Items[i].SubItems[indexStart++].Text = datas[i][2];
+ lvServers.Items[i].SubItems[indexStart++].Text = datas[i][3];
+ }
+ lvServers.ResumeLayout();
+ });
+
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ #endregion
+
+ #region 移动服务器
+
+ private void menuMoveTop_Click(object sender, EventArgs e)
+ {
+ MoveServer(EMove.Top);
+ }
+
+ private void menuMoveUp_Click(object sender, EventArgs e)
+ {
+ MoveServer(EMove.Up);
+ }
+
+ private void menuMoveDown_Click(object sender, EventArgs e)
+ {
+ MoveServer(EMove.Down);
+ }
+
+ private void menuMoveBottom_Click(object sender, EventArgs e)
+ {
+ MoveServer(EMove.Bottom);
+ }
+
+ private void MoveServer(EMove eMove)
+ {
+ int index = GetLvSelectedIndex();
+ if (index < 0)
+ {
+ UI.Show(UIRes.I18N("PleaseSelectServer"));
+ return;
+ }
+ if (ConfigHandler.MoveServer(ref config, index, eMove) == 0)
+ {
+ //刷新
+ RefreshServers();
+ LoadV2ray();
+ }
+ }
+ private void menuSelectAll_Click(object sender, EventArgs e)
+ {
+ foreach (ListViewItem item in lvServers.Items)
+ {
+ item.Selected = true;
+ }
+ }
+
+ #endregion
+
+ #region 系统代理相关
+
+ private void menuCopyPACUrl_Click(object sender, EventArgs e)
+ {
+ Utils.SetClipboardData(HttpProxyHandle.GetPacUrl());
+ }
+
+ private void menuSysAgentEnabled_Click(object sender, EventArgs e)
+ {
+ bool isChecked = !config.sysAgentEnabled;
+ config.sysAgentEnabled = isChecked;
+ ChangeSysAgent(isChecked);
+ }
+
+ private void menuGlobal_Click(object sender, EventArgs e)
+ {
+ config.listenerType = 1;
+ ChangePACButtonStatus(config.listenerType);
+ }
+
+ private void menuGlobalPAC_Click(object sender, EventArgs e)
+ {
+ config.listenerType = 2;
+ ChangePACButtonStatus(config.listenerType);
+ }
+
+ private void menuKeep_Click(object sender, EventArgs e)
+ {
+ config.listenerType = 3;
+ ChangePACButtonStatus(config.listenerType);
+ }
+
+ private void menuKeepPAC_Click(object sender, EventArgs e)
+ {
+ config.listenerType = 4;
+ ChangePACButtonStatus(config.listenerType);
+ }
+
+ private void ChangePACButtonStatus(int type)
+ {
+ if (HttpProxyHandle.Update(config, false))
+ {
+ switch (type)
+ {
+ case 1:
+ menuGlobal.Checked = true;
+ menuGlobalPAC.Checked = false;
+ menuKeep.Checked = false;
+ menuKeepPAC.Checked = false;
+ break;
+ case 2:
+ menuGlobal.Checked = false;
+ menuGlobalPAC.Checked = true;
+ menuKeep.Checked = false;
+ menuKeepPAC.Checked = false;
+ break;
+ case 3:
+ menuGlobal.Checked = false;
+ menuGlobalPAC.Checked = false;
+ menuKeep.Checked = true;
+ menuKeepPAC.Checked = false;
+ break;
+ case 4:
+ menuGlobal.Checked = false;
+ menuGlobalPAC.Checked = false;
+ menuKeep.Checked = false;
+ menuKeepPAC.Checked = true;
+ break;
+ }
+ }
+ DisplayToolStatus();
+ }
+
+ ///
+ /// 改变系统代理
+ ///
+ ///
+ private void ChangeSysAgent(bool isChecked)
+ {
+ if (isChecked)
+ {
+ if (HttpProxyHandle.RestartHttpAgent(config, true))
+ {
+ ChangePACButtonStatus(config.listenerType);
+ }
+ }
+ else
+ {
+ HttpProxyHandle.Update(config, true);
+ HttpProxyHandle.CloseHttpAgent(config);
+ }
+
+ menuSysAgentEnabled.Checked =
+ menuSysAgentMode.Enabled = isChecked;
+
+ DisplayToolStatus();
+ }
+ #endregion
+
+
+ #region CheckUpdate
+
+ private void tsbCheckUpdateN_Click(object sender, EventArgs e)
+ {
+ System.Diagnostics.Process.Start(Global.UpdateUrl);
+ }
+
+ private void tsbCheckUpdateCore_Click(object sender, EventArgs e)
+ {
+ if (v2rayUpdateHandle == null)
+ {
+ v2rayUpdateHandle = new V2rayUpdateHandle();
+ v2rayUpdateHandle.AbsoluteCompleted += (sender2, args) =>
+ {
+ if (args.Success)
+ {
+ AppendText(false, UIRes.I18N("MsgParsingV2rayCoreSuccessfully"));
+
+ string url = args.Msg;
+ this.Invoke((MethodInvoker)(delegate
+ {
+
+ if (UI.ShowYesNo(string.Format(UIRes.I18N("DownloadYesNo"), url)) == DialogResult.No)
+ {
+ return;
+ }
+ else
+ {
+ v2rayUpdateHandle.DownloadFileAsync(config, url);
+ }
+ }));
+ }
+ else
+ {
+ AppendText(false, args.Msg);
+ }
+ };
+ v2rayUpdateHandle.UpdateCompleted += (sender2, args) =>
+ {
+ if (args.Success)
+ {
+ AppendText(false, UIRes.I18N("MsgDownloadV2rayCoreSuccessfully"));
+ AppendText(false, UIRes.I18N("MsgUnpacking"));
+
+ try
+ {
+ CloseV2ray();
+
+ string fileName = v2rayUpdateHandle.DownloadFileName;
+ fileName = Utils.GetPath(fileName);
+ using (ZipArchive archive = ZipFile.OpenRead(fileName))
+ {
+ foreach (ZipArchiveEntry entry in archive.Entries)
+ {
+ if (entry.Length == 0)
+ continue;
+ entry.ExtractToFile(Utils.GetPath(entry.Name), true);
+ }
+ }
+ AppendText(false, UIRes.I18N("MsgUpdateV2rayCoreSuccessfullyMore"));
+
+ Global.reloadV2ray = true;
+ LoadV2ray();
+
+ AppendText(false, UIRes.I18N("MsgUpdateV2rayCoreSuccessfully"));
+ }
+ catch (Exception ex)
+ {
+ AppendText(false, ex.Message);
+ }
+ }
+ else
+ {
+ AppendText(false, args.Msg);
+ }
+ };
+ v2rayUpdateHandle.Error += (sender2, args) =>
+ {
+ AppendText(true, args.GetException().Message);
+ };
+ }
+
+ AppendText(false, UIRes.I18N("MsgStartUpdatingV2rayCore"));
+ v2rayUpdateHandle.AbsoluteV2rayCore(config);
+ }
+
+ private void tsbCheckUpdatePACList_Click(object sender, EventArgs e)
+ {
+ if (pacListHandle == null)
+ {
+ pacListHandle = new PACListHandle();
+ pacListHandle.UpdateCompleted += (sender2, args) =>
+ {
+ if (args.Success)
+ {
+ AppendText(false, UIRes.I18N("MsgPACUpdateSuccessfully"));
+ }
+ else
+ {
+ AppendText(false, UIRes.I18N("MsgPACUpdateFailed"));
+ }
+ };
+ pacListHandle.Error += (sender2, args) =>
+ {
+ AppendText(true, args.GetException().Message);
+ };
+ }
+ AppendText(false, UIRes.I18N("MsgStartUpdatingPAC"));
+ pacListHandle.UpdatePACFromGFWList(config);
+ }
+
+ private void tsbCheckClearPACList_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ File.WriteAllText(Utils.GetPath(Global.pacFILE), Utils.GetEmbedText(Global.BlankPacFileName), Encoding.UTF8);
+ AppendText(false, UIRes.I18N("MsgSimplifyPAC"));
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+ #endregion
+
+ #region Help
+
+
+ private void tsbAbout_Click(object sender, EventArgs e)
+ {
+ System.Diagnostics.Process.Start(Global.AboutUrl);
+ }
+
+ private void tsbPromotion_Click(object sender, EventArgs e)
+ {
+ System.Diagnostics.Process.Start(Global.PromotionUrl);
+ }
+ #endregion
+
+ #region ScanScreen
+
+
+ private void bgwScan_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
+ {
+ string ret = Utils.ScanScreen();
+ bgwScan.ReportProgress(0, ret);
+ }
+
+ private void bgwScan_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
+ {
+ ShowForm();
+
+ string result = Convert.ToString(e.UserState);
+ if (Utils.IsNullOrEmpty(result))
+ {
+ UI.Show(UIRes.I18N("NoValidQRcodeFound"));
+ }
+ else
+ {
+ if (AddBatchServers(result) == 0)
+ {
+ UI.Show(UIRes.I18N("SuccessfullyImportedServerViaScan"));
+ }
+ }
+ }
+
+ #endregion
+
+ #region 订阅
+ private void tsbSubSetting_Click(object sender, EventArgs e)
+ {
+ SubSettingForm fm = new SubSettingForm();
+ if (fm.ShowDialog() == DialogResult.OK)
+ {
+ RefreshServers();
+ }
+ }
+
+ private void tsbSubUpdate_Click(object sender, EventArgs e)
+ {
+ AppendText(false, UIRes.I18N("MsgUpdateSubscriptionStart"));
+
+ if (config.subItem == null || config.subItem.Count <= 0)
+ {
+ AppendText(false, UIRes.I18N("MsgNoValidSubscription"));
+ return;
+ }
+
+ for (int k = 1; k <= config.subItem.Count; k++)
+ {
+ string id = config.subItem[k - 1].id.TrimEx();
+ string url = config.subItem[k - 1].url.TrimEx();
+ string hashCode = $"{k}->";
+ if (config.subItem[k - 1].enabled == false)
+ {
+ continue;
+ }
+ if (Utils.IsNullOrEmpty(id) || Utils.IsNullOrEmpty(url))
+ {
+ AppendText(false, $"{hashCode}{UIRes.I18N("MsgNoValidSubscription")}");
+ continue;
+ }
+
+ V2rayUpdateHandle v2rayUpdateHandle3 = new V2rayUpdateHandle();
+ v2rayUpdateHandle3.UpdateCompleted += (sender2, args) =>
+ {
+ if (args.Success)
+ {
+ AppendText(false, $"{hashCode}{UIRes.I18N("MsgGetSubscriptionSuccessfully")}");
+ var result = Utils.Base64Decode(args.Msg);
+ if (Utils.IsNullOrEmpty(result))
+ {
+ AppendText(false, $"{hashCode}{UIRes.I18N("MsgSubscriptionDecodingFailed")}");
+ return;
+ }
+
+ ConfigHandler.RemoveServerViaSubid(ref config, id);
+ AppendText(false, $"{hashCode}{UIRes.I18N("MsgClearSubscription")}");
+ RefreshServers();
+ if (AddBatchServers(result, id) == 0)
+ {
+ }
+ else
+ {
+ AppendText(false, $"{hashCode}{UIRes.I18N("MsgFailedImportSubscription")}");
+ }
+ AppendText(false, $"{hashCode}{UIRes.I18N("MsgUpdateSubscriptionEnd")}");
+ }
+ else
+ {
+ AppendText(false, args.Msg);
+ }
+ };
+ v2rayUpdateHandle3.Error += (sender2, args) =>
+ {
+ AppendText(true, args.GetException().Message);
+ };
+
+ v2rayUpdateHandle3.WebDownloadString(url);
+ AppendText(false, $"{hashCode}{UIRes.I18N("MsgStartGettingSubscriptions")}");
+ }
+
+
+ }
+
+ #endregion
+
+ #region Language
+
+ private void tsbLanguageDef_Click(object sender, EventArgs e)
+ {
+ SetCurrentLanguage("en");
+ }
+
+ private void tsbLanguageZhHans_Click(object sender, EventArgs e)
+ {
+ SetCurrentLanguage("zh-Hans");
+ }
+ private void SetCurrentLanguage(string value)
+ {
+ Utils.RegWriteValue(Global.MyRegPath, Global.MyRegKeyLanguage, value);
+ }
+
+
+ #endregion
+
+
+ }
+}
diff --git a/v2rayN/v2rayN/Forms/MainForm.resx b/v2rayN/v2rayN/Forms/MainForm.resx
new file mode 100644
index 00000000..bfd73a86
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/MainForm.resx
@@ -0,0 +1,1409 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+ Fill
+
+
+
+ 3, 17
+
+
+ 327, 17
+
+
+ 447, 22
+
+
+ Add [VMess] server
+
+
+ 447, 22
+
+
+ Add [Shadowsocks] server
+
+
+ 447, 22
+
+
+ Add [Socks] server
+
+
+ 447, 22
+
+
+ Add a custom configuration server
+
+
+ 447, 22
+
+
+ Import bulk URL from clipboard
+
+
+ 447, 22
+
+
+ Scan QR code on the screen
+
+
+ 444, 6
+
+
+ 447, 22
+
+
+ Remove selected server (multiple choice) (Delete)
+
+
+ 447, 22
+
+
+ Remove duplicate server
+
+
+ 447, 22
+
+
+ Copy selected server
+
+
+ 447, 22
+
+
+ Set as active server (Enter)
+
+
+ 444, 6
+
+
+ 447, 22
+
+
+ Up to top
+
+
+ 447, 22
+
+
+ Upward (U)
+
+
+ 447, 22
+
+
+ Down (D)
+
+
+ 447, 22
+
+
+ Moves down to the bottom
+
+
+ 447, 22
+
+
+ Select All (Ctrl+A)
+
+
+ 444, 6
+
+
+ 447, 22
+
+
+ Test server ping (multiple choice)(Ctrl+P)
+
+
+ 447, 22
+
+
+ Test server tcping (multiple choice)(Ctrl+O)
+
+
+ 447, 22
+
+
+ Test server real ping (multiple choice)(Ctrl+R)
+
+
+ 447, 22
+
+
+ Test server speed (multiple choice)(Ctrl+T)
+
+
+ 444, 6
+
+
+ 447, 22
+
+
+ Export selected server for client configuration
+
+
+ 447, 22
+
+
+ Export selected server for server configuration
+
+
+ 447, 22
+
+
+ Batch export share URL to clipboard (multiple choice)
+
+
+ 447, 22
+
+
+ Batch export subscription content to clipboard (multiple choice)
+
+
+ Magenta
+
+
+ 64, 53
+
+
+ Servers
+
+
+ ImageAboveText
+
+
+ 448, 556
+
+
+ cmsLv
+
+
+ System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Fill
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
+ LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkMAwAAAFFTeXN0
+ ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2Vu
+ PWIwM2Y1ZjdmMTFkNTBhM2EFAQAAACFTeXN0ZW0uV2luZG93cy5Gb3Jtcy5MaXN0Vmlld0l0ZW0HAAAA
+ BFRleHQKSW1hZ2VJbmRleAlCYWNrQ29sb3IHQ2hlY2tlZARGb250CUZvcmVDb2xvchdVc2VJdGVtU3R5
+ bGVGb3JTdWJJdGVtcwEABAAEBAAIFFN5c3RlbS5EcmF3aW5nLkNvbG9yAwAAAAETU3lzdGVtLkRyYXdp
+ bmcuRm9udAMAAAAUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAAQIAAAAGBAAAAAD/////Bfv///8UU3lz
+ dGVtLkRyYXdpbmcuQ29sb3IEAAAABG5hbWUFdmFsdWUKa25vd25Db2xvcgVzdGF0ZQEAAAAJBwcDAAAA
+ CgAAAAAAAAAAGAABAAAJBgAAAAH5////+////woAAAAAAAAAABoAAQABBQYAAAATU3lzdGVtLkRyYXdp
+ bmcuRm9udAQAAAAETmFtZQRTaXplBVN0eWxlBFVuaXQBAAQECxhTeXN0ZW0uRHJhd2luZy5Gb250U3R5
+ bGUDAAAAG1N5c3RlbS5EcmF3aW5nLkdyYXBoaWNzVW5pdAMAAAADAAAABggAAAAG5a6L5L2TAAAQQQX3
+ ////GFN5c3RlbS5EcmF3aW5nLkZvbnRTdHlsZQEAAAAHdmFsdWVfXwAIAwAAAAAAAAAF9v///xtTeXN0
+ ZW0uRHJhd2luZy5HcmFwaGljc1VuaXQBAAAAB3ZhbHVlX18ACAMAAAADAAAACw==
+
+
+
+ 0, 0
+
+
+ 686, 331
+
+
+
+ 1
+
+
+ lvServers
+
+
+ v2rayN.Forms.ListViewFlickerFree, v2rayN, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
+
+
+ splitContainer1.Panel1
+
+
+ 0
+
+
+ splitContainer1.Panel1
+
+
+ System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ splitContainer1
+
+
+ 0
+
+
+ Fill
+
+
+ 0, 0
+
+
+ 256, 331
+
+
+ 0
+
+
+ qrCodeControl
+
+
+ v2rayN.Forms.QRCodeControl, v2rayN, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
+
+
+ splitContainer1.Panel2
+
+
+ 0
+
+
+ splitContainer1.Panel2
+
+
+ System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ splitContainer1
+
+
+ 1
+
+
+ 100
+
+
+ 946, 331
+
+
+ 686
+
+
+ 2
+
+
+ splitContainer1
+
+
+ System.Windows.Forms.SplitContainer, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 0
+
+
+ 17, 17
+
+
+ 137, 17
+
+
+ NoControl
+
+
+ 264, 22
+
+
+ Enable Http proxy
+
+
+ 547, 22
+
+
+ Open Http proxy and automatically configure proxy server (global mode)
+
+
+ 547, 22
+
+
+ Open PAC and automatically configure PAC (PAC mode)
+
+
+ 547, 22
+
+
+ Only open Http proxy, do not automatically configure proxy server (direct mode)
+
+
+ 547, 22
+
+
+ Only open PAC, do not automatically configure PAC
+
+
+ 264, 22
+
+
+ Http proxy mode
+
+
+ 264, 22
+
+
+ Server
+
+
+ 264, 22
+
+
+ Import bulk URL from clipboard
+
+
+ 264, 22
+
+
+ Scan QR code on the screen
+
+
+ 264, 22
+
+
+ Copy local PAC URL
+
+
+ 261, 6
+
+
+ 264, 22
+
+
+ Exit
+
+
+ 265, 164
+
+
+ cmsMain
+
+
+ System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ v2rayN
+
+
+ True
+
+
+ 498, 17
+
+
+ Fill
+
+
+ 0, 66
+
+
+ 952, 351
+
+
+ 2
+
+
+ Server list
+
+
+ groupBox1
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 2
+
+
+ Fill
+
+
+ 3, 17
+
+
+ 0
+
+
+ True
+
+
+ Vertical
+
+
+ 946, 134
+
+
+ 2
+
+
+ txtMsgBox
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 0
+
+
+ 228, 18
+
+
+ 微软雅黑, 8pt
+
+
+ 49, 17
+
+
+ SOCKS5
+
+
+ 0, 17
+
+
+ 微软雅黑, 8pt
+
+
+ 198, 17
+
+
+ 微软雅黑, 8pt
+
+
+ 36, 17
+
+
+ HTTP
+
+
+ 0, 17
+
+
+ 微软雅黑, 8pt
+
+
+ 198, 17
+
+
+ 微软雅黑, 8pt
+
+
+ 30, 17
+
+
+ PAC
+
+
+ 0, 17
+
+
+ 微软雅黑, 8pt
+
+
+ 198, 17
+
+
+ False
+
+
+ 微软雅黑, 8pt
+
+
+ No
+
+
+ 220, 17
+
+
+ SPEED Disabled
+
+
+ MiddleRight
+
+
+ 0, 17
+
+
+ 3, 151
+
+
+ 946, 22
+
+
+ 7
+
+
+ statusStrip1
+
+
+ ssMain
+
+
+ System.Windows.Forms.StatusStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 1
+
+
+ Bottom
+
+
+ 0, 417
+
+
+ 952, 176
+
+
+ 4
+
+
+ Information
+
+
+ groupBox2
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 3
+
+
+ Top
+
+
+ 0, 56
+
+
+ 952, 10
+
+
+ 5
+
+
+ panel1
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 4
+
+
+ 409, 17
+
+
+ 6, 56
+
+
+ 197, 22
+
+
+ Subscription settings
+
+
+ 197, 22
+
+
+ Update subscription
+
+
+ Magenta
+
+
+ 93, 53
+
+
+ Subscription
+
+
+ ImageAboveText
+
+
+ 6, 56
+
+
+ Magenta
+
+
+ 52, 53
+
+
+ Setting
+
+
+ ImageAboveText
+
+
+ 6, 56
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAE3SURBVFhH7ZaBDQIhDEVvBEdwBDfQDXQER3AD3cARdAPd
+ QDfSDbQvuSb1AicFjJrwkxcN0FIolOuamv5VE2E+gLaPayWchEcE+hhTXVPhIoQmDcFYbKpoJtwEdX4X
+ jgIrXfTwnzb6dBw22BaJVdjJmWQs1/SdBRtE0U5cBXW2oSFRO0HtSEeW2FZ1wsq9sjuRdTDVAXnNuWLY
+ 6JnAl0sYa/Q5q1dhq35ci+Bkq2HJvbZpxGeybAAuw4Fq+cnW1wPITgHFYxvBUw+qHEIL1yq1vDKhVlH3
+ NQwF4JkcFRWiUAB7IVW2FFPO3YqlgPd+LJf02e8Fdi3rMdIAcLDuf9UpeT0IS0G/hvhPm305vSl7EQFY
+ B6zCvozvYGzRM8zEoeg5TPZwDaGvpHQni1yzSxbXPW9q+hF13ROHuJnQcjbhtQAAAABJRU5ErkJggg==
+
+
+
+ BottomCenter
+
+
+ Magenta
+
+
+ 97, 53
+
+
+ Restart service
+
+
+ ImageAboveText
+
+
+ 6, 56
+
+
+ 338, 22
+
+
+ Check for updates to v2rayN
+
+
+ 338, 22
+
+
+ Check for updates to v2rayCore
+
+
+ 338, 22
+
+
+ Check for updated PAC (requires Http proxy)
+
+
+ 338, 22
+
+
+ Simplify PAC (please set Core route)
+
+
+ Magenta
+
+
+ 128, 53
+
+
+ Check for updates
+
+
+ ImageAboveText
+
+
+ 6, 56
+
+
+ 187, 22
+
+
+ About
+
+
+ 184, 6
+
+
+ 187, 22
+
+
+ Language-[English]
+
+
+ 187, 22
+
+
+ 语言-[中文简体]
+
+
+ Magenta
+
+
+ 48, 53
+
+
+ Help
+
+
+ ImageAboveText
+
+
+ Magenta
+
+
+ 89, 53
+
+
+ Promotion
+
+
+ ImageAboveText
+
+
+ 6, 56
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVFhH7c6xDQAgCEVBRnVTHU2ZABuMxV3yOvJDAAA/
+ GqfZVG6X8mg1dfUAAPBQxAZd0SJruVXHWwAAAABJRU5ErkJggg==
+
+
+
+ Magenta
+
+
+ 52, 53
+
+
+ Close
+
+
+ ImageAboveText
+
+
+ 0, 0
+
+
+ 952, 56
+
+
+ 6
+
+
+ tsMain
+
+
+ System.Windows.Forms.ToolStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 5
+
+
+ True
+
+
+ 65
+
+
+ 6, 12
+
+
+ 952, 593
+
+
+ 4, 4, 4, 4
+
+
+ v2rayN
+
+
+ menuAddVmessServer
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuAddShadowsocksServer
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuAddSocksServer
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuAddCustomServer
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuAddServers
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuScanScreen
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripSeparator1
+
+
+ System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuRemoveServer
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuRemoveDuplicateServer
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuCopyServer
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuSetDefaultServer
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripSeparator3
+
+
+ System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuMoveTop
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuMoveUp
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuMoveDown
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuMoveBottom
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuSelectAll
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripSeparator9
+
+
+ System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuPingServer
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuTcpingServer
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuRealPingServer
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuSpeedServer
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripSeparator6
+
+
+ System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuExport2ClientConfig
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuExport2ServerConfig
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuExport2ShareUrl
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuExport2SubContent
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbServer
+
+
+ System.Windows.Forms.ToolStripDropDownButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ notifyMain
+
+
+ System.Windows.Forms.NotifyIcon, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuSysAgentEnabled
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuSysAgentMode
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuGlobal
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuGlobalPAC
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuKeep
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuKeepPAC
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuServers
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuAddServers2
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuScanScreen2
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuCopyPACUrl
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripSeparator2
+
+
+ System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ menuExit
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ bgwScan
+
+
+ System.ComponentModel.BackgroundWorker, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolSslSocksPortLab
+
+
+ System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolSslSocksPort
+
+
+ System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolSslBlank1
+
+
+ System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolSslHttpPortLab
+
+
+ System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolSslHttpPort
+
+
+ System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolSslBlank2
+
+
+ System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolSslPacPortLab
+
+
+ System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolSslPacPort
+
+
+ System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolSslBlank3
+
+
+ System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolSslServerSpeed
+
+
+ System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolSslBlank4
+
+
+ System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripSeparator4
+
+
+ System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbSub
+
+
+ System.Windows.Forms.ToolStripDropDownButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbSubSetting
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbSubUpdate
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripSeparator8
+
+
+ System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbOptionSetting
+
+
+ System.Windows.Forms.ToolStripButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripSeparator5
+
+
+ System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbReload
+
+
+ System.Windows.Forms.ToolStripButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripSeparator7
+
+
+ System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbCheckUpdate
+
+
+ System.Windows.Forms.ToolStripDropDownButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbCheckUpdateN
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbCheckUpdateCore
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbCheckUpdatePACList
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbCheckClearPACList
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripSeparator10
+
+
+ System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbHelp
+
+
+ System.Windows.Forms.ToolStripDropDownButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbAbout
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripSeparator12
+
+
+ System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbLanguageDef
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbLanguageZhHans
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbPromotion
+
+
+ System.Windows.Forms.ToolStripButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ toolStripSeparator11
+
+
+ System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tsbClose
+
+
+ System.Windows.Forms.ToolStripButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ MainForm
+
+
+ v2rayN.Forms.BaseForm, v2rayN, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/MainForm.zh-Hans.resx b/v2rayN/v2rayN/Forms/MainForm.zh-Hans.resx
new file mode 100644
index 00000000..abb6629f
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/MainForm.zh-Hans.resx
@@ -0,0 +1,474 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+ 278, 22
+
+
+ 添加[VMess]服务器
+
+
+ 278, 22
+
+
+ 添加[Shadowsocks]服务器
+
+
+ 278, 22
+
+
+ 添加[Socks]服务器
+
+
+ 278, 22
+
+
+ 添加自定义配置服务器
+
+
+ 278, 22
+
+
+ 从剪贴板导入批量URL
+
+
+ 278, 22
+
+
+ 扫描屏幕上的二维码
+
+
+ 275, 6
+
+
+ 278, 22
+
+
+ 移除所选服务器(多选) (Delete)
+
+
+ 278, 22
+
+
+ 移除重复的服务器
+
+
+ 278, 22
+
+
+ 复制所选服务器
+
+
+ 278, 22
+
+
+ 设为活动服务器 (Enter)
+
+
+ 275, 6
+
+
+ 278, 22
+
+
+ 上移至顶
+
+
+ 278, 22
+
+
+ 上移 (U)
+
+
+ 278, 22
+
+
+ 下移 (D)
+
+
+ 278, 22
+
+
+ 下移至底
+
+
+ 278, 22
+
+
+ 全选 (Ctrl+A)
+
+
+ 275, 6
+
+
+ 278, 22
+
+
+ 测试服务器延迟Ping(多选)(Ctrl+P)
+
+
+ 278, 22
+
+
+ 测试服务器延迟Tcping(多选)(Ctrl+O)
+
+
+ 278, 22
+
+
+ 测试服务器真连接延迟(多选)(Ctrl+R)
+
+
+ 278, 22
+
+
+ 测试服务器速度(多选)(Ctrl+T)
+
+
+ 275, 6
+
+
+ 278, 22
+
+
+ 导出所选服务器为客户端配置
+
+
+ 278, 22
+
+
+ 导出所选服务器为服务端配置
+
+
+ 278, 22
+
+
+ 批量导出分享URL至剪贴板(多选)
+
+
+ 278, 22
+
+
+ 批量导出订阅内容至剪贴板(多选)
+
+
+ 279, 534
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
+ LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkMAwAAAFFTeXN0
+ ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2Vu
+ PWIwM2Y1ZjdmMTFkNTBhM2EFAQAAACFTeXN0ZW0uV2luZG93cy5Gb3Jtcy5MaXN0Vmlld0l0ZW0HAAAA
+ BFRleHQKSW1hZ2VJbmRleAlCYWNrQ29sb3IHQ2hlY2tlZARGb250CUZvcmVDb2xvchdVc2VJdGVtU3R5
+ bGVGb3JTdWJJdGVtcwEABAAEBAAIFFN5c3RlbS5EcmF3aW5nLkNvbG9yAwAAAAETU3lzdGVtLkRyYXdp
+ bmcuRm9udAMAAAAUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAAQIAAAAGBAAAAAD/////Bfv///8UU3lz
+ dGVtLkRyYXdpbmcuQ29sb3IEAAAABG5hbWUFdmFsdWUKa25vd25Db2xvcgVzdGF0ZQEAAAAJBwcDAAAA
+ CgAAAAAAAAAAGAABAAAJBgAAAAH5////+////woAAAAAAAAAABoAAQABBQYAAAATU3lzdGVtLkRyYXdp
+ bmcuRm9udAQAAAAETmFtZQRTaXplBVN0eWxlBFVuaXQBAAQECxhTeXN0ZW0uRHJhd2luZy5Gb250U3R5
+ bGUDAAAAG1N5c3RlbS5EcmF3aW5nLkdyYXBoaWNzVW5pdAMAAAADAAAABggAAAAG5a6L5L2TAAAQQQX3
+ ////GFN5c3RlbS5EcmF3aW5nLkZvbnRTdHlsZQEAAAAHdmFsdWVfXwAIAwAAAAAAAAAF9v///xtTeXN0
+ ZW0uRHJhd2luZy5HcmFwaGljc1VuaXQBAAAAB3ZhbHVlX18ACAMAAAADAAAACw==
+
+
+
+ 73, 53
+
+
+ 服务器
+
+
+ 196, 164
+
+
+ 195, 22
+
+
+ 启用Http代理
+
+
+ 195, 22
+
+
+ Http代理模式
+
+
+ 340, 22
+
+
+ 开启Http代理,并自动配置代理服务器(全局模式)
+
+
+ 340, 22
+
+
+ 开启PAC,并自动配置PAC(PAC模式)
+
+
+ 340, 22
+
+
+ 仅开启Http代理,不自动配置代理服务器(直连模式)
+
+
+ 340, 22
+
+
+ 仅开启PAC,不自动配置PAC
+
+
+ 195, 22
+
+
+ 服务器
+
+
+ 195, 22
+
+
+ 从剪贴板导入批量URL
+
+
+ 195, 22
+
+
+ 扫描屏幕上的二维码
+
+
+ 195, 22
+
+
+ 复制本地PAC网址
+
+
+ 192, 6
+
+
+ 195, 22
+
+
+ 退出
+
+
+ 服务器列表
+
+
+ 信息
+
+
+ 网速显示未启用
+
+
+ 61, 53
+
+
+ 订阅
+
+
+ 124, 22
+
+
+ 订阅设置
+
+
+ 124, 22
+
+
+ 更新订阅
+
+
+ 76, 53
+
+
+ 参数设置
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAE3SURBVFhH7ZaBDQIhDEVvBEdwBDfQDXQER3AD3cARdAPd
+ QDfSDbQvuSb1AicFjJrwkxcN0FIolOuamv5VE2E+gLaPayWchEcE+hhTXVPhIoQmDcFYbKpoJtwEdX4X
+ jgIrXfTwnzb6dBw22BaJVdjJmWQs1/SdBRtE0U5cBXW2oSFRO0HtSEeW2FZ1wsq9sjuRdTDVAXnNuWLY
+ 6JnAl0sYa/Q5q1dhq35ci+Bkq2HJvbZpxGeybAAuw4Fq+cnW1wPITgHFYxvBUw+qHEIL1yq1vDKhVlH3
+ NQwF4JkcFRWiUAB7IVW2FFPO3YqlgPd+LJf02e8Fdi3rMdIAcLDuf9UpeT0IS0G/hvhPm305vSl7EQFY
+ B6zCvozvYGzRM8zEoeg5TPZwDaGvpHQni1yzSxbXPW9q+hF13ROHuJnQcjbhtQAAAABJRU5ErkJggg==
+
+
+
+ 76, 53
+
+
+ 重启服务
+
+
+ 85, 53
+
+
+ 检查更新
+
+
+ 232, 22
+
+
+ 检查更新v2rayN
+
+
+ 232, 22
+
+
+ 检查更新v2rayCore
+
+
+ 232, 22
+
+
+ 检查更新PAC (需要Http代理)
+
+
+ 232, 22
+
+
+ 简化PAC (请设置Core路由)
+
+
+ 69, 53
+
+
+ 帮助
+
+
+ 关于
+
+
+ 68, 53
+
+
+ 推广
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVFhH7c6xDQAgCEVBRnVTHU2ZABuMxV3yOvJDAAA/
+ GqfZVG6X8mg1dfUAAPBQxAZd0SJruVXHWwAAAABJRU5ErkJggg==
+
+
+
+ 关闭
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/OptionSettingForm.Designer.cs b/v2rayN/v2rayN/Forms/OptionSettingForm.Designer.cs
new file mode 100644
index 00000000..d44d446a
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/OptionSettingForm.Designer.cs
@@ -0,0 +1,675 @@
+namespace v2rayN.Forms
+{
+ partial class OptionSettingForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OptionSettingForm));
+ this.btnClose = new System.Windows.Forms.Button();
+ this.tabControl1 = new System.Windows.Forms.TabControl();
+ this.tabPage1 = new System.Windows.Forms.TabPage();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.chksniffingEnabled2 = new System.Windows.Forms.CheckBox();
+ this.chksniffingEnabled = new System.Windows.Forms.CheckBox();
+ this.txtremoteDNS = new System.Windows.Forms.TextBox();
+ this.label14 = new System.Windows.Forms.Label();
+ this.chkmuxEnabled = new System.Windows.Forms.CheckBox();
+ this.chkAllowIn2 = new System.Windows.Forms.CheckBox();
+ this.chkudpEnabled2 = new System.Windows.Forms.CheckBox();
+ this.cmbprotocol2 = new System.Windows.Forms.ComboBox();
+ this.label3 = new System.Windows.Forms.Label();
+ this.txtlocalPort2 = new System.Windows.Forms.TextBox();
+ this.cmbprotocol = new System.Windows.Forms.ComboBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.chkudpEnabled = new System.Windows.Forms.CheckBox();
+ this.chklogEnabled = new System.Windows.Forms.CheckBox();
+ this.cmbloglevel = new System.Windows.Forms.ComboBox();
+ this.label5 = new System.Windows.Forms.Label();
+ this.txtlocalPort = new System.Windows.Forms.TextBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.tabPage2 = new System.Windows.Forms.TabPage();
+ this.groupBox2 = new System.Windows.Forms.GroupBox();
+ this.tabControl2 = new System.Windows.Forms.TabControl();
+ this.tabPage3 = new System.Windows.Forms.TabPage();
+ this.txtUseragent = new System.Windows.Forms.TextBox();
+ this.tabPage4 = new System.Windows.Forms.TabPage();
+ this.txtUserdirect = new System.Windows.Forms.TextBox();
+ this.tabPage5 = new System.Windows.Forms.TabPage();
+ this.txtUserblock = new System.Windows.Forms.TextBox();
+ this.panel3 = new System.Windows.Forms.Panel();
+ this.btnSetDefRountingRule = new System.Windows.Forms.Button();
+ this.cmbdomainStrategy = new System.Windows.Forms.ComboBox();
+ this.labRoutingTips = new System.Windows.Forms.Label();
+ this.label15 = new System.Windows.Forms.Label();
+ this.label12 = new System.Windows.Forms.Label();
+ this.cmbroutingMode = new System.Windows.Forms.ComboBox();
+ this.tabPage6 = new System.Windows.Forms.TabPage();
+ this.chkKcpcongestion = new System.Windows.Forms.CheckBox();
+ this.txtKcpwriteBufferSize = new System.Windows.Forms.TextBox();
+ this.label10 = new System.Windows.Forms.Label();
+ this.txtKcpreadBufferSize = new System.Windows.Forms.TextBox();
+ this.label11 = new System.Windows.Forms.Label();
+ this.txtKcpdownlinkCapacity = new System.Windows.Forms.TextBox();
+ this.label8 = new System.Windows.Forms.Label();
+ this.txtKcpuplinkCapacity = new System.Windows.Forms.TextBox();
+ this.label9 = new System.Windows.Forms.Label();
+ this.txtKcptti = new System.Windows.Forms.TextBox();
+ this.label7 = new System.Windows.Forms.Label();
+ this.txtKcpmtu = new System.Windows.Forms.TextBox();
+ this.label6 = new System.Windows.Forms.Label();
+ this.tabPage7 = new System.Windows.Forms.TabPage();
+ this.cbFreshrate = new System.Windows.Forms.ComboBox();
+ this.tbCacheDays = new System.Windows.Forms.TextBox();
+ this.lbFreshrate = new System.Windows.Forms.Label();
+ this.lbCacheDays = new System.Windows.Forms.Label();
+ this.chkEnableStatistics = new System.Windows.Forms.CheckBox();
+ this.chkAllowLANConn = new System.Windows.Forms.CheckBox();
+ this.txturlGFWList = new System.Windows.Forms.TextBox();
+ this.label13 = new System.Windows.Forms.Label();
+ this.chkAutoRun = new System.Windows.Forms.CheckBox();
+ this.panel2 = new System.Windows.Forms.Panel();
+ this.btnOK = new System.Windows.Forms.Button();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.configBindingSource = new System.Windows.Forms.BindingSource(this.components);
+ this.tabControl1.SuspendLayout();
+ this.tabPage1.SuspendLayout();
+ this.groupBox1.SuspendLayout();
+ this.tabPage2.SuspendLayout();
+ this.groupBox2.SuspendLayout();
+ this.tabControl2.SuspendLayout();
+ this.tabPage3.SuspendLayout();
+ this.tabPage4.SuspendLayout();
+ this.tabPage5.SuspendLayout();
+ this.panel3.SuspendLayout();
+ this.tabPage6.SuspendLayout();
+ this.tabPage7.SuspendLayout();
+ this.panel2.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.configBindingSource)).BeginInit();
+ this.SuspendLayout();
+ //
+ // btnClose
+ //
+ this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ resources.ApplyResources(this.btnClose, "btnClose");
+ this.btnClose.Name = "btnClose";
+ this.btnClose.UseVisualStyleBackColor = true;
+ this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
+ //
+ // tabControl1
+ //
+ this.tabControl1.Controls.Add(this.tabPage1);
+ this.tabControl1.Controls.Add(this.tabPage2);
+ this.tabControl1.Controls.Add(this.tabPage6);
+ this.tabControl1.Controls.Add(this.tabPage7);
+ resources.ApplyResources(this.tabControl1, "tabControl1");
+ this.tabControl1.Name = "tabControl1";
+ this.tabControl1.SelectedIndex = 0;
+ //
+ // tabPage1
+ //
+ this.tabPage1.Controls.Add(this.groupBox1);
+ resources.ApplyResources(this.tabPage1, "tabPage1");
+ this.tabPage1.Name = "tabPage1";
+ this.tabPage1.UseVisualStyleBackColor = true;
+ //
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.chksniffingEnabled2);
+ this.groupBox1.Controls.Add(this.chksniffingEnabled);
+ this.groupBox1.Controls.Add(this.txtremoteDNS);
+ this.groupBox1.Controls.Add(this.label14);
+ this.groupBox1.Controls.Add(this.chkmuxEnabled);
+ this.groupBox1.Controls.Add(this.chkAllowIn2);
+ this.groupBox1.Controls.Add(this.chkudpEnabled2);
+ this.groupBox1.Controls.Add(this.cmbprotocol2);
+ this.groupBox1.Controls.Add(this.label3);
+ this.groupBox1.Controls.Add(this.txtlocalPort2);
+ this.groupBox1.Controls.Add(this.cmbprotocol);
+ this.groupBox1.Controls.Add(this.label1);
+ this.groupBox1.Controls.Add(this.chkudpEnabled);
+ this.groupBox1.Controls.Add(this.chklogEnabled);
+ this.groupBox1.Controls.Add(this.cmbloglevel);
+ this.groupBox1.Controls.Add(this.label5);
+ this.groupBox1.Controls.Add(this.txtlocalPort);
+ this.groupBox1.Controls.Add(this.label2);
+ resources.ApplyResources(this.groupBox1, "groupBox1");
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.TabStop = false;
+ //
+ // chksniffingEnabled2
+ //
+ resources.ApplyResources(this.chksniffingEnabled2, "chksniffingEnabled2");
+ this.chksniffingEnabled2.Name = "chksniffingEnabled2";
+ this.chksniffingEnabled2.UseVisualStyleBackColor = true;
+ //
+ // chksniffingEnabled
+ //
+ resources.ApplyResources(this.chksniffingEnabled, "chksniffingEnabled");
+ this.chksniffingEnabled.Name = "chksniffingEnabled";
+ this.chksniffingEnabled.UseVisualStyleBackColor = true;
+ //
+ // txtremoteDNS
+ //
+ resources.ApplyResources(this.txtremoteDNS, "txtremoteDNS");
+ this.txtremoteDNS.Name = "txtremoteDNS";
+ //
+ // label14
+ //
+ resources.ApplyResources(this.label14, "label14");
+ this.label14.Name = "label14";
+ //
+ // chkmuxEnabled
+ //
+ resources.ApplyResources(this.chkmuxEnabled, "chkmuxEnabled");
+ this.chkmuxEnabled.Name = "chkmuxEnabled";
+ this.chkmuxEnabled.UseVisualStyleBackColor = true;
+ //
+ // chkAllowIn2
+ //
+ resources.ApplyResources(this.chkAllowIn2, "chkAllowIn2");
+ this.chkAllowIn2.Name = "chkAllowIn2";
+ this.chkAllowIn2.UseVisualStyleBackColor = true;
+ this.chkAllowIn2.CheckedChanged += new System.EventHandler(this.chkAllowIn2_CheckedChanged);
+ //
+ // chkudpEnabled2
+ //
+ resources.ApplyResources(this.chkudpEnabled2, "chkudpEnabled2");
+ this.chkudpEnabled2.Name = "chkudpEnabled2";
+ this.chkudpEnabled2.UseVisualStyleBackColor = true;
+ //
+ // cmbprotocol2
+ //
+ this.cmbprotocol2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cmbprotocol2.FormattingEnabled = true;
+ this.cmbprotocol2.Items.AddRange(new object[] {
+ resources.GetString("cmbprotocol2.Items"),
+ resources.GetString("cmbprotocol2.Items1")});
+ resources.ApplyResources(this.cmbprotocol2, "cmbprotocol2");
+ this.cmbprotocol2.Name = "cmbprotocol2";
+ //
+ // label3
+ //
+ resources.ApplyResources(this.label3, "label3");
+ this.label3.Name = "label3";
+ //
+ // txtlocalPort2
+ //
+ resources.ApplyResources(this.txtlocalPort2, "txtlocalPort2");
+ this.txtlocalPort2.Name = "txtlocalPort2";
+ //
+ // cmbprotocol
+ //
+ this.cmbprotocol.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ resources.ApplyResources(this.cmbprotocol, "cmbprotocol");
+ this.cmbprotocol.FormattingEnabled = true;
+ this.cmbprotocol.Items.AddRange(new object[] {
+ resources.GetString("cmbprotocol.Items"),
+ resources.GetString("cmbprotocol.Items1")});
+ this.cmbprotocol.Name = "cmbprotocol";
+ //
+ // label1
+ //
+ resources.ApplyResources(this.label1, "label1");
+ this.label1.Name = "label1";
+ //
+ // chkudpEnabled
+ //
+ resources.ApplyResources(this.chkudpEnabled, "chkudpEnabled");
+ this.chkudpEnabled.Name = "chkudpEnabled";
+ this.chkudpEnabled.UseVisualStyleBackColor = true;
+ //
+ // chklogEnabled
+ //
+ resources.ApplyResources(this.chklogEnabled, "chklogEnabled");
+ this.chklogEnabled.Name = "chklogEnabled";
+ this.chklogEnabled.UseVisualStyleBackColor = true;
+ //
+ // cmbloglevel
+ //
+ this.cmbloglevel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cmbloglevel.FormattingEnabled = true;
+ this.cmbloglevel.Items.AddRange(new object[] {
+ resources.GetString("cmbloglevel.Items"),
+ resources.GetString("cmbloglevel.Items1"),
+ resources.GetString("cmbloglevel.Items2"),
+ resources.GetString("cmbloglevel.Items3"),
+ resources.GetString("cmbloglevel.Items4")});
+ resources.ApplyResources(this.cmbloglevel, "cmbloglevel");
+ this.cmbloglevel.Name = "cmbloglevel";
+ //
+ // label5
+ //
+ resources.ApplyResources(this.label5, "label5");
+ this.label5.Name = "label5";
+ //
+ // txtlocalPort
+ //
+ resources.ApplyResources(this.txtlocalPort, "txtlocalPort");
+ this.txtlocalPort.Name = "txtlocalPort";
+ //
+ // label2
+ //
+ resources.ApplyResources(this.label2, "label2");
+ this.label2.Name = "label2";
+ //
+ // tabPage2
+ //
+ this.tabPage2.Controls.Add(this.groupBox2);
+ resources.ApplyResources(this.tabPage2, "tabPage2");
+ this.tabPage2.Name = "tabPage2";
+ this.tabPage2.UseVisualStyleBackColor = true;
+ //
+ // groupBox2
+ //
+ this.groupBox2.Controls.Add(this.tabControl2);
+ this.groupBox2.Controls.Add(this.panel3);
+ resources.ApplyResources(this.groupBox2, "groupBox2");
+ this.groupBox2.Name = "groupBox2";
+ this.groupBox2.TabStop = false;
+ //
+ // tabControl2
+ //
+ this.tabControl2.Controls.Add(this.tabPage3);
+ this.tabControl2.Controls.Add(this.tabPage4);
+ this.tabControl2.Controls.Add(this.tabPage5);
+ resources.ApplyResources(this.tabControl2, "tabControl2");
+ this.tabControl2.Name = "tabControl2";
+ this.tabControl2.SelectedIndex = 0;
+ //
+ // tabPage3
+ //
+ this.tabPage3.Controls.Add(this.txtUseragent);
+ resources.ApplyResources(this.tabPage3, "tabPage3");
+ this.tabPage3.Name = "tabPage3";
+ this.tabPage3.UseVisualStyleBackColor = true;
+ //
+ // txtUseragent
+ //
+ resources.ApplyResources(this.txtUseragent, "txtUseragent");
+ this.txtUseragent.Name = "txtUseragent";
+ //
+ // tabPage4
+ //
+ this.tabPage4.Controls.Add(this.txtUserdirect);
+ resources.ApplyResources(this.tabPage4, "tabPage4");
+ this.tabPage4.Name = "tabPage4";
+ this.tabPage4.UseVisualStyleBackColor = true;
+ //
+ // txtUserdirect
+ //
+ resources.ApplyResources(this.txtUserdirect, "txtUserdirect");
+ this.txtUserdirect.Name = "txtUserdirect";
+ //
+ // tabPage5
+ //
+ this.tabPage5.Controls.Add(this.txtUserblock);
+ resources.ApplyResources(this.tabPage5, "tabPage5");
+ this.tabPage5.Name = "tabPage5";
+ this.tabPage5.UseVisualStyleBackColor = true;
+ //
+ // txtUserblock
+ //
+ resources.ApplyResources(this.txtUserblock, "txtUserblock");
+ this.txtUserblock.Name = "txtUserblock";
+ //
+ // panel3
+ //
+ this.panel3.Controls.Add(this.btnSetDefRountingRule);
+ this.panel3.Controls.Add(this.cmbdomainStrategy);
+ this.panel3.Controls.Add(this.labRoutingTips);
+ this.panel3.Controls.Add(this.label15);
+ this.panel3.Controls.Add(this.label12);
+ this.panel3.Controls.Add(this.cmbroutingMode);
+ resources.ApplyResources(this.panel3, "panel3");
+ this.panel3.Name = "panel3";
+ //
+ // btnSetDefRountingRule
+ //
+ resources.ApplyResources(this.btnSetDefRountingRule, "btnSetDefRountingRule");
+ this.btnSetDefRountingRule.Name = "btnSetDefRountingRule";
+ this.btnSetDefRountingRule.UseVisualStyleBackColor = true;
+ this.btnSetDefRountingRule.Click += new System.EventHandler(this.btnSetDefRountingRule_Click);
+ //
+ // cmbdomainStrategy
+ //
+ this.cmbdomainStrategy.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cmbdomainStrategy.FormattingEnabled = true;
+ this.cmbdomainStrategy.Items.AddRange(new object[] {
+ resources.GetString("cmbdomainStrategy.Items"),
+ resources.GetString("cmbdomainStrategy.Items1"),
+ resources.GetString("cmbdomainStrategy.Items2")});
+ resources.ApplyResources(this.cmbdomainStrategy, "cmbdomainStrategy");
+ this.cmbdomainStrategy.Name = "cmbdomainStrategy";
+ //
+ // labRoutingTips
+ //
+ this.labRoutingTips.ForeColor = System.Drawing.Color.Brown;
+ resources.ApplyResources(this.labRoutingTips, "labRoutingTips");
+ this.labRoutingTips.Name = "labRoutingTips";
+ //
+ // label15
+ //
+ resources.ApplyResources(this.label15, "label15");
+ this.label15.Name = "label15";
+ //
+ // label12
+ //
+ resources.ApplyResources(this.label12, "label12");
+ this.label12.Name = "label12";
+ //
+ // cmbroutingMode
+ //
+ this.cmbroutingMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cmbroutingMode.FormattingEnabled = true;
+ this.cmbroutingMode.Items.AddRange(new object[] {
+ resources.GetString("cmbroutingMode.Items"),
+ resources.GetString("cmbroutingMode.Items1"),
+ resources.GetString("cmbroutingMode.Items2"),
+ resources.GetString("cmbroutingMode.Items3")});
+ resources.ApplyResources(this.cmbroutingMode, "cmbroutingMode");
+ this.cmbroutingMode.Name = "cmbroutingMode";
+ //
+ // tabPage6
+ //
+ this.tabPage6.Controls.Add(this.chkKcpcongestion);
+ this.tabPage6.Controls.Add(this.txtKcpwriteBufferSize);
+ this.tabPage6.Controls.Add(this.label10);
+ this.tabPage6.Controls.Add(this.txtKcpreadBufferSize);
+ this.tabPage6.Controls.Add(this.label11);
+ this.tabPage6.Controls.Add(this.txtKcpdownlinkCapacity);
+ this.tabPage6.Controls.Add(this.label8);
+ this.tabPage6.Controls.Add(this.txtKcpuplinkCapacity);
+ this.tabPage6.Controls.Add(this.label9);
+ this.tabPage6.Controls.Add(this.txtKcptti);
+ this.tabPage6.Controls.Add(this.label7);
+ this.tabPage6.Controls.Add(this.txtKcpmtu);
+ this.tabPage6.Controls.Add(this.label6);
+ resources.ApplyResources(this.tabPage6, "tabPage6");
+ this.tabPage6.Name = "tabPage6";
+ this.tabPage6.UseVisualStyleBackColor = true;
+ //
+ // chkKcpcongestion
+ //
+ resources.ApplyResources(this.chkKcpcongestion, "chkKcpcongestion");
+ this.chkKcpcongestion.Name = "chkKcpcongestion";
+ this.chkKcpcongestion.UseVisualStyleBackColor = true;
+ //
+ // txtKcpwriteBufferSize
+ //
+ resources.ApplyResources(this.txtKcpwriteBufferSize, "txtKcpwriteBufferSize");
+ this.txtKcpwriteBufferSize.Name = "txtKcpwriteBufferSize";
+ //
+ // label10
+ //
+ resources.ApplyResources(this.label10, "label10");
+ this.label10.Name = "label10";
+ //
+ // txtKcpreadBufferSize
+ //
+ resources.ApplyResources(this.txtKcpreadBufferSize, "txtKcpreadBufferSize");
+ this.txtKcpreadBufferSize.Name = "txtKcpreadBufferSize";
+ //
+ // label11
+ //
+ resources.ApplyResources(this.label11, "label11");
+ this.label11.Name = "label11";
+ //
+ // txtKcpdownlinkCapacity
+ //
+ resources.ApplyResources(this.txtKcpdownlinkCapacity, "txtKcpdownlinkCapacity");
+ this.txtKcpdownlinkCapacity.Name = "txtKcpdownlinkCapacity";
+ //
+ // label8
+ //
+ resources.ApplyResources(this.label8, "label8");
+ this.label8.Name = "label8";
+ //
+ // txtKcpuplinkCapacity
+ //
+ resources.ApplyResources(this.txtKcpuplinkCapacity, "txtKcpuplinkCapacity");
+ this.txtKcpuplinkCapacity.Name = "txtKcpuplinkCapacity";
+ //
+ // label9
+ //
+ resources.ApplyResources(this.label9, "label9");
+ this.label9.Name = "label9";
+ //
+ // txtKcptti
+ //
+ resources.ApplyResources(this.txtKcptti, "txtKcptti");
+ this.txtKcptti.Name = "txtKcptti";
+ //
+ // label7
+ //
+ resources.ApplyResources(this.label7, "label7");
+ this.label7.Name = "label7";
+ //
+ // txtKcpmtu
+ //
+ resources.ApplyResources(this.txtKcpmtu, "txtKcpmtu");
+ this.txtKcpmtu.Name = "txtKcpmtu";
+ //
+ // label6
+ //
+ resources.ApplyResources(this.label6, "label6");
+ this.label6.Name = "label6";
+ //
+ // tabPage7
+ //
+ this.tabPage7.Controls.Add(this.cbFreshrate);
+ this.tabPage7.Controls.Add(this.tbCacheDays);
+ this.tabPage7.Controls.Add(this.lbFreshrate);
+ this.tabPage7.Controls.Add(this.lbCacheDays);
+ this.tabPage7.Controls.Add(this.chkEnableStatistics);
+ this.tabPage7.Controls.Add(this.chkAllowLANConn);
+ this.tabPage7.Controls.Add(this.txturlGFWList);
+ this.tabPage7.Controls.Add(this.label13);
+ this.tabPage7.Controls.Add(this.chkAutoRun);
+ resources.ApplyResources(this.tabPage7, "tabPage7");
+ this.tabPage7.Name = "tabPage7";
+ this.tabPage7.UseVisualStyleBackColor = true;
+ //
+ // cbFreshrate
+ //
+ this.cbFreshrate.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cbFreshrate.FormattingEnabled = true;
+ resources.ApplyResources(this.cbFreshrate, "cbFreshrate");
+ this.cbFreshrate.Name = "cbFreshrate";
+ //
+ // tbCacheDays
+ //
+ resources.ApplyResources(this.tbCacheDays, "tbCacheDays");
+ this.tbCacheDays.Name = "tbCacheDays";
+ //
+ // lbFreshrate
+ //
+ resources.ApplyResources(this.lbFreshrate, "lbFreshrate");
+ this.lbFreshrate.Name = "lbFreshrate";
+ //
+ // lbCacheDays
+ //
+ resources.ApplyResources(this.lbCacheDays, "lbCacheDays");
+ this.lbCacheDays.Name = "lbCacheDays";
+ //
+ // chkEnableStatistics
+ //
+ resources.ApplyResources(this.chkEnableStatistics, "chkEnableStatistics");
+ this.chkEnableStatistics.Name = "chkEnableStatistics";
+ this.chkEnableStatistics.UseVisualStyleBackColor = true;
+ //
+ // chkAllowLANConn
+ //
+ resources.ApplyResources(this.chkAllowLANConn, "chkAllowLANConn");
+ this.chkAllowLANConn.Name = "chkAllowLANConn";
+ this.chkAllowLANConn.UseVisualStyleBackColor = true;
+ //
+ // txturlGFWList
+ //
+ resources.ApplyResources(this.txturlGFWList, "txturlGFWList");
+ this.txturlGFWList.Name = "txturlGFWList";
+ //
+ // label13
+ //
+ resources.ApplyResources(this.label13, "label13");
+ this.label13.Name = "label13";
+ //
+ // chkAutoRun
+ //
+ resources.ApplyResources(this.chkAutoRun, "chkAutoRun");
+ this.chkAutoRun.Name = "chkAutoRun";
+ this.chkAutoRun.UseVisualStyleBackColor = true;
+ //
+ // panel2
+ //
+ this.panel2.Controls.Add(this.btnClose);
+ this.panel2.Controls.Add(this.btnOK);
+ resources.ApplyResources(this.panel2, "panel2");
+ this.panel2.Name = "panel2";
+ //
+ // btnOK
+ //
+ resources.ApplyResources(this.btnOK, "btnOK");
+ this.btnOK.Name = "btnOK";
+ this.btnOK.UseVisualStyleBackColor = true;
+ this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
+ //
+ // panel1
+ //
+ resources.ApplyResources(this.panel1, "panel1");
+ this.panel1.Name = "panel1";
+ //
+ // configBindingSource
+ //
+ this.configBindingSource.DataSource = typeof(v2rayN.Mode.Config);
+ //
+ // OptionSettingForm
+ //
+ resources.ApplyResources(this, "$this");
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.btnClose;
+ this.Controls.Add(this.tabControl1);
+ this.Controls.Add(this.panel2);
+ this.Controls.Add(this.panel1);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.Name = "OptionSettingForm";
+ this.Load += new System.EventHandler(this.OptionSettingForm_Load);
+ this.tabControl1.ResumeLayout(false);
+ this.tabPage1.ResumeLayout(false);
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.tabPage2.ResumeLayout(false);
+ this.groupBox2.ResumeLayout(false);
+ this.tabControl2.ResumeLayout(false);
+ this.tabPage3.ResumeLayout(false);
+ this.tabPage3.PerformLayout();
+ this.tabPage4.ResumeLayout(false);
+ this.tabPage4.PerformLayout();
+ this.tabPage5.ResumeLayout(false);
+ this.tabPage5.PerformLayout();
+ this.panel3.ResumeLayout(false);
+ this.panel3.PerformLayout();
+ this.tabPage6.ResumeLayout(false);
+ this.tabPage6.PerformLayout();
+ this.tabPage7.ResumeLayout(false);
+ this.tabPage7.PerformLayout();
+ this.panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.configBindingSource)).EndInit();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button btnClose;
+ private System.Windows.Forms.Button btnOK;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.ComboBox cmbloglevel;
+ private System.Windows.Forms.Label label5;
+ private System.Windows.Forms.TextBox txtlocalPort;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.CheckBox chklogEnabled;
+ private System.Windows.Forms.CheckBox chkudpEnabled;
+ private System.Windows.Forms.Panel panel1;
+ private System.Windows.Forms.TabControl tabControl1;
+ private System.Windows.Forms.TabPage tabPage1;
+ private System.Windows.Forms.TabPage tabPage2;
+ private System.Windows.Forms.Panel panel2;
+ private System.Windows.Forms.GroupBox groupBox2;
+ private System.Windows.Forms.ComboBox cmbprotocol;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.ComboBox cmbprotocol2;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.TextBox txtlocalPort2;
+ private System.Windows.Forms.CheckBox chkudpEnabled2;
+ private System.Windows.Forms.CheckBox chkAllowIn2;
+ private System.Windows.Forms.CheckBox chkmuxEnabled;
+ private System.Windows.Forms.TabControl tabControl2;
+ private System.Windows.Forms.TabPage tabPage3;
+ private System.Windows.Forms.TabPage tabPage4;
+ private System.Windows.Forms.Label labRoutingTips;
+ private System.Windows.Forms.TextBox txtUseragent;
+ private System.Windows.Forms.TabPage tabPage5;
+ private System.Windows.Forms.TextBox txtUserdirect;
+ private System.Windows.Forms.TextBox txtUserblock;
+ private System.Windows.Forms.TabPage tabPage6;
+ private System.Windows.Forms.TextBox txtKcpmtu;
+ private System.Windows.Forms.Label label6;
+ private System.Windows.Forms.TextBox txtKcptti;
+ private System.Windows.Forms.Label label7;
+ private System.Windows.Forms.TextBox txtKcpwriteBufferSize;
+ private System.Windows.Forms.Label label10;
+ private System.Windows.Forms.TextBox txtKcpreadBufferSize;
+ private System.Windows.Forms.Label label11;
+ private System.Windows.Forms.TextBox txtKcpdownlinkCapacity;
+ private System.Windows.Forms.Label label8;
+ private System.Windows.Forms.TextBox txtKcpuplinkCapacity;
+ private System.Windows.Forms.Label label9;
+ private System.Windows.Forms.CheckBox chkKcpcongestion;
+ private System.Windows.Forms.TabPage tabPage7;
+ private System.Windows.Forms.CheckBox chkAutoRun;
+ private System.Windows.Forms.Label label13;
+ private System.Windows.Forms.TextBox txturlGFWList;
+ private System.Windows.Forms.CheckBox chkAllowLANConn;
+ private System.Windows.Forms.TextBox txtremoteDNS;
+ private System.Windows.Forms.Label label14;
+ private System.Windows.Forms.Panel panel3;
+ private System.Windows.Forms.ComboBox cmbdomainStrategy;
+ private System.Windows.Forms.Label label15;
+ private System.Windows.Forms.Label label12;
+ private System.Windows.Forms.ComboBox cmbroutingMode;
+ private System.Windows.Forms.CheckBox chksniffingEnabled;
+ private System.Windows.Forms.CheckBox chksniffingEnabled2;
+ private System.Windows.Forms.Button btnSetDefRountingRule;
+ private System.Windows.Forms.CheckBox chkEnableStatistics;
+ private System.Windows.Forms.TextBox tbCacheDays;
+ private System.Windows.Forms.Label lbCacheDays;
+ private System.Windows.Forms.ComboBox cbFreshrate;
+ private System.Windows.Forms.Label lbFreshrate;
+ private System.Windows.Forms.BindingSource configBindingSource;
+ }
+}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/OptionSettingForm.cs b/v2rayN/v2rayN/Forms/OptionSettingForm.cs
new file mode 100644
index 00000000..afd11944
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/OptionSettingForm.cs
@@ -0,0 +1,416 @@
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+using v2rayN.Handler;
+
+namespace v2rayN.Forms
+{
+ public partial class OptionSettingForm : BaseForm
+ {
+ public OptionSettingForm()
+ {
+ InitializeComponent();
+ }
+
+ private void OptionSettingForm_Load(object sender, EventArgs e)
+ {
+ InitBase();
+
+ InitRouting();
+
+ InitKCP();
+
+ InitGUI();
+ }
+
+ ///
+ /// 初始化基础设置
+ ///
+ private void InitBase()
+ {
+ //日志
+ chklogEnabled.Checked = config.logEnabled;
+ cmbloglevel.Text = config.loglevel;
+
+ //Mux
+ chkmuxEnabled.Checked = config.muxEnabled;
+
+ //本地监听
+ if (config.inbound.Count > 0)
+ {
+ txtlocalPort.Text = config.inbound[0].localPort.ToString();
+ cmbprotocol.Text = config.inbound[0].protocol.ToString();
+ chkudpEnabled.Checked = config.inbound[0].udpEnabled;
+ chksniffingEnabled.Checked = config.inbound[0].sniffingEnabled;
+ if (config.inbound.Count > 1)
+ {
+ txtlocalPort2.Text = config.inbound[1].localPort.ToString();
+ cmbprotocol2.Text = config.inbound[1].protocol.ToString();
+ chkudpEnabled2.Checked = config.inbound[1].udpEnabled;
+ chksniffingEnabled2.Checked = config.inbound[1].sniffingEnabled;
+ chkAllowIn2.Checked = true;
+ }
+ else
+ {
+ chkAllowIn2.Checked = false;
+ }
+ chkAllowIn2State();
+ }
+
+ //remoteDNS
+ txtremoteDNS.Text = config.remoteDNS;
+ }
+
+ ///
+ /// 初始化路由设置
+ ///
+ private void InitRouting()
+ {
+ //路由
+ cmbdomainStrategy.Text = config.domainStrategy;
+ int routingMode = 0;
+ int.TryParse(config.routingMode, out routingMode);
+ cmbroutingMode.SelectedIndex = routingMode;
+
+ txtUseragent.Text = Utils.List2String(config.useragent, true);
+ txtUserdirect.Text = Utils.List2String(config.userdirect, true);
+ txtUserblock.Text = Utils.List2String(config.userblock, true);
+ }
+
+ ///
+ /// 初始化KCP设置
+ ///
+ private void InitKCP()
+ {
+ txtKcpmtu.Text = config.kcpItem.mtu.ToString();
+ txtKcptti.Text = config.kcpItem.tti.ToString();
+ txtKcpuplinkCapacity.Text = config.kcpItem.uplinkCapacity.ToString();
+ txtKcpdownlinkCapacity.Text = config.kcpItem.downlinkCapacity.ToString();
+ txtKcpreadBufferSize.Text = config.kcpItem.readBufferSize.ToString();
+ txtKcpwriteBufferSize.Text = config.kcpItem.writeBufferSize.ToString();
+ chkKcpcongestion.Checked = config.kcpItem.congestion;
+ }
+
+ ///
+ /// 初始化v2rayN GUI设置
+ ///
+ private void InitGUI()
+ {
+ //开机自动启动
+ chkAutoRun.Checked = Utils.IsAutoRun();
+
+ //自定义GFWList
+ txturlGFWList.Text = config.urlGFWList;
+
+ chkAllowLANConn.Checked = config.allowLANConn;
+
+
+ var enableStatistics = config.enableStatistics;
+ chkEnableStatistics.Checked = enableStatistics;
+
+ tbCacheDays.Text = config.CacheDays.ToString();
+
+
+ var cbSource = new ComboItem[]
+ {
+ new ComboItem{ID = (int)Global.StatisticsFreshRate.quick, Text = UIRes.I18N("QuickFresh")},
+ new ComboItem{ID = (int)Global.StatisticsFreshRate.medium, Text = UIRes.I18N("MediumFresh")},
+ new ComboItem{ID = (int)Global.StatisticsFreshRate.slow, Text = UIRes.I18N("SlowFresh")},
+ };
+ cbFreshrate.DataSource = cbSource;
+
+ cbFreshrate.DisplayMember = "Text";
+ cbFreshrate.ValueMember = "ID";
+
+ switch(config.statisticsFreshRate)
+ {
+ case (int)Global.StatisticsFreshRate.quick:
+ cbFreshrate.SelectedItem = cbSource[0];
+ break;
+ case (int)Global.StatisticsFreshRate.medium:
+ cbFreshrate.SelectedItem = cbSource[1];
+ break;
+ case (int)Global.StatisticsFreshRate.slow:
+ cbFreshrate.SelectedItem = cbSource[2];
+ break;
+ }
+
+ }
+
+ private void btnOK_Click(object sender, EventArgs e)
+ {
+ if (SaveBase() != 0)
+ {
+ return;
+ }
+
+ if (SaveRouting() != 0)
+ {
+ return;
+ }
+
+ if (SaveKCP() != 0)
+ {
+ return;
+ }
+
+ if (SaveGUI() != 0)
+ {
+ return;
+ }
+
+ if (ConfigHandler.SaveConfig(ref config) == 0)
+ {
+ this.DialogResult = DialogResult.OK;
+ }
+ else
+ {
+ UI.Show(UIRes.I18N("OperationFailed"));
+ }
+ }
+
+ ///
+ /// 保存基础设置
+ ///
+ ///
+ private int SaveBase()
+ {
+ //日志
+ bool logEnabled = chklogEnabled.Checked;
+ string loglevel = cmbloglevel.Text.TrimEx();
+
+ //Mux
+ bool muxEnabled = chkmuxEnabled.Checked;
+
+ //本地监听
+ string localPort = txtlocalPort.Text.TrimEx();
+ string protocol = cmbprotocol.Text.TrimEx();
+ bool udpEnabled = chkudpEnabled.Checked;
+ bool sniffingEnabled = chksniffingEnabled.Checked;
+ if (Utils.IsNullOrEmpty(localPort) || !Utils.IsNumberic(localPort))
+ {
+ UI.Show(UIRes.I18N("FillLocalListeningPort"));
+ return -1;
+ }
+ if (Utils.IsNullOrEmpty(protocol))
+ {
+ UI.Show(UIRes.I18N("PleaseSelectProtocol"));
+ return -1;
+ }
+ config.inbound[0].localPort = Utils.ToInt(localPort);
+ config.inbound[0].protocol = protocol;
+ config.inbound[0].udpEnabled = udpEnabled;
+ config.inbound[0].sniffingEnabled = sniffingEnabled;
+
+ //本地监听2
+ string localPort2 = txtlocalPort2.Text.TrimEx();
+ string protocol2 = cmbprotocol2.Text.TrimEx();
+ bool udpEnabled2 = chkudpEnabled2.Checked;
+ bool sniffingEnabled2 = chksniffingEnabled2.Checked;
+ if (chkAllowIn2.Checked)
+ {
+ if (Utils.IsNullOrEmpty(localPort2) || !Utils.IsNumberic(localPort2))
+ {
+ UI.Show(UIRes.I18N("FillLocalListeningPort"));
+ return -1;
+ }
+ if (Utils.IsNullOrEmpty(protocol2))
+ {
+ UI.Show(UIRes.I18N("PleaseSelectProtocol"));
+ return -1;
+ }
+ if (config.inbound.Count < 2)
+ {
+ config.inbound.Add(new Mode.InItem());
+ }
+ config.inbound[1].localPort = Utils.ToInt(localPort2);
+ config.inbound[1].protocol = protocol2;
+ config.inbound[1].udpEnabled = udpEnabled2;
+ config.inbound[1].sniffingEnabled = sniffingEnabled2;
+ }
+ else
+ {
+ if (config.inbound.Count > 1)
+ {
+ config.inbound.RemoveAt(1);
+ }
+ }
+
+ //日志
+ config.logEnabled = logEnabled;
+ config.loglevel = loglevel;
+
+ //Mux
+ config.muxEnabled = muxEnabled;
+
+ //remoteDNS
+ config.remoteDNS = txtremoteDNS.Text.TrimEx();
+
+ return 0;
+ }
+
+ ///
+ /// 保存路由设置
+ ///
+ ///
+ private int SaveRouting()
+ {
+ //路由
+ string domainStrategy = cmbdomainStrategy.Text;
+ string routingMode = cmbroutingMode.SelectedIndex.ToString();
+
+ string useragent = txtUseragent.Text.TrimEx();
+ string userdirect = txtUserdirect.Text.TrimEx();
+ string userblock = txtUserblock.Text.TrimEx();
+
+ config.domainStrategy = domainStrategy;
+ config.routingMode = routingMode;
+
+ config.useragent = Utils.String2List(useragent);
+ config.userdirect = Utils.String2List(userdirect);
+ config.userblock = Utils.String2List(userblock);
+
+ return 0;
+ }
+
+ ///
+ /// 保存KCP设置
+ ///
+ ///
+ private int SaveKCP()
+ {
+ string mtu = txtKcpmtu.Text.TrimEx();
+ string tti = txtKcptti.Text.TrimEx();
+ string uplinkCapacity = txtKcpuplinkCapacity.Text.TrimEx();
+ string downlinkCapacity = txtKcpdownlinkCapacity.Text.TrimEx();
+ string readBufferSize = txtKcpreadBufferSize.Text.TrimEx();
+ string writeBufferSize = txtKcpwriteBufferSize.Text.TrimEx();
+ bool congestion = chkKcpcongestion.Checked;
+
+ if (Utils.IsNullOrEmpty(mtu) || !Utils.IsNumberic(mtu)
+ || Utils.IsNullOrEmpty(tti) || !Utils.IsNumberic(tti)
+ || Utils.IsNullOrEmpty(uplinkCapacity) || !Utils.IsNumberic(uplinkCapacity)
+ || Utils.IsNullOrEmpty(downlinkCapacity) || !Utils.IsNumberic(downlinkCapacity)
+ || Utils.IsNullOrEmpty(readBufferSize) || !Utils.IsNumberic(readBufferSize)
+ || Utils.IsNullOrEmpty(writeBufferSize) || !Utils.IsNumberic(writeBufferSize))
+ {
+ UI.Show(UIRes.I18N("FillKcpParameters"));
+ return -1;
+ }
+ config.kcpItem.mtu = Utils.ToInt(mtu);
+ config.kcpItem.tti = Utils.ToInt(tti);
+ config.kcpItem.uplinkCapacity = Utils.ToInt(uplinkCapacity);
+ config.kcpItem.downlinkCapacity = Utils.ToInt(downlinkCapacity);
+ config.kcpItem.readBufferSize = Utils.ToInt(readBufferSize);
+ config.kcpItem.writeBufferSize = Utils.ToInt(writeBufferSize);
+ config.kcpItem.congestion = congestion;
+
+ return 0;
+ }
+
+ ///
+ /// 保存GUI设置
+ ///
+ ///
+ private int SaveGUI()
+ {
+ //开机自动启动
+ Utils.SetAutoRun(chkAutoRun.Checked);
+
+ //自定义GFWList
+ config.urlGFWList = txturlGFWList.Text.TrimEx();
+
+ config.allowLANConn = chkAllowLANConn.Checked;
+
+ var lastEnableStatistics = config.enableStatistics;
+ config.enableStatistics = chkEnableStatistics.Checked;
+
+ uint days = 0;
+ var valid = uint.TryParse(tbCacheDays.Text, out days);
+ if (!valid)
+ days = 7;
+ config.CacheDays = days;
+
+ config.statisticsFreshRate = (int)cbFreshrate.SelectedValue;
+
+ //if(lastEnableStatistics != config.enableStatistics)
+ //{
+ // /// https://stackoverflow.com/questions/779405/how-do-i-restart-my-c-sharp-winform-application
+ // // Shut down the current app instance.
+ // Application.Exit();
+
+ // // Restart the app passing "/restart [processId]" as cmd line args
+ // Process.Start(Application.ExecutablePath, "/restart " + Process.GetCurrentProcess().Id);
+ //}
+ return 0;
+ }
+
+ private void btnClose_Click(object sender, EventArgs e)
+ {
+ this.DialogResult = DialogResult.Cancel;
+ }
+
+ private void chkAllowIn2_CheckedChanged(object sender, EventArgs e)
+ {
+ chkAllowIn2State();
+ }
+ private void chkAllowIn2State()
+ {
+ bool blAllow2 = chkAllowIn2.Checked;
+ txtlocalPort2.Enabled =
+ cmbprotocol2.Enabled =
+ chkudpEnabled2.Enabled = blAllow2;
+ }
+
+ private void btnSetDefRountingRule_Click(object sender, EventArgs e)
+ {
+ var lstUrl = new List();
+ lstUrl.Add(Global.CustomRoutingListUrl + "proxy");
+ lstUrl.Add(Global.CustomRoutingListUrl + "direct");
+ lstUrl.Add(Global.CustomRoutingListUrl + "block");
+
+ var lstTxt = new List();
+ lstTxt.Add(txtUseragent);
+ lstTxt.Add(txtUserdirect);
+ lstTxt.Add(txtUserblock);
+
+ for (int k = 0; k < lstUrl.Count; k++)
+ {
+ var txt = lstTxt[k];
+ V2rayUpdateHandle v2rayUpdateHandle3 = new V2rayUpdateHandle();
+ v2rayUpdateHandle3.UpdateCompleted += (sender2, args) =>
+ {
+ if (args.Success)
+ {
+ var result = args.Msg;
+ if (Utils.IsNullOrEmpty(result))
+ {
+ return;
+ }
+ txt.Text = result;
+ }
+ else
+ {
+ AppendText(false, args.Msg);
+ }
+ };
+ v2rayUpdateHandle3.Error += (sender2, args) =>
+ {
+ AppendText(true, args.GetException().Message);
+ };
+
+ v2rayUpdateHandle3.WebDownloadString(lstUrl[k]);
+ }
+ }
+ void AppendText(bool notify, string text)
+ {
+ labRoutingTips.Text = text;
+ }
+ }
+
+ class ComboItem
+ {
+ public int ID { get; set; }
+ public string Text { get; set; }
+ }
+}
diff --git a/v2rayN/v2rayN/Forms/OptionSettingForm.resx b/v2rayN/v2rayN/Forms/OptionSettingForm.resx
new file mode 100644
index 00000000..7e395cbd
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/OptionSettingForm.resx
@@ -0,0 +1,1869 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+ 355, 16
+
+
+ 75, 23
+
+
+
+ 7
+
+
+ &Cancel
+
+
+ btnClose
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel2
+
+
+ 0
+
+
+ True
+
+
+
+ NoControl
+
+
+ 468, 60
+
+
+ 120, 16
+
+
+ 32
+
+
+ Turn on Sniffing
+
+
+ False
+
+
+ chksniffingEnabled2
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 0
+
+
+ True
+
+
+ NoControl
+
+
+ 468, 27
+
+
+ 120, 16
+
+
+ 31
+
+
+ Turn on Sniffing
+
+
+ chksniffingEnabled
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 1
+
+
+ 33, 192
+
+
+ 402, 21
+
+
+ 30
+
+
+ txtremoteDNS
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 2
+
+
+ True
+
+
+ 33, 168
+
+
+ 281, 12
+
+
+ 29
+
+
+ Custom DNS (multiple, separated by commas (,))
+
+
+ label14
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 3
+
+
+ True
+
+
+ 15, 93
+
+
+ 174, 16
+
+
+ 20
+
+
+ Turn on Mux Multiplexing
+
+
+ chkmuxEnabled
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 4
+
+
+ True
+
+
+ 15, 63
+
+
+ 120, 16
+
+
+ 19
+
+
+ listening port 2
+
+
+ False
+
+
+ chkAllowIn2
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 5
+
+
+ True
+
+
+ 369, 62
+
+
+ 84, 16
+
+
+ 18
+
+
+ Enable UDP
+
+
+ False
+
+
+ chkudpEnabled2
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 6
+
+
+ socks
+
+
+ http
+
+
+ 257, 60
+
+
+ 97, 20
+
+
+ 17
+
+
+ False
+
+
+ cmbprotocol2
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 7
+
+
+ True
+
+
+ 206, 64
+
+
+ 53, 12
+
+
+ 16
+
+
+ protocol
+
+
+ False
+
+
+ label3
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 8
+
+
+ 124, 60
+
+
+ 78, 21
+
+
+ 14
+
+
+ False
+
+
+ txtlocalPort2
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 9
+
+
+ False
+
+
+ socks
+
+
+ http
+
+
+ 257, 25
+
+
+ 97, 20
+
+
+ 12
+
+
+ cmbprotocol
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 10
+
+
+ True
+
+
+ 206, 29
+
+
+ 53, 12
+
+
+ 11
+
+
+ protocol
+
+
+ label1
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 11
+
+
+ True
+
+
+ 369, 27
+
+
+ 84, 16
+
+
+ 10
+
+
+ Enable UDP
+
+
+ chkudpEnabled
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 12
+
+
+ True
+
+
+ 15, 124
+
+
+ 126, 16
+
+
+ 9
+
+
+ Record local logs
+
+
+ chklogEnabled
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 13
+
+
+ debug
+
+
+ info
+
+
+ warning
+
+
+ error
+
+
+ none
+
+
+ 257, 122
+
+
+ 97, 20
+
+
+ 6
+
+
+ cmbloglevel
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 14
+
+
+ True
+
+
+ 193, 126
+
+
+ 59, 12
+
+
+ 8
+
+
+ Log level
+
+
+ label5
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 15
+
+
+ 124, 25
+
+
+ 78, 21
+
+
+ 3
+
+
+ txtlocalPort
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 16
+
+
+ True
+
+
+ 33, 29
+
+
+ 89, 12
+
+
+ 2
+
+
+ Listening port
+
+
+ label2
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox1
+
+
+ 17
+
+
+ Fill
+
+
+ 3, 3
+
+
+ 624, 573
+
+
+ 6
+
+
+ groupBox1
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage1
+
+
+ 0
+
+
+ 4, 22
+
+
+ 3, 3, 3, 3
+
+
+ 630, 579
+
+
+ 0
+
+
+ Core: basic settings
+
+
+ tabPage1
+
+
+ System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabControl1
+
+
+ 0
+
+
+ Fill
+
+
+ 3, 3
+
+
+ True
+
+
+ Vertical
+
+
+ 604, 414
+
+
+ 0
+
+
+ txtUseragent
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage3
+
+
+ 0
+
+
+ 4, 22
+
+
+ 3, 3, 3, 3
+
+
+ 610, 420
+
+
+ 0
+
+
+ Proxy's Domain or IP
+
+
+ tabPage3
+
+
+ System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabControl2
+
+
+ 0
+
+
+ Fill
+
+
+ 3, 3
+
+
+ True
+
+
+ Vertical
+
+
+ 604, 414
+
+
+ 1
+
+
+ txtUserdirect
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage4
+
+
+ 0
+
+
+ 4, 22
+
+
+ 3, 3, 3, 3
+
+
+ 610, 420
+
+
+ 1
+
+
+ Directly connected Domain or IP
+
+
+ tabPage4
+
+
+ System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabControl2
+
+
+ 1
+
+
+ Fill
+
+
+ 3, 3
+
+
+ True
+
+
+ Vertical
+
+
+ 604, 414
+
+
+ 1
+
+
+ txtUserblock
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage5
+
+
+ 0
+
+
+ 4, 22
+
+
+ 3, 3, 3, 3
+
+
+ 610, 420
+
+
+ 2
+
+
+ Blocked Domain or IP
+
+
+ tabPage5
+
+
+ System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabControl2
+
+
+ 2
+
+
+ Fill
+
+
+ 3, 124
+
+
+ 618, 446
+
+
+ 12
+
+
+ tabControl2
+
+
+ System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 0
+
+
+ 356, 43
+
+
+ 229, 23
+
+
+ 18
+
+
+ Set default custom routing rules
+
+
+ btnSetDefRountingRule
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel3
+
+
+ 0
+
+
+ AsIs
+
+
+ IPIfNonMatch
+
+
+ IPOnDemand
+
+
+ 123, 13
+
+
+ 209, 20
+
+
+ 16
+
+
+ cmbdomainStrategy
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel3
+
+
+ 1
+
+
+ 5, 83
+
+
+ 598, 16
+
+
+ 13
+
+
+ *Set the rules, separated by commas (,); support Domain (pure string / regular / subdomain) and IP
+
+
+ labRoutingTips
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel3
+
+
+ 2
+
+
+ True
+
+
+ NoControl
+
+
+ 13, 17
+
+
+ 95, 12
+
+
+ 17
+
+
+ Domain strategy
+
+
+ label15
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel3
+
+
+ 3
+
+
+ True
+
+
+ NoControl
+
+
+ 13, 50
+
+
+ 77, 12
+
+
+ 15
+
+
+ Routing mode
+
+
+ label12
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel3
+
+
+ 4
+
+
+ Global
+
+
+ Bypassing the LAN address
+
+
+ Bypass mainland address
+
+
+ Bypassing LAN and mainland address
+
+
+ 123, 46
+
+
+ 209, 20
+
+
+ 14
+
+
+ cmbroutingMode
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel3
+
+
+ 5
+
+
+ Top
+
+
+ 3, 17
+
+
+ 618, 107
+
+
+ 19
+
+
+ panel3
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ groupBox2
+
+
+ 1
+
+
+ Fill
+
+
+ 3, 3
+
+
+ 624, 573
+
+
+ 12
+
+
+ groupBox2
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage2
+
+
+ 0
+
+
+ 4, 22
+
+
+ 3, 3, 3, 3
+
+
+ 630, 579
+
+
+ 1
+
+
+ Core: Routing settings
+
+
+ tabPage2
+
+
+ System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabControl1
+
+
+ 1
+
+
+ True
+
+
+ 20, 143
+
+
+ 84, 16
+
+
+ 20
+
+
+ congestion
+
+
+ chkKcpcongestion
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage6
+
+
+ 0
+
+
+ 345, 100
+
+
+ 94, 21
+
+
+ 15
+
+
+ txtKcpwriteBufferSize
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage6
+
+
+ 1
+
+
+ True
+
+
+ 236, 104
+
+
+ 95, 12
+
+
+ 14
+
+
+ writeBufferSize
+
+
+ label10
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage6
+
+
+ 2
+
+
+ 111, 100
+
+
+ 94, 21
+
+
+ 13
+
+
+ txtKcpreadBufferSize
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage6
+
+
+ 3
+
+
+ True
+
+
+ 18, 104
+
+
+ 89, 12
+
+
+ 12
+
+
+ readBufferSize
+
+
+ label11
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage6
+
+
+ 4
+
+
+ 345, 62
+
+
+ 94, 21
+
+
+ 11
+
+
+ txtKcpdownlinkCapacity
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage6
+
+
+ 5
+
+
+ True
+
+
+ 236, 66
+
+
+ 101, 12
+
+
+ 10
+
+
+ downlinkCapacity
+
+
+ label8
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage6
+
+
+ 6
+
+
+ 111, 62
+
+
+ 94, 21
+
+
+ 9
+
+
+ txtKcpuplinkCapacity
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage6
+
+
+ 7
+
+
+ True
+
+
+ 18, 66
+
+
+ 89, 12
+
+
+ 8
+
+
+ uplinkCapacity
+
+
+ label9
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage6
+
+
+ 8
+
+
+ 345, 24
+
+
+ 94, 21
+
+
+ 7
+
+
+ txtKcptti
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage6
+
+
+ 9
+
+
+ True
+
+
+ 236, 28
+
+
+ 23, 12
+
+
+ 6
+
+
+ tti
+
+
+ label7
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage6
+
+
+ 10
+
+
+ 111, 24
+
+
+ 94, 21
+
+
+ 5
+
+
+ txtKcpmtu
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage6
+
+
+ 11
+
+
+ True
+
+
+ 18, 28
+
+
+ 23, 12
+
+
+ 4
+
+
+ mtu
+
+
+ label6
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage6
+
+
+ 12
+
+
+ 4, 22
+
+
+ 3, 3, 3, 3
+
+
+ 630, 579
+
+
+ 2
+
+
+ Core: KCP settings
+
+
+ tabPage6
+
+
+ System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabControl1
+
+
+ 2
+
+
+ 161, 82
+
+
+ 58, 20
+
+
+ 32
+
+
+ cbFreshrate
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage7
+
+
+ 0
+
+
+ 516, 109
+
+
+ 60, 21
+
+
+ 31
+
+
+ tbCacheDays
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage7
+
+
+ 1
+
+
+ True
+
+
+ NoControl
+
+
+ 30, 90
+
+
+ 125, 12
+
+
+ 30
+
+
+ Statistics freshrate
+
+
+ lbFreshrate
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage7
+
+
+ 2
+
+
+ True
+
+
+ 30, 118
+
+
+ 455, 12
+
+
+ 30
+
+
+ Cache days(between 0 to 30, 0 disable cache indivitual days statistic data)
+
+
+ lbCacheDays
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage7
+
+
+ 3
+
+
+ True
+
+
+ NoControl
+
+
+ 15, 60
+
+
+ 558, 16
+
+
+ 29
+
+
+ Enable Statistics(Realtime net speed and traffic data amount. Need restart v2rayN client)
+
+
+ chkEnableStatistics
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage7
+
+
+ 4
+
+
+ True
+
+
+ 15, 38
+
+
+ 204, 16
+
+
+ 29
+
+
+ Allow connections from the LAN
+
+
+ chkAllowLANConn
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage7
+
+
+ 5
+
+
+ 32, 205
+
+
+ 544, 21
+
+
+ 28
+
+
+ txturlGFWList
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage7
+
+
+ 6
+
+
+ True
+
+
+ 30, 176
+
+
+ 431, 12
+
+
+ 27
+
+
+ Custom GFWList address (please fill in the blank without customization)
+
+
+ label13
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage7
+
+
+ 7
+
+
+ True
+
+
+ 15, 16
+
+
+ 132, 16
+
+
+ 23
+
+
+ Boot automatically
+
+
+ chkAutoRun
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabPage7
+
+
+ 8
+
+
+ 4, 22
+
+
+ 3, 3, 3, 3
+
+
+ 630, 579
+
+
+ 3
+
+
+ v2rayN settings
+
+
+ tabPage7
+
+
+ System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tabControl1
+
+
+ 3
+
+
+ Fill
+
+
+ 0, 10
+
+
+ 638, 605
+
+
+ 10
+
+
+ tabControl1
+
+
+ System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 0
+
+
+ 267, 16
+
+
+ 75, 23
+
+
+ 8
+
+
+ &OK
+
+
+ btnOK
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel2
+
+
+ 1
+
+
+ Bottom
+
+
+ 0, 615
+
+
+ 638, 60
+
+
+ 11
+
+
+ panel2
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 1
+
+
+ Top
+
+
+ 0, 0
+
+
+ 638, 10
+
+
+ 9
+
+
+ panel1
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 2
+
+
+ 17, 17
+
+
+ True
+
+
+ 6, 12
+
+
+ 638, 675
+
+
+ 4, 4, 4, 4
+
+
+ Settings
+
+
+ configBindingSource
+
+
+ System.Windows.Forms.BindingSource, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ OptionSettingForm
+
+
+ v2rayN.Forms.BaseForm, v2rayN, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/OptionSettingForm.zh-Hans.resx b/v2rayN/v2rayN/Forms/OptionSettingForm.zh-Hans.resx
new file mode 100644
index 00000000..cef4cd5a
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/OptionSettingForm.zh-Hans.resx
@@ -0,0 +1,300 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 取消(&C)
+
+
+
+ 96, 16
+
+
+ 开启流量探测
+
+
+ 96, 16
+
+
+ 开启流量探测
+
+
+ 191, 12
+
+
+ 自定义DNS(可多个,用逗号(,)隔开)
+
+
+ 开启Mux多路复用(默认开启)
+
+
+ 102, 16
+
+
+ 本地监听端口2
+
+
+ 66, 16
+
+
+ 开启UDP
+
+
+ 29, 12
+
+
+ 协议
+
+
+ 29, 12
+
+
+ 协议
+
+
+ 66, 16
+
+
+ 开启UDP
+
+
+ 156, 16
+
+
+ 记录本地日志(默认关闭)
+
+
+ 53, 12
+
+
+ 日志等级
+
+
+ 77, 12
+
+
+ 本地监听端口
+
+
+ Core:基础设置
+
+
+ 代理的Domain或IP
+
+
+ 直连的Domain或IP
+
+
+ 阻止的Domain或IP
+
+
+
+ NoControl
+
+
+ 381, 43
+
+
+ 201, 23
+
+
+ 一键设置默认自定义路由规则
+
+
+ 232, 20
+
+
+
+ True
+
+
+ 383, 12
+
+
+ *设置的规则,用逗号(,)隔开;支持Domain(纯字符串/正则/子域名)和IP
+
+
+ 53, 12
+
+
+ 域名策略
+
+
+ 53, 12
+
+
+ 路由模式
+
+
+ 全局
+
+
+ 绕过局域网地址
+
+
+ 绕过大陆地址
+
+
+ 绕过局域网及大陆地址
+
+
+ 232, 20
+
+
+ Core:路由设置
+
+
+ Core:KCP设置
+
+
+ 144, 16
+
+
+ 允许来自局域网的连接
+
+
+ 227, 12
+
+
+ 自定义GFWList地址(不需自定义请填空白)
+
+
+ 180, 16
+
+
+ 开机自动启动(可能会不成功)
+
+
+ v2rayN设置
+
+
+ 确定(&O)
+
+
+ 参数设置
+
+
+ 启用统计(实时网速显示和使用流量显示,需要重启v2rayN客户端)
+
+
+ 缓存天数(0-30, 0关闭缓存单独每天的数据使用情况)
+
+
+ 统计刷新频率
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/QRCodeControl.Designer.cs b/v2rayN/v2rayN/Forms/QRCodeControl.Designer.cs
new file mode 100644
index 00000000..5d0a2624
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/QRCodeControl.Designer.cs
@@ -0,0 +1,78 @@
+namespace v2rayN.Forms
+{
+ partial class QRCodeControl
+ {
+ ///
+ /// 必需的设计器变量。
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 清理所有正在使用的资源。
+ ///
+ /// 如果应释放托管资源,为 true;否则为 false。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region 组件设计器生成的代码
+
+ ///
+ /// 设计器支持所需的方法 - 不要
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(QRCodeControl));
+ this.txtUrl = new System.Windows.Forms.TextBox();
+ this.picQRCode = new System.Windows.Forms.PictureBox();
+ this.chkShow = new System.Windows.Forms.CheckBox();
+ ((System.ComponentModel.ISupportInitialize)(this.picQRCode)).BeginInit();
+ this.SuspendLayout();
+ //
+ // txtUrl
+ //
+ resources.ApplyResources(this.txtUrl, "txtUrl");
+ this.txtUrl.Name = "txtUrl";
+ this.txtUrl.ReadOnly = true;
+ //
+ // picQRCode
+ //
+ resources.ApplyResources(this.picQRCode, "picQRCode");
+ this.picQRCode.Name = "picQRCode";
+ this.picQRCode.TabStop = false;
+ //
+ // chkShow
+ //
+ resources.ApplyResources(this.chkShow, "chkShow");
+ this.chkShow.Name = "chkShow";
+ this.chkShow.UseVisualStyleBackColor = true;
+ this.chkShow.CheckedChanged += new System.EventHandler(this.chkShow_CheckedChanged);
+ //
+ // QRCodeControl
+ //
+ resources.ApplyResources(this, "$this");
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.picQRCode);
+ this.Controls.Add(this.txtUrl);
+ this.Controls.Add(this.chkShow);
+ this.Name = "QRCodeControl";
+ this.Load += new System.EventHandler(this.QRCodeControl_Load);
+ ((System.ComponentModel.ISupportInitialize)(this.picQRCode)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TextBox txtUrl;
+ private System.Windows.Forms.PictureBox picQRCode;
+ private System.Windows.Forms.CheckBox chkShow;
+ }
+}
diff --git a/v2rayN/v2rayN/Forms/QRCodeControl.cs b/v2rayN/v2rayN/Forms/QRCodeControl.cs
new file mode 100644
index 00000000..ea5e7fda
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/QRCodeControl.cs
@@ -0,0 +1,47 @@
+using System.Windows.Forms;
+using v2rayN.Handler;
+using v2rayN.Mode;
+
+namespace v2rayN.Forms
+{
+ public partial class QRCodeControl : UserControl
+ {
+ public QRCodeControl()
+ {
+ InitializeComponent();
+ }
+ private void QRCodeControl_Load(object sender, System.EventArgs e)
+ {
+ chkShow_CheckedChanged(null, null);
+ txtUrl.MouseUp += txtUrl_MouseUp;
+ }
+
+ void txtUrl_MouseUp(object sender, MouseEventArgs e)
+ {
+ txtUrl.SelectAll();
+ }
+
+ public void showQRCode(int Index, Config config)
+ {
+ if (Index >= 0)
+ {
+ string url = ConfigHandler.GetVmessQRCode(config, Index);
+ if (Utils.IsNullOrEmpty(url))
+ {
+ picQRCode.Image = null;
+ txtUrl.Text = string.Empty;
+ return;
+ }
+ picQRCode.Image = QRCodeHelper.GetQRCode(url);
+ txtUrl.Text = url;
+ }
+ }
+
+ private void chkShow_CheckedChanged(object sender, System.EventArgs e)
+ {
+ picQRCode.Visible =
+ txtUrl.Visible = chkShow.Checked;
+ }
+
+ }
+}
diff --git a/v2rayN/v2rayN/Forms/QRCodeControl.resx b/v2rayN/v2rayN/Forms/QRCodeControl.resx
new file mode 100644
index 00000000..ef0c4f04
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/QRCodeControl.resx
@@ -0,0 +1,222 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 0
+
+
+
+ 356, 441
+
+
+ 0, 0
+
+
+
+ 0
+
+
+ Show shared content
+
+
+ System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 356, 16
+
+
+ QRCodeControl
+
+
+ 356, 355
+
+
+ 0, 371
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ Bottom
+
+
+ 24
+
+
+ Top
+
+
+ Fill
+
+
+ True
+
+
+ Zoom
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 1
+
+
+ $this
+
+
+ 0, 16
+
+
+ $this
+
+
+ chkShow
+
+
+ $this
+
+
+ txtUrl
+
+
+ 2
+
+
+ picQRCode
+
+
+ 356, 70
+
+
+ 25
+
+
+ 6, 12
+
+
+ True
+
+
+ True
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/QRCodeControl.zh-Hans.resx b/v2rayN/v2rayN/Forms/QRCodeControl.zh-Hans.resx
new file mode 100644
index 00000000..991ed0d0
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/QRCodeControl.zh-Hans.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 显示分享内容
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/QRCodeForm.Designer.cs b/v2rayN/v2rayN/Forms/QRCodeForm.Designer.cs
new file mode 100644
index 00000000..733adb47
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/QRCodeForm.Designer.cs
@@ -0,0 +1,94 @@
+namespace v2rayN.Forms
+{
+ partial class QRCodeForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.picQRCode = new System.Windows.Forms.PictureBox();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.txtUrl = new System.Windows.Forms.TextBox();
+ ((System.ComponentModel.ISupportInitialize)(this.picQRCode)).BeginInit();
+ this.groupBox1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // picQRCode
+ //
+ this.picQRCode.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.picQRCode.Location = new System.Drawing.Point(0, 0);
+ this.picQRCode.Name = "picQRCode";
+ this.picQRCode.Size = new System.Drawing.Size(482, 483);
+ this.picQRCode.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
+ this.picQRCode.TabIndex = 23;
+ this.picQRCode.TabStop = false;
+ //
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.txtUrl);
+ this.groupBox1.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.groupBox1.Location = new System.Drawing.Point(0, 483);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(482, 90);
+ this.groupBox1.TabIndex = 0;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "URL";
+ //
+ // txtUrl
+ //
+ this.txtUrl.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.txtUrl.Location = new System.Drawing.Point(3, 17);
+ this.txtUrl.Multiline = true;
+ this.txtUrl.Name = "txtUrl";
+ this.txtUrl.ReadOnly = true;
+ this.txtUrl.Size = new System.Drawing.Size(476, 70);
+ this.txtUrl.TabIndex = 0;
+ //
+ // QRCodeForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(482, 573);
+ this.Controls.Add(this.picQRCode);
+ this.Controls.Add(this.groupBox1);
+ this.Name = "QRCodeForm";
+ this.Text = "服务器配置二维码和URL";
+ this.Load += new System.EventHandler(this.QRCodeForm_Load);
+ this.Shown += new System.EventHandler(this.QRCodeForm_Shown);
+ ((System.ComponentModel.ISupportInitialize)(this.picQRCode)).EndInit();
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.TextBox txtUrl;
+ private System.Windows.Forms.PictureBox picQRCode;
+
+ }
+}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/QRCodeForm.cs b/v2rayN/v2rayN/Forms/QRCodeForm.cs
new file mode 100644
index 00000000..d170b173
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/QRCodeForm.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using v2rayN.Handler;
+using v2rayN.Mode;
+
+namespace v2rayN.Forms
+{
+ public partial class QRCodeForm : BaseForm
+ {
+ public int Index { get; set; }
+
+ public QRCodeForm()
+ {
+ InitializeComponent();
+ }
+
+ private void QRCodeForm_Load(object sender, EventArgs e)
+ {
+ txtUrl.MouseUp += txtUrl_MouseUp;
+ }
+
+ void txtUrl_MouseUp(object sender, MouseEventArgs e)
+ {
+ txtUrl.SelectAll();
+ }
+
+ private void QRCodeForm_Shown(object sender, EventArgs e)
+ {
+ if (Index >= 0)
+ {
+ VmessQRCode vmessQRCode = null;
+ if (ConfigHandler.GetVmessQRCode(config, Index, ref vmessQRCode) != 0)
+ {
+ return;
+ }
+ string url = Utils.ToJson(vmessQRCode);
+ url = Utils.Base64Encode(url);
+ url = string.Format("{0}{1}", Global.vmessProtocol, url);
+ picQRCode.Image = QRCodeHelper.GetQRCode(url);
+ txtUrl.Text = url;
+ }
+ }
+
+ }
+}
diff --git a/v2rayN/v2rayN/Forms/QRCodeForm.resx b/v2rayN/v2rayN/Forms/QRCodeForm.resx
new file mode 100644
index 00000000..1af7de15
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/QRCodeForm.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/SubSettingControl.Designer.cs b/v2rayN/v2rayN/Forms/SubSettingControl.Designer.cs
new file mode 100644
index 00000000..30fcadf5
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/SubSettingControl.Designer.cs
@@ -0,0 +1,113 @@
+namespace v2rayN.Forms
+{
+ partial class SubSettingControl
+ {
+ ///
+ /// 必需的设计器变量。
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 清理所有正在使用的资源。
+ ///
+ /// 如果应释放托管资源,为 true;否则为 false。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region 组件设计器生成的代码
+
+ ///
+ /// 设计器支持所需的方法 - 不要修改
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SubSettingControl));
+ this.groupBox2 = new System.Windows.Forms.GroupBox();
+ this.chkEnabled = new System.Windows.Forms.CheckBox();
+ this.btnRemove = new System.Windows.Forms.Button();
+ this.txtUrl = new System.Windows.Forms.TextBox();
+ this.txtRemarks = new System.Windows.Forms.TextBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.label3 = new System.Windows.Forms.Label();
+ this.groupBox2.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // groupBox2
+ //
+ resources.ApplyResources(this.groupBox2, "groupBox2");
+ this.groupBox2.Controls.Add(this.chkEnabled);
+ this.groupBox2.Controls.Add(this.btnRemove);
+ this.groupBox2.Controls.Add(this.txtUrl);
+ this.groupBox2.Controls.Add(this.txtRemarks);
+ this.groupBox2.Controls.Add(this.label2);
+ this.groupBox2.Controls.Add(this.label3);
+ this.groupBox2.Name = "groupBox2";
+ this.groupBox2.TabStop = false;
+ //
+ // chkEnabled
+ //
+ resources.ApplyResources(this.chkEnabled, "chkEnabled");
+ this.chkEnabled.Name = "chkEnabled";
+ this.chkEnabled.UseVisualStyleBackColor = true;
+ this.chkEnabled.Leave += new System.EventHandler(this.txtRemarks_Leave);
+ //
+ // btnRemove
+ //
+ resources.ApplyResources(this.btnRemove, "btnRemove");
+ this.btnRemove.Name = "btnRemove";
+ this.btnRemove.UseVisualStyleBackColor = true;
+ this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click);
+ //
+ // txtUrl
+ //
+ resources.ApplyResources(this.txtUrl, "txtUrl");
+ this.txtUrl.Name = "txtUrl";
+ this.txtUrl.Leave += new System.EventHandler(this.txtRemarks_Leave);
+ //
+ // txtRemarks
+ //
+ resources.ApplyResources(this.txtRemarks, "txtRemarks");
+ this.txtRemarks.Name = "txtRemarks";
+ this.txtRemarks.Leave += new System.EventHandler(this.txtRemarks_Leave);
+ //
+ // label2
+ //
+ resources.ApplyResources(this.label2, "label2");
+ this.label2.Name = "label2";
+ //
+ // label3
+ //
+ resources.ApplyResources(this.label3, "label3");
+ this.label3.Name = "label3";
+ //
+ // SubSettingControl
+ //
+ resources.ApplyResources(this, "$this");
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.groupBox2);
+ this.Name = "SubSettingControl";
+ this.Load += new System.EventHandler(this.SubSettingControl_Load);
+ this.groupBox2.ResumeLayout(false);
+ this.groupBox2.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.GroupBox groupBox2;
+ private System.Windows.Forms.TextBox txtUrl;
+ private System.Windows.Forms.TextBox txtRemarks;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.Button btnRemove;
+ private System.Windows.Forms.CheckBox chkEnabled;
+ }
+}
diff --git a/v2rayN/v2rayN/Forms/SubSettingControl.cs b/v2rayN/v2rayN/Forms/SubSettingControl.cs
new file mode 100644
index 00000000..a4ee2189
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/SubSettingControl.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Windows.Forms;
+using v2rayN.Mode;
+
+namespace v2rayN.Forms
+{
+ public delegate void ChangeEventHandler(object sender, EventArgs e);
+ public partial class SubSettingControl : UserControl
+ {
+ public event ChangeEventHandler OnButtonClicked;
+
+
+ public SubItem subItem { get; set; }
+
+ public SubSettingControl()
+ {
+ InitializeComponent();
+ }
+
+ private void SubSettingControl_Load(object sender, EventArgs e)
+ {
+ BindingSub();
+ }
+
+ private void BindingSub()
+ {
+ if (subItem != null)
+ {
+ txtRemarks.Text = subItem.remarks.ToString();
+ txtUrl.Text = subItem.url.ToString();
+ chkEnabled.Checked = subItem.enabled;
+ }
+ }
+ private void EndBindingSub()
+ {
+ if (subItem != null)
+ {
+ subItem.remarks = txtRemarks.Text.TrimEx();
+ subItem.url = txtUrl.Text.TrimEx();
+ subItem.enabled = chkEnabled.Checked;
+ }
+ }
+ private void txtRemarks_Leave(object sender, EventArgs e)
+ {
+ EndBindingSub();
+ }
+
+ private void btnRemove_Click(object sender, EventArgs e)
+ {
+ if (subItem != null)
+ {
+ subItem.remarks = string.Empty;
+ subItem.url = string.Empty;
+ }
+
+ if (OnButtonClicked != null)
+ {
+ OnButtonClicked(sender, e);
+ }
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/Forms/SubSettingControl.resx b/v2rayN/v2rayN/Forms/SubSettingControl.resx
new file mode 100644
index 00000000..af5f03e9
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/SubSettingControl.resx
@@ -0,0 +1,330 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+ NoControl
+
+
+ groupBox2
+
+
+
+ 60, 16
+
+
+ txtUrl
+
+
+ &Remove
+
+
+ 484, 21
+
+
+
+ 24
+
+
+ 432, 46
+
+
+ SubSettingControl
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ True
+
+
+ groupBox2
+
+
+ 83, 12
+
+
+ groupBox2
+
+
+ 6, 12
+
+
+ label3
+
+
+ 127, 21
+
+
+ True
+
+
+ 0
+
+
+ 12, 55
+
+
+ 127, 55
+
+
+ 10
+
+
+ Bottom
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 2
+
+
+ groupBox2
+
+
+ 4
+
+
+ 47, 12
+
+
+ Subscription details
+
+
+ 0, 9
+
+
+ Enable
+
+
+ chkEnabled
+
+
+ 3
+
+
+ NoControl
+
+
+ Address (url)
+
+
+ 25
+
+
+ 23
+
+
+ groupBox2
+
+
+ groupBox2
+
+
+ 406, 23
+
+
+ True
+
+
+ True
+
+
+ btnRemove
+
+
+ NoControl
+
+
+ label2
+
+
+ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 584, 110
+
+
+ NoControl
+
+
+ 584, 119
+
+
+ 11
+
+
+ Remarks
+
+
+ 0
+
+
+ 12, 25
+
+
+ 75, 23
+
+
+ groupBox2
+
+
+ 265, 21
+
+
+ 10
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 1
+
+
+ $this
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 0
+
+
+ txtRemarks
+
+
+ 5
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ True
+
+
+ zh-Hans
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/SubSettingControl.zh-Hans.resx b/v2rayN/v2rayN/Forms/SubSettingControl.zh-Hans.resx
new file mode 100644
index 00000000..12e6dbd4
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/SubSettingControl.zh-Hans.resx
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+ 48, 16
+
+
+ 启用
+
+
+ 移除
+
+
+ 29, 12
+
+
+ 备注
+
+
+ 65, 12
+
+
+ 地址 (url)
+
+
+ 订阅详情
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/SubSettingForm.Designer.cs b/v2rayN/v2rayN/Forms/SubSettingForm.Designer.cs
new file mode 100644
index 00000000..489693c8
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/SubSettingForm.Designer.cs
@@ -0,0 +1,97 @@
+namespace v2rayN.Forms
+{
+ partial class SubSettingForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SubSettingForm));
+ this.btnClose = new System.Windows.Forms.Button();
+ this.panCon = new System.Windows.Forms.Panel();
+ this.panel2 = new System.Windows.Forms.Panel();
+ this.btnAdd = new System.Windows.Forms.Button();
+ this.btnOK = new System.Windows.Forms.Button();
+ this.panel2.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // btnClose
+ //
+ this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ resources.ApplyResources(this.btnClose, "btnClose");
+ this.btnClose.Name = "btnClose";
+ this.btnClose.UseVisualStyleBackColor = true;
+ this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
+ //
+ // panCon
+ //
+ resources.ApplyResources(this.panCon, "panCon");
+ this.panCon.Name = "panCon";
+ //
+ // panel2
+ //
+ this.panel2.Controls.Add(this.btnAdd);
+ this.panel2.Controls.Add(this.btnClose);
+ this.panel2.Controls.Add(this.btnOK);
+ resources.ApplyResources(this.panel2, "panel2");
+ this.panel2.Name = "panel2";
+ //
+ // btnAdd
+ //
+ resources.ApplyResources(this.btnAdd, "btnAdd");
+ this.btnAdd.Name = "btnAdd";
+ this.btnAdd.UseVisualStyleBackColor = true;
+ this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);
+ //
+ // btnOK
+ //
+ resources.ApplyResources(this.btnOK, "btnOK");
+ this.btnOK.Name = "btnOK";
+ this.btnOK.UseVisualStyleBackColor = true;
+ this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
+ //
+ // SubSettingForm
+ //
+ resources.ApplyResources(this, "$this");
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.btnClose;
+ this.Controls.Add(this.panCon);
+ this.Controls.Add(this.panel2);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.Name = "SubSettingForm";
+ this.Load += new System.EventHandler(this.SubSettingForm_Load);
+ this.panel2.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+ private System.Windows.Forms.Button btnClose;
+ private System.Windows.Forms.Button btnOK;
+ private System.Windows.Forms.Panel panel2;
+ private System.Windows.Forms.Button btnAdd;
+ private System.Windows.Forms.Panel panCon;
+ }
+}
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/SubSettingForm.cs b/v2rayN/v2rayN/Forms/SubSettingForm.cs
new file mode 100644
index 00000000..14b5fbf6
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/SubSettingForm.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+using v2rayN.Handler;
+using v2rayN.Mode;
+
+namespace v2rayN.Forms
+{
+ public partial class SubSettingForm : BaseForm
+ {
+ List lstControls = new List();
+
+ public SubSettingForm()
+ {
+ InitializeComponent();
+ }
+
+ private void SubSettingForm_Load(object sender, EventArgs e)
+ {
+ if (config.subItem == null)
+ {
+ config.subItem = new List();
+ }
+
+ RefreshSubsView();
+ }
+
+ ///
+ /// 刷新列表
+ ///
+ private void RefreshSubsView()
+ {
+ panCon.Controls.Clear();
+ lstControls.Clear();
+
+ for (int k = config.subItem.Count - 1; k >= 0; k--)
+ {
+ var item = config.subItem[k];
+ if (Utils.IsNullOrEmpty(item.remarks)
+ && Utils.IsNullOrEmpty(item.url))
+ {
+ if (!Utils.IsNullOrEmpty(item.id))
+ {
+ ConfigHandler.RemoveServerViaSubid(ref config, item.id);
+ }
+ config.subItem.RemoveAt(k);
+ }
+ }
+
+ for (int k = 0; k < config.subItem.Count; k++)
+ {
+ var item = config.subItem[k];
+ SubSettingControl control = new SubSettingControl();
+ control.OnButtonClicked += Control_OnButtonClicked;
+ control.subItem = item;
+ control.Dock = DockStyle.Top;
+
+ panCon.Controls.Add(control);
+ panCon.Controls.SetChildIndex(control, 0);
+
+ lstControls.Add(control);
+ }
+ }
+
+ private void Control_OnButtonClicked(object sender, EventArgs e)
+ {
+ RefreshSubsView();
+ }
+
+ private void btnOK_Click(object sender, EventArgs e)
+ {
+ if (config.subItem.Count <= 0)
+ {
+ AddSub();
+ }
+
+ if (ConfigHandler.SaveSubItem(ref config) == 0)
+ {
+ this.DialogResult = DialogResult.OK;
+ }
+ else
+ {
+ UI.Show(UIRes.I18N("OperationFailed"));
+ }
+ }
+
+ private void btnClose_Click(object sender, EventArgs e)
+ {
+ this.DialogResult = DialogResult.Cancel;
+ }
+
+ private void btnAdd_Click(object sender, EventArgs e)
+ {
+ AddSub();
+
+ RefreshSubsView();
+ }
+
+
+ private void AddSub()
+ {
+ var subItem = new SubItem();
+ subItem.id = string.Empty;
+ subItem.remarks = "remarks";
+ subItem.url = "url";
+ config.subItem.Add(subItem);
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/Forms/SubSettingForm.resx b/v2rayN/v2rayN/Forms/SubSettingForm.resx
new file mode 100644
index 00000000..05d3db7b
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/SubSettingForm.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
+
+
+
+ NoControl
+
+
+
+ 448, 17
+
+
+ 75, 23
+
+
+
+ 4
+
+
+ &Cancel
+
+
+ btnClose
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel2
+
+
+ 1
+
+
+ True
+
+
+ Fill
+
+
+ 0, 0
+
+
+ 581, 569
+
+
+ 10
+
+
+ panCon
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 0
+
+
+ NoControl
+
+
+ 47, 17
+
+
+ 75, 23
+
+
+ 6
+
+
+ &Add
+
+
+ btnAdd
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel2
+
+
+ 0
+
+
+ NoControl
+
+
+ 355, 17
+
+
+ 75, 23
+
+
+ 5
+
+
+ &OK
+
+
+ btnOK
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ panel2
+
+
+ 2
+
+
+ Bottom
+
+
+ 0, 569
+
+
+ 581, 60
+
+
+ 7
+
+
+ panel2
+
+
+ System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ $this
+
+
+ 1
+
+
+ True
+
+
+ 6, 12
+
+
+ 581, 629
+
+
+ Subscription settings
+
+
+ SubSettingForm
+
+
+ v2rayN.Forms.BaseForm, v2rayN, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Forms/SubSettingForm.zh-Hans.resx b/v2rayN/v2rayN/Forms/SubSettingForm.zh-Hans.resx
new file mode 100644
index 00000000..628dd5ab
--- /dev/null
+++ b/v2rayN/v2rayN/Forms/SubSettingForm.zh-Hans.resx
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 取消(&C)
+
+
+ 添加(&A)
+
+
+ 确定(&O)
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
+ LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkMAwAAAFFTeXN0
+ ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2Vu
+ PWIwM2Y1ZjdmMTFkNTBhM2EFAQAAACFTeXN0ZW0uV2luZG93cy5Gb3Jtcy5MaXN0Vmlld0l0ZW0HAAAA
+ BFRleHQKSW1hZ2VJbmRleAlCYWNrQ29sb3IHQ2hlY2tlZARGb250CUZvcmVDb2xvchdVc2VJdGVtU3R5
+ bGVGb3JTdWJJdGVtcwEABAAEBAAIFFN5c3RlbS5EcmF3aW5nLkNvbG9yAwAAAAETU3lzdGVtLkRyYXdp
+ bmcuRm9udAMAAAAUU3lzdGVtLkRyYXdpbmcuQ29sb3IDAAAAAQIAAAAGBAAAAAD/////Bfv///8UU3lz
+ dGVtLkRyYXdpbmcuQ29sb3IEAAAABG5hbWUFdmFsdWUKa25vd25Db2xvcgVzdGF0ZQEAAAAJBwcDAAAA
+ CgAAAAAAAAAAGAABAAAJBgAAAAH5////+////woAAAAAAAAAABoAAQABBQYAAAATU3lzdGVtLkRyYXdp
+ bmcuRm9udAQAAAAETmFtZQRTaXplBVN0eWxlBFVuaXQBAAQECxhTeXN0ZW0uRHJhd2luZy5Gb250U3R5
+ bGUDAAAAG1N5c3RlbS5EcmF3aW5nLkdyYXBoaWNzVW5pdAMAAAADAAAABggAAAAG5a6L5L2TAAAQQQX3
+ ////GFN5c3RlbS5EcmF3aW5nLkZvbnRTdHlsZQEAAAAHdmFsdWVfXwAIAwAAAAAAAAAF9v///xtTeXN0
+ ZW0uRHJhd2luZy5HcmFwaGljc1VuaXQBAAAAB3ZhbHVlX18ACAMAAAADAAAACw==
+
+
+
+ 订阅设置
+
+
\ No newline at end of file
diff --git a/v2rayN/v2rayN/Global.cs b/v2rayN/v2rayN/Global.cs
new file mode 100644
index 00000000..2027cc78
--- /dev/null
+++ b/v2rayN/v2rayN/Global.cs
@@ -0,0 +1,204 @@
+
+namespace v2rayN
+{
+ class Global
+ {
+ #region 常量
+
+ ///
+ /// 更新链接
+ ///
+ public const string UpdateUrl = @"https://github.com/2dust/v2rayN/releases";
+ ///
+ /// 关于链接
+ ///
+ public const string AboutUrl = @"https://github.com/2dust/v2rayN";
+
+ ///
+ /// SpeedTestUrl
+ ///
+ public const string SpeedTestUrl = @"http://speedtest-sfo2.digitalocean.com/10mb.test";
+ public const string SpeedPingTestUrl = @"https://www.google.com/generate_204";
+
+ ///
+ /// CustomRoutingListUrl
+ ///
+ public const string CustomRoutingListUrl = @"https://raw.githubusercontent.com/2dust/v2rayCustomRoutingList/master/";
+
+ ///
+ /// PromotionUrl
+ ///
+ public const string PromotionUrl = @"https://1.2345345.xyz/ads.html";
+
+ ///
+ /// 本软件配置文件名
+ ///
+ public const string ConfigFileName = "guiNConfig.json";
+
+ ///
+ /// v2ray配置文件名
+ ///
+ public const string v2rayConfigFileName = "config.json";
+
+ ///
+ /// v2ray客户端配置样例文件名
+ ///
+ public const string v2raySampleClient = "v2rayN.Sample.SampleClientConfig.txt";
+ ///
+ /// v2ray服务端配置样例文件名
+ ///
+ public const string v2raySampleServer = "v2rayN.Sample.SampleServerConfig.txt";
+ ///
+ /// v2ray配置Httprequest文件名
+ ///
+ public const string v2raySampleHttprequestFileName = "v2rayN.Sample.SampleHttprequest.txt";
+ ///
+ /// v2ray配置Httpresponse文件名
+ ///
+ public const string v2raySampleHttpresponseFileName = "v2rayN.Sample.SampleHttpresponse.txt";
+ ///
+ /// 空白的pac文件
+ ///
+ public const string BlankPacFileName = "v2rayN.Sample.BlankPac.txt";
+
+
+ ///
+ /// 默认加密方式
+ ///
+ public const string DefaultSecurity = "auto";
+
+ ///
+ /// 默认传输协议
+ ///
+ public const string DefaultNetwork = "tcp";
+
+ ///
+ /// Tcp伪装http
+ ///
+ public const string TcpHeaderHttp = "http";
+
+ ///
+ /// None值
+ ///
+ public const string None = "none";
+
+ ///
+ /// 代理 tag值
+ ///
+ public const string agentTag = "proxy";
+
+ ///
+ /// 直连 tag值
+ ///
+ public const string directTag = "direct";
+
+ ///
+ /// 阻止 tag值
+ ///
+ public const string blockTag = "block";
+
+ ///
+ ///
+ ///
+ public const string StreamSecurity = "tls";
+
+ ///
+ /// vmess
+ ///
+ public const string vmessProtocol = "vmess://";
+ ///
+ /// shadowsocks
+ ///
+ public const string ssProtocol = "ss://";
+ ///
+ /// socks
+ ///
+ public const string socksProtocol = "socks://";
+ ///
+ /// http
+ ///
+ public const string httpProtocol = "http://";
+ ///
+ /// https
+ ///
+ public const string httpsProtocol = "https://";
+
+ ///
+ /// pac
+ ///
+ public const string pacFILE = "pac.txt";
+
+ ///
+ /// email
+ ///
+ public const string userEMail = "t@t.tt";
+
+ ///
+ /// MyRegPath
+ ///
+ public const string MyRegPath = "Software\\v2rayNGUI";
+
+ ///
+ /// Language
+ ///
+ public const string MyRegKeyLanguage = "CurrentLanguage";
+ ///
+ /// Icon
+ ///
+ public const string CustomIconName = "v2rayN.ico";
+
+
+ public const string InboundAPITagName = "api";
+ public const string InboundProxyTagName = "proxy";
+ public const string Loopback = "127.0.0.1";
+ public const string InboundAPIProtocal = "dokodemo-door";
+
+ public enum StatisticsFreshRate
+ {
+ quick = 1000,
+ medium = 2000,
+ slow = 3000
+ }
+ public const string StatisticLogDirectory = "Statistics";
+ public const string StatisticLogOverall = "overall.txt";
+
+ #endregion
+
+ #region 全局变量
+
+ ///
+ /// 是否需要重启服务V2ray
+ ///
+ public static bool reloadV2ray { get; set; }
+
+ ///
+ /// 是否开启全局代理(http)
+ ///
+ public static bool sysAgent { get; set; }
+
+ ///
+ /// socks端口号
+ ///
+ public static int socksPort { get; set; }
+
+ ///
+ /// 全局代理端口(http)
+ ///
+ public static int sysAgentPort { get; set; }
+
+ ///
+ /// PAC监听端口号
+ ///
+ public static int pacPort { get; set; }
+
+ ///
+ ///
+ ///
+ public static int statePort { get; set; }
+
+ #endregion
+
+
+
+ }
+}
diff --git a/v2rayN/v2rayN/Handler/ConfigHandler.cs b/v2rayN/v2rayN/Handler/ConfigHandler.cs
new file mode 100644
index 00000000..ba87e466
--- /dev/null
+++ b/v2rayN/v2rayN/Handler/ConfigHandler.cs
@@ -0,0 +1,853 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using v2rayN.Mode;
+
+namespace v2rayN.Handler
+{
+ ///
+ /// 本软件配置文件处理类
+ ///
+ class ConfigHandler
+ {
+ private static string configRes = Global.ConfigFileName;
+
+ ///
+ /// 载入配置文件
+ ///
+ ///
+ ///
+ public static int LoadConfig(ref Config config)
+ {
+ //载入配置文件
+ string result = Utils.LoadResource(Utils.GetPath(configRes));
+ if (!Utils.IsNullOrEmpty(result))
+ {
+ //转成Json
+ config = Utils.FromJson(result);
+ }
+ if (config == null)
+ {
+ config = new Config();
+ config.index = -1;
+ config.logEnabled = false;
+ config.loglevel = "warning";
+ config.vmess = new List();
+
+ //Mux
+ config.muxEnabled = true;
+
+ ////默认监听端口
+ //config.pacPort = 8888;
+
+ // 默认缓存七天
+ config.CacheDays = 7;
+
+ // 默认不开启统计
+ config.enableStatistics = false;
+
+ // 默认中等刷新率
+ config.statisticsFreshRate = (int)Global.StatisticsFreshRate.medium;
+ }
+
+ //本地监听
+ if (config.inbound == null)
+ {
+ config.inbound = new List();
+ InItem inItem = new InItem();
+ inItem.protocol = "socks";
+ inItem.localPort = 10808;
+ inItem.udpEnabled = true;
+ inItem.sniffingEnabled = true;
+
+ config.inbound.Add(inItem);
+
+ //inItem = new InItem();
+ //inItem.protocol = "http";
+ //inItem.localPort = 1081;
+ //inItem.udpEnabled = true;
+
+ //config.inbound.Add(inItem);
+ }
+ else
+ {
+ //http协议不由core提供,只保留socks
+ if (config.inbound.Count > 0)
+ {
+ config.inbound[0].protocol = "socks";
+ }
+ }
+ //路由规则
+ if (Utils.IsNullOrEmpty(config.domainStrategy))
+ {
+ config.domainStrategy = "IPIfNonMatch";
+ }
+ if (Utils.IsNullOrEmpty(config.routingMode))
+ {
+ config.routingMode = "0";
+ }
+ if (config.useragent == null)
+ {
+ config.useragent = new List();
+ }
+ if (config.userdirect == null)
+ {
+ config.userdirect = new List();
+ }
+ if (config.userblock == null)
+ {
+ config.userblock = new List();
+ }
+ //kcp
+ if (config.kcpItem == null)
+ {
+ config.kcpItem = new KcpItem();
+ config.kcpItem.mtu = 1350;
+ config.kcpItem.tti = 50;
+ config.kcpItem.uplinkCapacity = 12;
+ config.kcpItem.downlinkCapacity = 100;
+ config.kcpItem.readBufferSize = 2;
+ config.kcpItem.writeBufferSize = 2;
+ config.kcpItem.congestion = false;
+ }
+ if (config.uiItem == null)
+ {
+ config.uiItem = new UIItem();
+ }
+ //// 如果是用户升级,首次会有端口号为0的情况,不可用,这里处理
+ //if (config.pacPort == 0)
+ //{
+ // config.pacPort = 8888;
+ //}
+
+ if (config.subItem == null)
+ {
+ config.subItem = new List();
+ }
+
+ if (config == null
+ || config.index < 0
+ || config.vmess.Count <= 0
+ || config.index > config.vmess.Count - 1
+ )
+ {
+ Global.reloadV2ray = false;
+ }
+ else
+ {
+ Global.reloadV2ray = true;
+
+ //版本升级
+ for (int i = 0; i < config.vmess.Count; i++)
+ {
+ VmessItem vmessItem = config.vmess[i];
+ UpgradeServerVersion(ref vmessItem);
+ }
+ }
+
+ return 0;
+ }
+
+ ///
+ /// 添加服务器或编辑
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int AddServer(ref Config config, VmessItem vmessItem, int index)
+ {
+ vmessItem.configVersion = 2;
+ vmessItem.configType = (int)EConfigType.Vmess;
+
+ vmessItem.address = vmessItem.address.TrimEx();
+ vmessItem.id = vmessItem.id.TrimEx();
+ vmessItem.security = vmessItem.security.TrimEx();
+ vmessItem.network = vmessItem.network.TrimEx();
+ vmessItem.headerType = vmessItem.headerType.TrimEx();
+ vmessItem.requestHost = vmessItem.requestHost.TrimEx();
+ vmessItem.path = vmessItem.path.TrimEx();
+ vmessItem.streamSecurity = vmessItem.streamSecurity.TrimEx();
+
+ if (index >= 0)
+ {
+ //修改
+ config.vmess[index] = vmessItem;
+ if (config.index.Equals(index))
+ {
+ Global.reloadV2ray = true;
+ }
+ }
+ else
+ {
+ //添加
+ config.vmess.Add(vmessItem);
+ if (config.vmess.Count == 1)
+ {
+ config.index = 0;
+ Global.reloadV2ray = true;
+ }
+ }
+
+ ToJsonFile(config);
+
+ return 0;
+ }
+
+ ///
+ /// 移除服务器
+ ///
+ ///
+ ///
+ ///
+ public static int RemoveServer(ref Config config, int index)
+ {
+ if (index < 0 || index > config.vmess.Count - 1)
+ {
+ return -1;
+ }
+
+ //删除
+ config.vmess.RemoveAt(index);
+
+
+ //移除的是活动的
+ if (config.index.Equals(index))
+ {
+ if (config.vmess.Count > 0)
+ {
+ config.index = 0;
+ }
+ else
+ {
+ config.index = -1;
+ }
+ Global.reloadV2ray = true;
+ }
+ else if (index < config.index)//移除活动之前的
+ {
+ config.index--;
+ Global.reloadV2ray = true;
+ }
+
+ ToJsonFile(config);
+
+ return 0;
+ }
+
+ ///
+ /// 复制服务器
+ ///
+ ///
+ ///
+ ///
+ public static int CopyServer(ref Config config, int index)
+ {
+ if (index < 0 || index > config.vmess.Count - 1)
+ {
+ return -1;
+ }
+
+ VmessItem vmessItem = new VmessItem();
+ vmessItem.configVersion = config.vmess[index].configVersion;
+ vmessItem.configType = config.vmess[index].configType;
+ vmessItem.address = config.vmess[index].address;
+ vmessItem.port = config.vmess[index].port;
+ vmessItem.id = config.vmess[index].id;
+ vmessItem.alterId = config.vmess[index].alterId;
+ vmessItem.security = config.vmess[index].security;
+ vmessItem.network = config.vmess[index].network;
+ vmessItem.headerType = config.vmess[index].headerType;
+ vmessItem.requestHost = config.vmess[index].requestHost;
+ vmessItem.path = config.vmess[index].path;
+ vmessItem.streamSecurity = config.vmess[index].streamSecurity;
+ vmessItem.remarks = string.Format("{0}-clone", config.vmess[index].remarks);
+
+ config.vmess.Add(vmessItem);
+
+ ToJsonFile(config);
+
+ return 0;
+ }
+
+ ///
+ /// 设置活动服务器
+ ///
+ ///
+ ///
+ ///
+ public static int SetDefaultServer(ref Config config, int index)
+ {
+ if (index < 0 || index > config.vmess.Count - 1)
+ {
+ return -1;
+ }
+
+ ////和现在相同
+ //if (config.index.Equals(index))
+ //{
+ // return -1;
+ //}
+ config.index = index;
+ Global.reloadV2ray = true;
+
+ ToJsonFile(config);
+
+ return 0;
+ }
+
+ ///
+ /// 保参数
+ ///
+ ///
+ ///
+ public static int SaveConfig(ref Config config)
+ {
+ Global.reloadV2ray = true;
+
+ ToJsonFile(config);
+
+ return 0;
+ }
+
+ ///
+ /// 存储文件
+ ///
+ ///
+ public static void ToJsonFile(Config config)
+ {
+ Utils.ToJsonFile(config, Utils.GetPath(configRes));
+ }
+
+ ///
+ /// 取得服务器QRCode配置
+ ///
+ ///
+ ///
+ ///
+ public static string GetVmessQRCode(Config config, int index)
+ {
+ try
+ {
+ string url = string.Empty;
+
+ VmessItem vmessItem = config.vmess[index];
+ if (vmessItem.configType == (int)EConfigType.Vmess)
+ {
+ VmessQRCode vmessQRCode = new VmessQRCode();
+ vmessQRCode.v = vmessItem.configVersion.ToString();
+ vmessQRCode.ps = vmessItem.remarks.TrimEx(); //备注也许很长 ;
+ vmessQRCode.add = vmessItem.address;
+ vmessQRCode.port = vmessItem.port.ToString();
+ vmessQRCode.id = vmessItem.id;
+ vmessQRCode.aid = vmessItem.alterId.ToString();
+ vmessQRCode.net = vmessItem.network;
+ vmessQRCode.type = vmessItem.headerType;
+ vmessQRCode.host = vmessItem.requestHost;
+ vmessQRCode.path = vmessItem.path;
+ vmessQRCode.tls = vmessItem.streamSecurity;
+
+ url = Utils.ToJson(vmessQRCode);
+ url = Utils.Base64Encode(url);
+ url = string.Format("{0}{1}", Global.vmessProtocol, url);
+
+ }
+ else if (vmessItem.configType == (int)EConfigType.Shadowsocks)
+ {
+ var remark = string.Empty;
+ if (!Utils.IsNullOrEmpty(vmessItem.remarks))
+ {
+ remark = "#" + WebUtility.UrlEncode(vmessItem.remarks);
+ }
+ url = string.Format("{0}:{1}@{2}:{3}",
+ vmessItem.security,
+ vmessItem.id,
+ vmessItem.address,
+ vmessItem.port);
+ url = Utils.Base64Encode(url);
+ url = string.Format("{0}{1}{2}", Global.ssProtocol, url, remark);
+ }
+ else if (vmessItem.configType == (int)EConfigType.Socks)
+ {
+ var remark = string.Empty;
+ if (!Utils.IsNullOrEmpty(vmessItem.remarks))
+ {
+ remark = "#" + WebUtility.UrlEncode(vmessItem.remarks);
+ }
+ url = string.Format("{0}:{1}@{2}:{3}",
+ vmessItem.security,
+ vmessItem.id,
+ vmessItem.address,
+ vmessItem.port);
+ url = Utils.Base64Encode(url);
+ url = string.Format("{0}{1}{2}", Global.socksProtocol, url, remark);
+ }
+ else
+ {
+ }
+ return url;
+ }
+ catch
+ {
+ return "";
+ }
+ }
+
+ ///
+ /// 移动服务器
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int MoveServer(ref Config config, int index, EMove eMove)
+ {
+ int count = config.vmess.Count;
+ if (index < 0 || index > config.vmess.Count - 1)
+ {
+ return -1;
+ }
+ switch (eMove)
+ {
+ case EMove.Top:
+ {
+ if (index == 0)
+ {
+ return 0;
+ }
+ VmessItem vmess = Utils.DeepCopy(config.vmess[index]);
+ config.vmess.RemoveAt(index);
+ config.vmess.Insert(0, vmess);
+ if (index < config.index)
+ {
+ //
+ }
+ else if (config.index == index)
+ {
+ config.index = 0;
+ }
+ else
+ {
+ config.index++;
+ }
+ break;
+ }
+ case EMove.Up:
+ {
+ if (index == 0)
+ {
+ return 0;
+ }
+ VmessItem vmess = Utils.DeepCopy(config.vmess[index]);
+ config.vmess.RemoveAt(index);
+ config.vmess.Insert(index - 1, vmess);
+ if (index == config.index + 1)
+ {
+ config.index++;
+ }
+ else if (config.index == index)
+ {
+ config.index--;
+ }
+ break;
+ }
+
+ case EMove.Down:
+ {
+ if (index == count - 1)
+ {
+ return 0;
+ }
+ VmessItem vmess = Utils.DeepCopy(config.vmess[index]);
+ config.vmess.RemoveAt(index);
+ config.vmess.Insert(index + 1, vmess);
+ if (index == config.index - 1)
+ {
+ config.index--;
+ }
+ else if (config.index == index)
+ {
+ config.index++;
+ }
+ break;
+ }
+ case EMove.Bottom:
+ {
+ if (index == count - 1)
+ {
+ return 0;
+ }
+ VmessItem vmess = Utils.DeepCopy(config.vmess[index]);
+ config.vmess.RemoveAt(index);
+ config.vmess.Add(vmess);
+ if (index < config.index)
+ {
+ config.index--;
+ }
+ else if (config.index == index)
+ {
+ config.index = count - 1;
+ }
+ else
+ {
+ //
+ }
+ break;
+ }
+
+ }
+ Global.reloadV2ray = true;
+
+ ToJsonFile(config);
+
+ return 0;
+ }
+
+ ///
+ /// 添加自定义服务器
+ ///
+ ///
+ ///
+ ///
+ public static int AddCustomServer(ref Config config, string fileName)
+ {
+ string newFileName = string.Empty;
+ newFileName = string.Format("{0}.json", Utils.GetGUID());
+ newFileName = Path.Combine(Utils.GetTempPath(), newFileName);
+
+ try
+ {
+ File.Copy(fileName, newFileName);
+ }
+ catch
+ {
+ return -1;
+ }
+
+ VmessItem vmessItem = new VmessItem();
+ vmessItem.address = newFileName;
+ vmessItem.configType = (int)EConfigType.Custom;
+ vmessItem.remarks = string.Format("import custom@{0}", DateTime.Now.ToShortDateString());
+
+ config.vmess.Add(vmessItem);
+ if (config.vmess.Count == 1)
+ {
+ config.index = 0;
+ Global.reloadV2ray = true;
+ }
+
+ ToJsonFile(config);
+
+ return 0;
+ }
+
+ ///
+ /// 添加服务器或编辑
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int EditCustomServer(ref Config config, VmessItem vmessItem, int index)
+ {
+ //修改
+ config.vmess[index] = vmessItem;
+ if (config.index.Equals(index))
+ {
+ Global.reloadV2ray = true;
+ }
+
+ ToJsonFile(config);
+
+ return 0;
+ }
+
+ ///
+ /// 添加服务器或编辑
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int AddShadowsocksServer(ref Config config, VmessItem vmessItem, int index)
+ {
+ vmessItem.configVersion = 2;
+ vmessItem.configType = (int)EConfigType.Shadowsocks;
+
+ vmessItem.address = vmessItem.address.TrimEx();
+ vmessItem.id = vmessItem.id.TrimEx();
+ vmessItem.security = vmessItem.security.TrimEx();
+
+ if (index >= 0)
+ {
+ //修改
+ config.vmess[index] = vmessItem;
+ if (config.index.Equals(index))
+ {
+ Global.reloadV2ray = true;
+ }
+ }
+ else
+ {
+ //添加
+ config.vmess.Add(vmessItem);
+ if (config.vmess.Count == 1)
+ {
+ config.index = 0;
+ Global.reloadV2ray = true;
+ }
+ }
+
+ ToJsonFile(config);
+
+ return 0;
+ }
+
+ ///
+ /// 添加服务器或编辑
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int AddSocksServer(ref Config config, VmessItem vmessItem, int index)
+ {
+ vmessItem.configVersion = 2;
+ vmessItem.configType = (int)EConfigType.Socks;
+
+ vmessItem.address = vmessItem.address.TrimEx();
+
+ if (index >= 0)
+ {
+ //修改
+ config.vmess[index] = vmessItem;
+ if (config.index.Equals(index))
+ {
+ Global.reloadV2ray = true;
+ }
+ }
+ else
+ {
+ //添加
+ config.vmess.Add(vmessItem);
+ if (config.vmess.Count == 1)
+ {
+ config.index = 0;
+ Global.reloadV2ray = true;
+ }
+ }
+
+ ToJsonFile(config);
+
+ return 0;
+ }
+
+ ///
+ /// 配置文件版本升级
+ ///
+ ///
+ ///
+ public static int UpgradeServerVersion(ref VmessItem vmessItem)
+ {
+ try
+ {
+ if (vmessItem == null
+ || vmessItem.configVersion == 2)
+ {
+ return 0;
+ }
+ if (vmessItem.configType == (int)EConfigType.Vmess)
+ {
+ string path = "";
+ string host = "";
+ string[] arrParameter;
+ switch (vmessItem.network)
+ {
+ case "kcp":
+ break;
+ case "ws":
+ //*ws(path+host),它们中间分号(;)隔开
+ arrParameter = vmessItem.requestHost.Replace(" ", "").Split(';');
+ if (arrParameter.Length > 0)
+ {
+ path = arrParameter[0];
+ }
+ if (arrParameter.Length > 1)
+ {
+ path = arrParameter[0];
+ host = arrParameter[1];
+ }
+ vmessItem.path = path;
+ vmessItem.requestHost = host;
+ break;
+ case "h2":
+ //*h2 path
+ arrParameter = vmessItem.requestHost.Replace(" ", "").Split(';');
+ if (arrParameter.Length > 0)
+ {
+ path = arrParameter[0];
+ }
+ if (arrParameter.Length > 1)
+ {
+ path = arrParameter[0];
+ host = arrParameter[1];
+ }
+ vmessItem.path = path;
+ vmessItem.requestHost = host;
+ break;
+ default:
+ break;
+ }
+ }
+ vmessItem.configVersion = 2;
+ }
+ catch
+ {
+ }
+ return 0;
+ }
+
+ ///
+ /// 批量添加服务器
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int AddBatchServers(ref Config config, string clipboardData, string subid = "")
+ {
+ if (Utils.IsNullOrEmpty(clipboardData))
+ {
+ return -1;
+ }
+ //if (clipboardData.IndexOf("vmess") >= 0 && clipboardData.IndexOf("vmess") == clipboardData.LastIndexOf("vmess"))
+ //{
+ // clipboardData = clipboardData.Replace("\r\n", "").Replace("\n", "");
+ //}
+ int countServers = 0;
+
+ //string[] arrData = clipboardData.Split(new string[] { "\r\n" }, StringSplitOptions.None);
+ string[] arrData = clipboardData.Split(Environment.NewLine.ToCharArray());
+ foreach (string str in arrData)
+ {
+ string msg;
+ //maybe sub
+ if (str.StartsWith(Global.httpsProtocol) || str.StartsWith(Global.httpProtocol))
+ {
+ if (AddSubItem(ref config, str) == 0)
+ {
+ countServers++;
+ }
+ continue;
+ }
+ VmessItem vmessItem = V2rayConfigHandler.ImportFromClipboardConfig(str, out msg);
+ if (vmessItem == null)
+ {
+ continue;
+ }
+ vmessItem.subid = subid;
+ if (vmessItem.configType == (int)EConfigType.Vmess)
+ {
+ if (AddServer(ref config, vmessItem, -1) == 0)
+ {
+ countServers++;
+ }
+ }
+ else if (vmessItem.configType == (int)EConfigType.Shadowsocks)
+ {
+ if (AddShadowsocksServer(ref config, vmessItem, -1) == 0)
+ {
+ countServers++;
+ }
+ }
+ else if (vmessItem.configType == (int)EConfigType.Socks)
+ {
+ if (AddSocksServer(ref config, vmessItem, -1) == 0)
+ {
+ countServers++;
+ }
+ }
+ }
+ if (countServers > 0)
+ {
+ return 0;
+ }
+ return -1;
+ }
+
+ ///
+ /// add sub
+ ///
+ ///
+ ///
+ ///
+ public static int AddSubItem(ref Config config, string url)
+ {
+ //already exists
+ foreach (var sub in config.subItem)
+ {
+ if (url == sub.url)
+ {
+ return 0;
+ }
+ }
+
+ var subItem = new SubItem();
+ subItem.id = string.Empty;
+ subItem.remarks = "import sub";
+ subItem.url = url;
+ config.subItem.Add(subItem);
+
+ return SaveSubItem(ref config);
+ }
+
+ ///
+ /// save sub
+ ///
+ ///
+ ///
+ public static int SaveSubItem(ref Config config)
+ {
+ if (config.subItem == null || config.subItem.Count <= 0)
+ {
+ return -1;
+ }
+
+ foreach (SubItem sub in config.subItem)
+ {
+ if (Utils.IsNullOrEmpty(sub.id))
+ {
+ sub.id = Utils.GetGUID();
+ }
+ }
+
+ ToJsonFile(config);
+ return 0;
+ }
+
+ ///
+ /// 移除服务器
+ ///
+ ///
+ ///
+ ///
+ public static int RemoveServerViaSubid(ref Config config, string subid)
+ {
+ if (Utils.IsNullOrEmpty(subid) || config.vmess.Count <= 0)
+ {
+ return -1;
+ }
+ for (int k = config.vmess.Count - 1; k >= 0; k--)
+ {
+ if (config.vmess[k].subid.Equals(subid))
+ {
+ config.vmess.RemoveAt(k);
+ }
+ }
+
+ ToJsonFile(config);
+ return 0;
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/Handler/ProxySetting.cs b/v2rayN/v2rayN/Handler/ProxySetting.cs
new file mode 100644
index 00000000..ec43bce1
--- /dev/null
+++ b/v2rayN/v2rayN/Handler/ProxySetting.cs
@@ -0,0 +1,190 @@
+using System;
+using Microsoft.Win32;
+using System.Runtime.InteropServices;
+
+namespace v2rayN.Handler
+{
+ ///
+ /// 设置系统代理类
+ ///
+ class ProxySetting
+ {
+ public static bool UnsetProxy()
+ {
+ return SetProxy(null, null);
+ }
+ public static bool SetProxy(string strProxy)
+ {
+ return SetProxy(strProxy, null);
+ }
+
+ public static bool SetProxy(string strProxy, string exceptions)
+ {
+ InternetPerConnOptionList list = new InternetPerConnOptionList();
+
+ int optionCount = string.IsNullOrEmpty(strProxy) ? 1 : (string.IsNullOrEmpty(exceptions) ? 2 : 3);
+ InternetConnectionOption[] options = new InternetConnectionOption[optionCount];
+ // USE a proxy server ...
+ options[0].m_Option = PerConnOption.INTERNET_PER_CONN_FLAGS;
+ options[0].m_Value.m_Int = (int)((optionCount < 2) ? PerConnFlags.PROXY_TYPE_DIRECT : (PerConnFlags.PROXY_TYPE_DIRECT | PerConnFlags.PROXY_TYPE_PROXY));
+ // use THIS proxy server
+ if (optionCount > 1)
+ {
+ options[1].m_Option = PerConnOption.INTERNET_PER_CONN_PROXY_SERVER;
+ options[1].m_Value.m_StringPtr = Marshal.StringToHGlobalAuto(strProxy);
+ // except for these addresses ...
+ if (optionCount > 2)
+ {
+ options[2].m_Option = PerConnOption.INTERNET_PER_CONN_PROXY_BYPASS;
+ options[2].m_Value.m_StringPtr = Marshal.StringToHGlobalAuto(exceptions);
+ }
+ }
+
+ // default stuff
+ list.dwSize = Marshal.SizeOf(list);
+ list.szConnection = IntPtr.Zero;
+ list.dwOptionCount = options.Length;
+ list.dwOptionError = 0;
+
+
+ int optSize = Marshal.SizeOf(typeof(InternetConnectionOption));
+ // make a pointer out of all that ...
+ IntPtr optionsPtr = Marshal.AllocCoTaskMem(optSize * options.Length);
+ // copy the array over into that spot in memory ...
+ for (int i = 0; i < options.Length; ++i)
+ {
+ IntPtr opt = new IntPtr(optionsPtr.ToInt32() + (i * optSize));
+ Marshal.StructureToPtr(options[i], opt, false);
+ }
+
+ list.options = optionsPtr;
+
+ // and then make a pointer out of the whole list
+ IntPtr ipcoListPtr = Marshal.AllocCoTaskMem((Int32)list.dwSize);
+ Marshal.StructureToPtr(list, ipcoListPtr, false);
+
+ // and finally, call the API method!
+ int returnvalue = NativeMethods.InternetSetOption(IntPtr.Zero,
+ InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION,
+ ipcoListPtr, list.dwSize) ? -1 : 0;
+ if (returnvalue == 0)
+ { // get the error codes, they might be helpful
+ returnvalue = Marshal.GetLastWin32Error();
+ }
+ // FREE the data ASAP
+ Marshal.FreeCoTaskMem(optionsPtr);
+ Marshal.FreeCoTaskMem(ipcoListPtr);
+ if (returnvalue > 0)
+ { // throw the error codes, they might be helpful
+ //throw new Win32Exception(Marshal.GetLastWin32Error());
+ }
+
+ return (returnvalue < 0);
+ }
+
+
+ #region WinInet structures
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public struct InternetPerConnOptionList
+ {
+ public int dwSize; // size of the INTERNET_PER_CONN_OPTION_LIST struct
+ public IntPtr szConnection; // connection name to set/query options
+ public int dwOptionCount; // number of options to set/query
+ public int dwOptionError; // on error, which option failed
+ //[MarshalAs(UnmanagedType.)]
+ public IntPtr options;
+ };
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public struct InternetConnectionOption
+ {
+ static readonly int Size;
+ public PerConnOption m_Option;
+ public InternetConnectionOptionValue m_Value;
+ static InternetConnectionOption()
+ {
+ InternetConnectionOption.Size = Marshal.SizeOf(typeof(InternetConnectionOption));
+ }
+
+ // Nested Types
+ [StructLayout(LayoutKind.Explicit)]
+ public struct InternetConnectionOptionValue
+ {
+ // Fields
+ [FieldOffset(0)]
+ public System.Runtime.InteropServices.ComTypes.FILETIME m_FileTime;
+ [FieldOffset(0)]
+ public int m_Int;
+ [FieldOffset(0)]
+ public IntPtr m_StringPtr;
+ }
+ }
+ #endregion
+
+ #region WinInet enums
+ //
+ // options manifests for Internet{Query|Set}Option
+ //
+ public enum InternetOption : uint
+ {
+ INTERNET_OPTION_PER_CONNECTION_OPTION = 75
+ }
+
+ //
+ // Options used in INTERNET_PER_CONN_OPTON struct
+ //
+ public enum PerConnOption
+ {
+ INTERNET_PER_CONN_FLAGS = 1, // Sets or retrieves the connection type. The Value member will contain one or more of the values from PerConnFlags
+ INTERNET_PER_CONN_PROXY_SERVER = 2, // Sets or retrieves a string containing the proxy servers.
+ INTERNET_PER_CONN_PROXY_BYPASS = 3, // Sets or retrieves a string containing the URLs that do not use the proxy server.
+ INTERNET_PER_CONN_AUTOCONFIG_URL = 4//, // Sets or retrieves a string containing the URL to the automatic configuration script.
+
+ }
+
+ //
+ // PER_CONN_FLAGS
+ //
+ [Flags]
+ public enum PerConnFlags
+ {
+ PROXY_TYPE_DIRECT = 0x00000001, // direct to net
+ PROXY_TYPE_PROXY = 0x00000002, // via named proxy
+ PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, // autoproxy URL
+ PROXY_TYPE_AUTO_DETECT = 0x00000008 // use autoproxy detection
+ }
+ #endregion
+
+ internal static class NativeMethods
+ {
+ [DllImport("WinInet.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool InternetSetOption(IntPtr hInternet, InternetOption dwOption, IntPtr lpBuffer, int dwBufferLength);
+ }
+
+ //判断是否使用代理
+ public static bool UsedProxy()
+ {
+ RegistryKey rk = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings", true);
+ if (rk.GetValue("ProxyEnable").ToString() == "1")
+ {
+ rk.Close();
+ return true;
+ }
+ else
+ {
+ rk.Close();
+ return false;
+ }
+ }
+ //获得代理的IP和端口
+ public static string GetProxyProxyServer()
+ {
+ RegistryKey rk = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings", true);
+ string ProxyServer = rk.GetValue("ProxyServer").ToString();
+ rk.Close();
+ return ProxyServer;
+
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/Handler/QRCodeHelper.cs b/v2rayN/v2rayN/Handler/QRCodeHelper.cs
new file mode 100644
index 00000000..e5433dec
--- /dev/null
+++ b/v2rayN/v2rayN/Handler/QRCodeHelper.cs
@@ -0,0 +1,41 @@
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using ZXing;
+using ZXing.QrCode;
+
+namespace v2rayN.Handler
+{
+ ///
+ /// 含有QR码的描述类和包装编码和渲染
+ ///
+ public class QRCodeHelper
+ {
+ public static Image GetQRCode(string strContent)
+ {
+ Image img = null;
+ try
+ {
+ QrCodeEncodingOptions options = new QrCodeEncodingOptions();
+ options.CharacterSet = "UTF-8";
+ options.DisableECI = true; // Extended Channel Interpretation (ECI) 主要用于特殊的字符集。并不是所有的扫描器都支持这种编码。
+ options.ErrorCorrection = ZXing.QrCode.Internal.ErrorCorrectionLevel.M; // 纠错级别
+ options.Width = 500;
+ options.Height = 500;
+ options.Margin = 1;
+ // options.Hints,更多属性,也可以在这里添加。
+
+ BarcodeWriter writer = new BarcodeWriter();
+ writer.Format = BarcodeFormat.QR_CODE;
+ writer.Options = options;
+ Bitmap bmp = writer.Write(strContent);
+ img = (Image)bmp;
+ return img;
+ }
+ catch
+ {
+ return img;
+ }
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/Handler/RoutingRuleHandler.cs b/v2rayN/v2rayN/Handler/RoutingRuleHandler.cs
new file mode 100644
index 00000000..57d4f564
--- /dev/null
+++ b/v2rayN/v2rayN/Handler/RoutingRuleHandler.cs
@@ -0,0 +1,53 @@
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+
+namespace v2rayN.Handler
+{
+ ///
+ /// 路由规则文件处理类
+ ///
+ class RoutingRuleHandler
+ {
+ ///
+ /// Parse Pac to v2ray rule
+ ///
+ ///
+ ///
+ public static List ParsePac(string filePath)
+ {
+ string result = Utils.LoadResource(filePath);
+ if (Utils.IsNullOrEmpty(result))
+ {
+ return null;
+ }
+
+ //取得rule
+ string pattern = @"(?is)(?<=\[)(.*)(?=\])";
+ Regex rgx = new Regex(pattern);
+ result = rgx.Match(result).Value;
+ int index = result.IndexOf("];");
+ result = result.Substring(0, index);
+ if (Utils.IsNullOrEmpty(result))
+ {
+ return null;
+ }
+
+ string[] arrPac = result.Split(',');
+ List lstPac = new List();
+ foreach (string str in arrPac)
+ {
+ //处理有效值
+ if (Utils.IsNullOrEmpty(str)
+ || str.Length <= 3)
+ {
+ continue;
+ }
+ string value = str.Replace("\",", "").Replace("\"", "").Replace(",", "").Replace("\r\n", "").Replace(" ", "");
+ lstPac.Add(value);
+ }
+
+ return lstPac;
+ }
+
+ }
+}
diff --git a/v2rayN/v2rayN/Handler/SpeedtestHandler.cs b/v2rayN/v2rayN/Handler/SpeedtestHandler.cs
new file mode 100644
index 00000000..f96dd00d
--- /dev/null
+++ b/v2rayN/v2rayN/Handler/SpeedtestHandler.cs
@@ -0,0 +1,305 @@
+using Grpc.Core;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+using v2rayN.Mode;
+
+namespace v2rayN.Handler
+{
+ class SpeedtestHandler
+ {
+ private V2rayUpdateHandle v2rayUpdateHandle2;
+ private Config _config;
+ private V2rayHandler _v2rayHandler;
+ private List _selecteds;
+ private Thread _workThread;
+ Action _updateFunc;
+
+ private int testCounter = 0;
+ private int ItemIndex
+ {
+ get
+ {
+ return _selecteds[testCounter - 1];
+ }
+ }
+
+ public SpeedtestHandler(ref Config config, ref V2rayHandler v2rayHandler, List selecteds, string actionType, Action update)
+ {
+ _config = config;
+ _v2rayHandler = v2rayHandler;
+ _selecteds = selecteds;
+ _updateFunc = update;
+
+ if (actionType == "ping")
+ {
+ _workThread = new Thread(new ThreadStart(RunPing));
+ _workThread.Start();
+ }
+ if (actionType == "tcping")
+ {
+ _workThread = new Thread(new ThreadStart(RunTcping));
+ _workThread.Start();
+ }
+ else if (actionType == "realping")
+ {
+ _workThread = new Thread(new ThreadStart(RunRealPing));
+ _workThread.Start();
+ }
+ else if (actionType == "speedtest")
+ {
+ RunSpeedTest();
+ }
+ }
+
+ public void Close()
+ {
+ try
+ {
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ public void RunPing()
+ {
+ try
+ {
+ for (int k = 0; k < _selecteds.Count; k++)
+ {
+ int index = _selecteds[k];
+ if (_config.vmess[index].configType == (int)EConfigType.Custom)
+ {
+ continue;
+ }
+ try
+ {
+ long time = Utils.Ping(_config.vmess[index].address);
+ _updateFunc(index, string.Format("{0}ms", time));
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ Thread.Sleep(1);
+
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ public void RunTcping()
+ {
+ try
+ {
+ for (int k = 0; k < _selecteds.Count; k++)
+ {
+ int index = _selecteds[k];
+ if (_config.vmess[index].configType == (int)EConfigType.Custom)
+ {
+ continue;
+ }
+ try
+ {
+ var time = GetTcpingTime(_config.vmess[index].address, _config.vmess[index].port);
+ _updateFunc(index, string.Format("{0}ms", time));
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ Thread.Sleep(1);
+
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ public void RunRealPing()
+ {
+ try
+ {
+ for (int k = 0; k < _selecteds.Count; k++)
+ {
+ int index = _selecteds[k];
+ if (_config.vmess[index].configType == (int)EConfigType.Custom)
+ {
+ continue;
+ }
+ try
+ {
+ if (ConfigHandler.SetDefaultServer(ref _config, index) == 0)
+ {
+ _v2rayHandler.LoadV2ray(_config);
+ }
+ else
+ {
+ return;
+ }
+ Thread.Sleep(1000 * 5);
+
+ int responseTime = -1;
+ var status = GetRealPingTime(Global.SpeedPingTestUrl, out responseTime);
+ if (!Utils.IsNullOrEmpty(status))
+ {
+ _updateFunc(index, string.Format("{0}", status));
+ }
+ else
+ {
+ _updateFunc(index, string.Format("{0}ms", responseTime));
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ Thread.Sleep(1);
+
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ private void RunSpeedTest()
+ {
+ if (_config.vmess.Count <= 0)
+ {
+ return;
+ }
+
+ string url = Global.SpeedTestUrl;
+ testCounter = 0;
+ if (v2rayUpdateHandle2 == null)
+ {
+ v2rayUpdateHandle2 = new V2rayUpdateHandle();
+ v2rayUpdateHandle2.UpdateCompleted += (sender2, args) =>
+ {
+ if (args.Success)
+ {
+ _updateFunc(ItemIndex, args.Msg);
+ if (ServerSpeedTestSub(testCounter, url) != 0)
+ {
+ return;
+ }
+ }
+ else
+ {
+ _updateFunc(ItemIndex, args.Msg);
+ }
+ };
+ v2rayUpdateHandle2.Error += (sender2, args) =>
+ {
+ _updateFunc(ItemIndex, args.GetException().Message);
+ if (ServerSpeedTestSub(testCounter, url) != 0)
+ {
+ return;
+ }
+ };
+ }
+ if (ServerSpeedTestSub(testCounter, url) != 0)
+ {
+ return;
+ }
+ }
+
+ private int ServerSpeedTestSub(int index, string url)
+ {
+ if (index >= _selecteds.Count)
+ {
+ return -1;
+ }
+
+ if (ConfigHandler.SetDefaultServer(ref _config, _selecteds[index]) == 0)
+ {
+ _v2rayHandler.LoadV2ray(_config);
+
+ testCounter++;
+
+ v2rayUpdateHandle2.DownloadFileAsync(_config, url);
+
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ private int GetTcpingTime(string url, int port)
+ {
+ var responseTime = -1;
+
+ try
+ {
+ IPHostEntry ipHostInfo = System.Net.Dns.Resolve(url);
+ IPAddress ipAddress = ipHostInfo.AddressList[0];
+
+ var timer = new Stopwatch();
+ timer.Start();
+
+ Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ clientSocket.Connect(new IPEndPoint(ipAddress, port));
+ timer.Stop();
+ responseTime = timer.Elapsed.Milliseconds;
+ clientSocket.Close();
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ return responseTime;
+ }
+
+ private string GetRealPingTime(string url, out int responseTime)
+ {
+ string msg = string.Empty;
+ responseTime = -1;
+
+ try
+ {
+ HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
+ myHttpWebRequest.Timeout = 5000;
+
+ var timer = new Stopwatch();
+ timer.Start();
+
+ HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
+ if (myHttpWebResponse.StatusCode != HttpStatusCode.OK
+ && myHttpWebResponse.StatusCode != HttpStatusCode.NoContent)
+ {
+ msg = myHttpWebResponse.StatusDescription;
+ }
+ timer.Stop();
+ responseTime = timer.Elapsed.Milliseconds;
+
+ myHttpWebResponse.Close();
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ msg = ex.Message;
+ }
+ return msg;
+
+ }
+
+
+ }
+}
diff --git a/v2rayN/v2rayN/Handler/StatisticsHandler.cs b/v2rayN/v2rayN/Handler/StatisticsHandler.cs
new file mode 100644
index 00000000..766d4021
--- /dev/null
+++ b/v2rayN/v2rayN/Handler/StatisticsHandler.cs
@@ -0,0 +1,446 @@
+using Grpc.Core;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+using v2rayN.Mode;
+using v2rayN.Protos.Statistics;
+
+namespace v2rayN.Handler
+{
+ class StatisticsHandler
+ {
+ private Mode.Config config_;
+
+ private Channel channel_;
+ private StatsService.StatsServiceClient client_;
+ private Thread workThread_;
+
+ Action> updateFunc_;
+
+ private bool enabled_;
+ public bool Enable
+ {
+ get
+ {
+ return enabled_;
+ }
+ set
+ {
+ enabled_ = value;
+ }
+ }
+
+ public bool UpdateUI;
+
+ public ulong TotalUp
+ {
+ get; private set;
+ }
+
+ public ulong TotalDown
+ {
+ get; private set;
+ }
+
+ public List Statistic
+ {
+ get; set;
+ }
+
+ public ulong Up
+ {
+ get; private set;
+ }
+
+ public ulong Down
+ {
+ get; private set;
+ }
+
+ private string logPath_;
+
+ private bool exitFlag_; // true to close workThread_
+
+ public StatisticsHandler(Mode.Config config, Action> update)
+ {
+ config_ = config;
+ enabled_ = config.enableStatistics;
+ UpdateUI = false;
+ updateFunc_ = update;
+ logPath_ = Utils.GetPath(Global.StatisticLogDirectory);
+ Statistic = new List();
+ exitFlag_ = false;
+
+ DeleteExpiredLog();
+ foreach (var server in config.vmess)
+ {
+ var statistic = new ServerStatistics(server.remarks, server.address, server.port, server.path, server.requestHost, 0, 0, 0, 0);
+ Statistic.Add(statistic);
+ }
+
+ LoadFromFile();
+
+ GrpcInit();
+
+ workThread_ = new Thread(new ThreadStart(Run));
+ workThread_.Start();
+ }
+
+ private void GrpcInit()
+ {
+ if (channel_ == null)
+ {
+ Global.statePort = GetFreePort();
+
+ channel_ = new Channel($"127.0.0.1:{Global.statePort}", ChannelCredentials.Insecure);
+ channel_.ConnectAsync();
+ client_ = new StatsService.StatsServiceClient(channel_);
+ }
+ }
+
+ public void Close()
+ {
+ try
+ {
+
+ exitFlag_ = true;
+ channel_.ShutdownAsync();
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ public void Run()
+ {
+ while (!exitFlag_)
+ {
+ try
+ {
+ if (enabled_ && channel_.State == ChannelState.Ready)
+ {
+ QueryStatsResponse res = null;
+ try
+ {
+ res = client_.QueryStats(new QueryStatsRequest() { Pattern = "", Reset = true });
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+
+ if (res != null)
+ {
+ var addr = config_.address();
+ var port = config_.port();
+ var path = config_.path();
+ var cur = Statistic.FindIndex(item => item.address == addr && item.port == port && item.path == path);
+ ulong up = 0,
+ down = 0;
+
+ //TODO: parse output
+ ParseOutput(res.Stat, out up, out down);
+
+ Up = up;
+ Down = down;
+
+ TotalUp += up;
+ TotalDown += down;
+
+ if (cur != -1)
+ {
+ Statistic[cur].todayUp += up;
+ Statistic[cur].todayDown += down;
+ Statistic[cur].totalUp += up;
+ Statistic[cur].totalDown += down;
+ }
+
+ if (UpdateUI)
+ updateFunc_(TotalUp, TotalDown, Up, Down, Statistic);
+ }
+ }
+ Thread.Sleep(config_.statisticsFreshRate);
+ channel_.ConnectAsync();
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+ }
+
+ public void ParseOutput(Google.Protobuf.Collections.RepeatedField source, out ulong up, out ulong down)
+ {
+
+ up = 0; down = 0;
+ try
+ {
+
+ foreach (var stat in source)
+ {
+ var name = stat.Name;
+ var value = stat.Value;
+ var nStr = name.Split(">>>".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
+ var type = "";
+
+ name = name.Trim();
+
+ name = nStr[1];
+ type = nStr[3];
+
+ if (name == Global.InboundProxyTagName)
+ {
+ if (type == "uplink")
+ {
+ up = (ulong)value;
+ }
+ else if (type == "downlink")
+ {
+ down = (ulong)value;
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ public void SaveToFile()
+ {
+ if (!Directory.Exists(logPath_))
+ {
+ Directory.CreateDirectory(logPath_);
+ }
+
+ // 总流量统计文件
+ var overallPath = Path.Combine(logPath_, Global.StatisticLogOverall);
+ if (!File.Exists(overallPath))
+ {
+ File.Create(overallPath);
+ }
+ try
+ {
+ using (var overallWriter = new StreamWriter(overallPath))
+ {
+ double up_amount, down_amount;
+ string up_unit, down_unit;
+
+ Utils.ToHumanReadable(TotalUp, out up_amount, out up_unit);
+ Utils.ToHumanReadable(TotalDown, out down_amount, out down_unit);
+
+ overallWriter.WriteLine($"LastUpdate {DateTime.Now.ToString("yyyy-MM-dd")} {DateTime.Now.ToLongTimeString()}");
+ overallWriter.WriteLine($"UP {string.Format("{0:f2}", up_amount)}{up_unit} {TotalUp}");
+ overallWriter.WriteLine($"DOWN {string.Format("{0:f2}", down_amount)}{down_unit} {TotalDown}");
+ foreach (var s in Statistic)
+ {
+ overallWriter.WriteLine($"* {s.name} {s.address} {s.port} {s.path} {s.host} {s.totalUp} {s.totalDown}");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+
+ // 当天流量记录文件
+ var dailyPath = Path.Combine(logPath_, $"{DateTime.Now.ToString("yyyy-MM-dd")}.txt");
+ if (!File.Exists(dailyPath))
+ {
+ File.Create(dailyPath);
+ }
+ try
+ {
+ using (var dailyWriter = new StreamWriter(dailyPath))
+ {
+ dailyWriter.WriteLine($"LastUpdate {DateTime.Now.ToString("yyyy-MM-dd")} {DateTime.Now.ToLongTimeString()}");
+ foreach (var s in Statistic)
+ {
+ dailyWriter.WriteLine($"* {s.name} {s.address} {s.port} {s.path} {s.host} {s.todayUp} {s.todayDown}");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ public void LoadFromFile()
+ {
+ if (!Directory.Exists(logPath_)) return;
+
+ // 总流量统计文件
+ ///
+ /// 文件结构
+ /// LastUpdate [date] [time]
+ /// UP [readable string] [amount]
+ /// DOWN [readable string] [amount]
+ /// 每行每个数据空格分隔
+
+ try
+ {
+ Utils.SaveLog(logPath_ + Global.StatisticLogOverall);
+ var overallPath = Path.Combine(logPath_, Global.StatisticLogOverall);
+ if (File.Exists(overallPath))
+ {
+ using (var overallReader = new StreamReader(overallPath))
+ {
+ while (!overallReader.EndOfStream)
+ {
+ var line = overallReader.ReadLine();
+ if (line.StartsWith("LastUpdate"))
+ {
+
+ }
+ else if (line.StartsWith("UP"))
+ {
+ var datas = line.Split(' ');
+ if (datas.Length < 3) return;
+ TotalUp = ulong.Parse(datas[2]);
+ }
+ else if (line.StartsWith("DOWN"))
+ {
+ var datas = line.Split(' ');
+ if (datas.Length < 3) return;
+ TotalDown = ulong.Parse(datas[2]);
+ }
+ else if (line.StartsWith("*"))
+ {
+ var datas = line.Split(' ');
+ if (datas.Length < 8) return;
+ var name = datas[1];
+ var address = datas[2];
+ var port = int.Parse(datas[3]);
+ var path = datas[4];
+ var host = datas[5];
+ var totalUp = ulong.Parse(datas[6]);
+ var totalDown = ulong.Parse(datas[7]);
+
+ var temp = new ServerStatistics(name, address, port, path, host, 0, 0, 0, 0);
+ var index = Statistic.FindIndex(item => Utils.IsIdenticalServer(item, temp));
+ if (index != -1)
+ {
+ Statistic[index].totalUp = totalUp;
+ Statistic[index].totalDown = totalDown;
+ }
+ else
+ {
+ var s = new Mode.ServerStatistics(name, address, port, path, host, totalUp, totalDown, 0, 0);
+ Statistic.Add(s);
+ }
+ }
+ }
+
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+
+ try
+ {
+ Utils.SaveLog(logPath_ + $"{DateTime.Now.ToString("yyyy-MM-dd")}.txt");
+ var dailyPath = Path.Combine(logPath_, $"{DateTime.Now.ToString("yyyy-MM-dd")}.txt");
+ if (File.Exists(dailyPath))
+ {
+
+ using (var dailyReader = new StreamReader(dailyPath))
+ {
+ while (!dailyReader.EndOfStream)
+ {
+ var line = dailyReader.ReadLine();
+ if (line.StartsWith("LastUpdate"))
+ {
+
+ }
+ else if (line.StartsWith("*"))
+ {
+ var datas = line.Split(' ');
+ if (datas.Length < 8) return;
+ var name = datas[1];
+ var address = datas[2];
+ var port = int.Parse(datas[3]);
+ var path = datas[4];
+ var host = datas[5];
+ var todayUp = ulong.Parse(datas[6]);
+ var todayDown = ulong.Parse(datas[7]);
+
+ var temp = new ServerStatistics(name, address, port, path, host, 0, 0, 0, 0);
+ var index = Statistic.FindIndex(item => Utils.IsIdenticalServer(item, temp));
+ if (index != -1)
+ {
+ Statistic[index].todayUp = todayUp;
+ Statistic[index].todayDown = todayDown;
+ }
+ else
+ {
+ var s = new Mode.ServerStatistics(name, address, port, path, host, 0, 0, todayUp, todayDown);
+ Statistic.Add(s);
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+
+ private void DeleteExpiredLog()
+ {
+ try
+ {
+ if (!Directory.Exists(logPath_)) return;
+ var dirInfo = new DirectoryInfo(logPath_);
+ var files = dirInfo.GetFiles();
+ foreach (var file in files)
+ {
+ if (file.Name == "overall.txt") continue;
+ var name = file.Name.Split('.')[0];
+ var ft = DateTime.Parse(name);
+ var ct = DateTime.Now;
+ var dur = ct - ft;
+ if (dur.Days > config_.CacheDays)
+ {
+ file.Delete();
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ private int GetFreePort()
+ {
+ int defaultPort = 28123;
+ try
+ {
+ // TCP stack please do me a favor
+ TcpListener l = new TcpListener(IPAddress.Loopback, 0);
+ l.Start();
+ var port = ((IPEndPoint)l.LocalEndpoint).Port;
+ l.Stop();
+ return port;
+ }
+ catch (Exception ex)
+ {
+ // in case access denied
+ Utils.SaveLog(ex.Message, ex);
+ return defaultPort;
+ }
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/Handler/V2rayConfigHandler.cs b/v2rayN/v2rayN/Handler/V2rayConfigHandler.cs
new file mode 100644
index 00000000..712e8350
--- /dev/null
+++ b/v2rayN/v2rayN/Handler/V2rayConfigHandler.cs
@@ -0,0 +1,1369 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using v2rayN.Mode;
+using System.Net;
+using System.Text;
+using System.Linq;
+
+namespace v2rayN.Handler
+{
+ ///
+ /// v2ray配置文件处理类
+ ///
+ class V2rayConfigHandler
+ {
+ private static string SampleClient = Global.v2raySampleClient;
+ private static string SampleServer = Global.v2raySampleServer;
+
+ #region 生成客户端配置
+
+ ///
+ /// 生成v2ray的客户端配置文件
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int GenerateClientConfig(Config config, string fileName, bool blExport, out string msg)
+ {
+ msg = string.Empty;
+
+ try
+ {
+ //检查GUI设置
+ if (config == null
+ || config.index < 0
+ || config.vmess.Count <= 0
+ || config.index > config.vmess.Count - 1
+ )
+ {
+ msg = UIRes.I18N("CheckServerSettings");
+ return -1;
+ }
+
+ msg = UIRes.I18N("InitialConfiguration");
+ if (config.configType() == (int)EConfigType.Custom)
+ {
+ return GenerateClientCustomConfig(config, fileName, out msg);
+ }
+
+ //取得默认配置
+ string result = Utils.GetEmbedText(SampleClient);
+ if (Utils.IsNullOrEmpty(result))
+ {
+ msg = UIRes.I18N("FailedGetDefaultConfiguration");
+ return -1;
+ }
+
+ //转成Json
+ V2rayConfig v2rayConfig = Utils.FromJson(result);
+ if (v2rayConfig == null)
+ {
+ msg = UIRes.I18N("FailedGenDefaultConfiguration");
+ return -1;
+ }
+
+ //开始修改配置
+ log(config, ref v2rayConfig, blExport);
+
+ //本地端口
+ inbound(config, ref v2rayConfig);
+
+ //路由
+ routing(config, ref v2rayConfig);
+
+ //outbound
+ outbound(config, ref v2rayConfig);
+
+ //dns
+ dns(config, ref v2rayConfig);
+
+ // TODO: 统计配置
+ statistic(config, ref v2rayConfig);
+
+ Utils.ToJsonFile(v2rayConfig, fileName);
+
+ msg = string.Format(UIRes.I18N("SuccessfulConfiguration"), config.getSummary());
+ }
+ catch
+ {
+ msg = UIRes.I18N("FailedGenDefaultConfiguration");
+ return -1;
+ }
+ return 0;
+ }
+
+ ///
+ /// 日志
+ ///
+ ///
+ ///
+ ///
+ private static int log(Config config, ref V2rayConfig v2rayConfig, bool blExport)
+ {
+ try
+ {
+ if (blExport)
+ {
+ if (config.logEnabled)
+ {
+ v2rayConfig.log.loglevel = config.loglevel;
+ }
+ else
+ {
+ v2rayConfig.log.loglevel = config.loglevel;
+ v2rayConfig.log.access = "";
+ v2rayConfig.log.error = "";
+ }
+ }
+ else
+ {
+ if (config.logEnabled)
+ {
+ v2rayConfig.log.loglevel = config.loglevel;
+ v2rayConfig.log.access = Utils.GetPath(v2rayConfig.log.access);
+ v2rayConfig.log.error = Utils.GetPath(v2rayConfig.log.error);
+ }
+ else
+ {
+ v2rayConfig.log.loglevel = config.loglevel;
+ v2rayConfig.log.access = "";
+ v2rayConfig.log.error = "";
+ }
+ }
+ }
+ catch
+ {
+ }
+ return 0;
+ }
+
+ ///
+ /// 本地端口
+ ///
+ ///
+ ///
+ ///
+ private static int inbound(Config config, ref V2rayConfig v2rayConfig)
+ {
+ try
+ {
+ var inbound = v2rayConfig.inbounds[0];
+ //端口
+ inbound.port = config.inbound[0].localPort;
+ inbound.protocol = config.inbound[0].protocol;
+ if (config.allowLANConn)
+ {
+ inbound.listen = "0.0.0.0";
+ }
+ else
+ {
+ inbound.listen = "127.0.0.1";
+ }
+ //开启udp
+ inbound.settings.udp = config.inbound[0].udpEnabled;
+ inbound.sniffing.enabled = config.inbound[0].sniffingEnabled;
+ }
+ catch
+ {
+ }
+ return 0;
+ }
+
+ ///
+ /// 路由
+ ///
+ ///
+ ///
+ ///
+ private static int routing(Config config, ref V2rayConfig v2rayConfig)
+ {
+ try
+ {
+ if (v2rayConfig.routing != null
+ && v2rayConfig.routing.rules != null)
+ {
+ v2rayConfig.routing.domainStrategy = config.domainStrategy;
+
+ //自定义
+ //需代理
+ routingUserRule(config.useragent, Global.agentTag, ref v2rayConfig);
+ //直连
+ routingUserRule(config.userdirect, Global.directTag, ref v2rayConfig);
+ //阻止
+ routingUserRule(config.userblock, Global.blockTag, ref v2rayConfig);
+
+
+ switch (config.routingMode)
+ {
+ case "0":
+ break;
+ case "1":
+ routingGeo("ip", "private", Global.directTag, ref v2rayConfig);
+ break;
+ case "2":
+ routingGeo("", "cn", Global.directTag, ref v2rayConfig);
+ break;
+ case "3":
+ routingGeo("ip", "private", Global.directTag, ref v2rayConfig);
+ routingGeo("", "cn", Global.directTag, ref v2rayConfig);
+ break;
+ }
+
+ }
+ }
+ catch
+ {
+ }
+ return 0;
+ }
+ private static int routingUserRule(List userRule, string tag, ref V2rayConfig v2rayConfig)
+ {
+ try
+ {
+ if (userRule != null
+ && userRule.Count > 0)
+ {
+ //Domain
+ RulesItem rulesDomain = new RulesItem();
+ rulesDomain.type = "field";
+ rulesDomain.outboundTag = tag;
+ rulesDomain.domain = new List();
+
+ //IP
+ RulesItem rulesIP = new RulesItem();
+ rulesIP.type = "field";
+ rulesIP.outboundTag = tag;
+ rulesIP.ip = new List();
+
+ for (int k = 0; k < userRule.Count; k++)
+ {
+ string url = userRule[k].TrimEx();
+ if (Utils.IsNullOrEmpty(url))
+ {
+ continue;
+ }
+ if (Utils.IsIP(url) || url.StartsWith("geoip:"))
+ {
+ rulesIP.ip.Add(url);
+ }
+ else if (Utils.IsDomain(url)
+ || url.StartsWith("geosite:")
+ || url.StartsWith("regexp:")
+ || url.StartsWith("domain:")
+ || url.StartsWith("full:"))
+ {
+ rulesDomain.domain.Add(url);
+ }
+ }
+ if (rulesDomain.domain.Count > 0)
+ {
+ v2rayConfig.routing.rules.Add(rulesDomain);
+ }
+ if (rulesIP.ip.Count > 0)
+ {
+ v2rayConfig.routing.rules.Add(rulesIP);
+ }
+ }
+ }
+ catch
+ {
+ }
+ return 0;
+ }
+
+
+ private static int routingGeo(string ipOrDomain, string code, string tag, ref V2rayConfig v2rayConfig)
+ {
+ try
+ {
+ if (!Utils.IsNullOrEmpty(code))
+ {
+ //IP
+ if (ipOrDomain == "ip" || ipOrDomain == "")
+ {
+ RulesItem rulesItem = new RulesItem();
+ rulesItem.type = "field";
+ rulesItem.outboundTag = Global.directTag;
+ rulesItem.ip = new List();
+ rulesItem.ip.Add($"geoip:{code}");
+
+ v2rayConfig.routing.rules.Add(rulesItem);
+ }
+
+ if (ipOrDomain == "domain" || ipOrDomain == "")
+ {
+ RulesItem rulesItem = new RulesItem();
+ rulesItem.type = "field";
+ rulesItem.outboundTag = Global.directTag;
+ rulesItem.domain = new List();
+ rulesItem.domain.Add($"geosite:{code}");
+ v2rayConfig.routing.rules.Add(rulesItem);
+ }
+ }
+ }
+ catch
+ {
+ }
+ return 0;
+ }
+
+ ///
+ /// vmess协议服务器配置
+ ///
+ ///
+ ///
+ ///
+ private static int outbound(Config config, ref V2rayConfig v2rayConfig)
+ {
+ try
+ {
+ var outbound = v2rayConfig.outbounds[0];
+ if (config.configType() == (int)EConfigType.Vmess)
+ {
+ VnextItem vnextItem;
+ if (outbound.settings.vnext.Count <= 0)
+ {
+ vnextItem = new VnextItem();
+ outbound.settings.vnext.Add(vnextItem);
+ }
+ else
+ {
+ vnextItem = outbound.settings.vnext[0];
+ }
+ //远程服务器地址和端口
+ vnextItem.address = config.address();
+ vnextItem.port = config.port();
+
+ UsersItem usersItem;
+ if (vnextItem.users.Count <= 0)
+ {
+ usersItem = new UsersItem();
+ vnextItem.users.Add(usersItem);
+ }
+ else
+ {
+ usersItem = vnextItem.users[0];
+ }
+ //远程服务器用户ID
+ usersItem.id = config.id();
+ usersItem.alterId = config.alterId();
+ usersItem.email = Global.userEMail;
+ usersItem.security = config.security();
+
+ //Mux
+ outbound.mux.enabled = config.muxEnabled;
+
+ //远程服务器底层传输配置
+ StreamSettings streamSettings = outbound.streamSettings;
+ boundStreamSettings(config, "out", ref streamSettings);
+
+ outbound.protocol = "vmess";
+ outbound.settings.servers = null;
+ }
+ else if (config.configType() == (int)EConfigType.Shadowsocks)
+ {
+ ServersItem serversItem;
+ if (outbound.settings.servers.Count <= 0)
+ {
+ serversItem = new ServersItem();
+ outbound.settings.servers.Add(serversItem);
+ }
+ else
+ {
+ serversItem = outbound.settings.servers[0];
+ }
+ //远程服务器地址和端口
+ serversItem.address = config.address();
+ serversItem.port = config.port();
+ serversItem.password = config.id();
+ serversItem.method = config.security();
+
+ serversItem.ota = false;
+ serversItem.level = 1;
+
+ outbound.mux.enabled = false;
+
+ outbound.protocol = "shadowsocks";
+ outbound.settings.vnext = null;
+ }
+ else if (config.configType() == (int)EConfigType.Socks)
+ {
+ ServersItem serversItem;
+ if (outbound.settings.servers.Count <= 0)
+ {
+ serversItem = new ServersItem();
+ outbound.settings.servers.Add(serversItem);
+ }
+ else
+ {
+ serversItem = outbound.settings.servers[0];
+ }
+ //远程服务器地址和端口
+ serversItem.address = config.address();
+ serversItem.port = config.port();
+
+ if (!Utils.IsNullOrEmpty(config.security())
+ && !Utils.IsNullOrEmpty(config.id()))
+ {
+ var socksUsersItem = new SocksUsersItem();
+ socksUsersItem.user = config.security();
+ socksUsersItem.pass = config.id();
+ socksUsersItem.level = 1;
+
+ serversItem.users = new List() { socksUsersItem };
+ }
+
+ outbound.mux.enabled = false;
+
+ outbound.protocol = "socks";
+ outbound.settings.vnext = null;
+ }
+ }
+ catch
+ {
+ }
+ return 0;
+ }
+
+ ///
+ /// vmess协议远程服务器底层传输配置
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static int boundStreamSettings(Config config, string iobound, ref StreamSettings streamSettings)
+ {
+ try
+ {
+ //远程服务器底层传输配置
+ streamSettings.network = config.network();
+ var host = config.requestHost();
+
+ //if tls
+ if (config.streamSecurity() == Global.StreamSecurity)
+ {
+ streamSettings.security = config.streamSecurity();
+
+ TlsSettings tlsSettings = new TlsSettings();
+ tlsSettings.allowInsecure = config.allowInsecure();
+ if (!string.IsNullOrWhiteSpace(host))
+ {
+ tlsSettings.serverName = host;
+ }
+ streamSettings.tlsSettings = tlsSettings;
+ }
+
+ //streamSettings
+ switch (config.network())
+ {
+ //kcp基本配置暂时是默认值,用户能自己设置伪装类型
+ case "kcp":
+ KcpSettings kcpSettings = new KcpSettings();
+ kcpSettings.mtu = config.kcpItem.mtu;
+ kcpSettings.tti = config.kcpItem.tti;
+ if (iobound.Equals("out"))
+ {
+ kcpSettings.uplinkCapacity = config.kcpItem.uplinkCapacity;
+ kcpSettings.downlinkCapacity = config.kcpItem.downlinkCapacity;
+ }
+ else if (iobound.Equals("in"))
+ {
+ kcpSettings.uplinkCapacity = config.kcpItem.downlinkCapacity; ;
+ kcpSettings.downlinkCapacity = config.kcpItem.downlinkCapacity;
+ }
+ else
+ {
+ kcpSettings.uplinkCapacity = config.kcpItem.uplinkCapacity;
+ kcpSettings.downlinkCapacity = config.kcpItem.downlinkCapacity;
+ }
+
+ kcpSettings.congestion = config.kcpItem.congestion;
+ kcpSettings.readBufferSize = config.kcpItem.readBufferSize;
+ kcpSettings.writeBufferSize = config.kcpItem.writeBufferSize;
+ kcpSettings.header = new Header();
+ kcpSettings.header.type = config.headerType();
+ streamSettings.kcpSettings = kcpSettings;
+ break;
+ //ws
+ case "ws":
+ WsSettings wsSettings = new WsSettings();
+ wsSettings.connectionReuse = true;
+
+ string path = config.path();
+ if (!string.IsNullOrWhiteSpace(host))
+ {
+ wsSettings.headers = new Headers();
+ wsSettings.headers.Host = host;
+ }
+ if (!string.IsNullOrWhiteSpace(path))
+ {
+ wsSettings.path = path;
+ }
+ streamSettings.wsSettings = wsSettings;
+
+ //TlsSettings tlsSettings = new TlsSettings();
+ //tlsSettings.allowInsecure = config.allowInsecure();
+ //if (!string.IsNullOrWhiteSpace(host))
+ //{
+ // tlsSettings.serverName = host;
+ //}
+ //streamSettings.tlsSettings = tlsSettings;
+ break;
+ //h2
+ case "h2":
+ HttpSettings httpSettings = new HttpSettings();
+
+ if (!string.IsNullOrWhiteSpace(host))
+ {
+ httpSettings.host = Utils.String2List(host);
+ }
+ httpSettings.path = config.path();
+
+ streamSettings.httpSettings = httpSettings;
+
+ //TlsSettings tlsSettings2 = new TlsSettings();
+ //tlsSettings2.allowInsecure = config.allowInsecure();
+ //streamSettings.tlsSettings = tlsSettings2;
+ break;
+ //quic
+ case "quic":
+ QuicSettings quicsettings = new QuicSettings();
+ quicsettings.security = host;
+ quicsettings.key = config.path();
+ quicsettings.header = new Header();
+ quicsettings.header.type = config.headerType();
+
+ streamSettings.quicSettings = quicsettings;
+ break;
+ default:
+ //tcp带http伪装
+ if (config.headerType().Equals(Global.TcpHeaderHttp))
+ {
+ TcpSettings tcpSettings = new TcpSettings();
+ tcpSettings.connectionReuse = true;
+ tcpSettings.header = new Header();
+ tcpSettings.header.type = config.headerType();
+
+ if (iobound.Equals("out"))
+ {
+ //request填入自定义Host
+ string request = Utils.GetEmbedText(Global.v2raySampleHttprequestFileName);
+ string[] arrHost = host.Split(',');
+ string host2 = string.Join("\",\"", arrHost);
+ request = request.Replace("$requestHost$", string.Format("\"{0}\"", host2));
+ //request = request.Replace("$requestHost$", string.Format("\"{0}\"", config.requestHost()));
+
+ //填入自定义Path
+ string pathHttp = @"/";
+ if (!Utils.IsNullOrEmpty(config.path()))
+ {
+ string[] arrPath = config.path().Split(',');
+ pathHttp = string.Join("\",\"", arrPath);
+ }
+ request = request.Replace("$requestPath$", string.Format("\"{0}\"", pathHttp));
+ tcpSettings.header.request = Utils.FromJson(request);
+ }
+ else if (iobound.Equals("in"))
+ {
+ //string response = Utils.GetEmbedText(Global.v2raySampleHttpresponseFileName);
+ //tcpSettings.header.response = Utils.FromJson(response);
+ }
+
+ streamSettings.tcpSettings = tcpSettings;
+ }
+ break;
+ }
+ }
+ catch
+ {
+ }
+ return 0;
+ }
+
+ ///
+ /// remoteDNS
+ ///
+ ///
+ ///
+ ///
+ private static int dns(Config config, ref V2rayConfig v2rayConfig)
+ {
+ try
+ {
+ if (string.IsNullOrWhiteSpace(config.remoteDNS))
+ {
+ return 0;
+ }
+ List servers = new List();
+
+ string[] arrDNS = config.remoteDNS.Split(',');
+ foreach (string str in arrDNS)
+ {
+ //if (Utils.IsIP(str))
+ //{
+ servers.Add(str);
+ //}
+ }
+ //servers.Add("localhost");
+ v2rayConfig.dns = new Mode.Dns();
+ v2rayConfig.dns.servers = servers;
+ }
+ catch
+ {
+ }
+ return 0;
+ }
+
+ public static int statistic(Config config, ref V2rayConfig v2rayConfig)
+ {
+ if (config.enableStatistics)
+ {
+ var tag = Global.InboundAPITagName;
+ var apiObj = new Mode.API();
+ var policyObj = new Mode.Policy();
+ var policySystemSetting = new Mode.SystemPolicy();
+
+ string[] services = { "StatsService" };
+
+ v2rayConfig.stats = new Stats();
+
+ apiObj.tag = tag;
+ apiObj.services = services.ToList();
+ v2rayConfig.api = apiObj;
+
+ policySystemSetting.statsInboundDownlink = true;
+ policySystemSetting.statsInboundUplink = true;
+ policyObj.system = policySystemSetting;
+ v2rayConfig.policy = policyObj;
+
+ if (!v2rayConfig.inbounds.Exists(item => { return item.tag == tag; }))
+ {
+ var apiInbound = new Mode.Inbounds();
+ var apiInboundSettings = new Mode.Inboundsettings();
+ apiInbound.tag = tag;
+ apiInbound.listen = Global.Loopback;
+ apiInbound.port = Global.statePort;
+ apiInbound.protocol = Global.InboundAPIProtocal;
+ apiInboundSettings.address = Global.Loopback;
+ apiInbound.settings = apiInboundSettings;
+ v2rayConfig.inbounds.Add(apiInbound);
+ }
+
+ if (!v2rayConfig.routing.rules.Exists(item => { return item.outboundTag == tag; }))
+ {
+ var apiRoutingRule = new Mode.RulesItem();
+ apiRoutingRule.inboundTag = tag;
+ apiRoutingRule.outboundTag = tag;
+ apiRoutingRule.type = "field";
+ v2rayConfig.routing.rules.Add(apiRoutingRule);
+ }
+ }
+ return 0;
+ }
+
+ ///
+ /// 生成v2ray的客户端配置文件(自定义配置)
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int GenerateClientCustomConfig(Config config, string fileName, out string msg)
+ {
+ msg = string.Empty;
+
+ try
+ {
+ //检查GUI设置
+ if (config == null
+ || config.index < 0
+ || config.vmess.Count <= 0
+ || config.index > config.vmess.Count - 1
+ )
+ {
+ msg = UIRes.I18N("CheckServerSettings");
+ return -1;
+ }
+
+ string addressFileName = config.address();
+ if (File.Exists(fileName))
+ {
+ File.Delete(fileName);
+ }
+ File.Copy(addressFileName, fileName);
+
+ msg = string.Format(UIRes.I18N("SuccessfulConfiguration"), config.getSummary());
+ }
+ catch
+ {
+ msg = UIRes.I18N("FailedGenDefaultConfiguration");
+ return -1;
+ }
+ return 0;
+ }
+
+ #endregion
+
+ #region 生成服务端端配置
+
+ ///
+ /// 生成v2ray的客户端配置文件
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int GenerateServerConfig(Config config, string fileName, out string msg)
+ {
+ msg = string.Empty;
+
+ try
+ {
+ //检查GUI设置
+ if (config == null
+ || config.index < 0
+ || config.vmess.Count <= 0
+ || config.index > config.vmess.Count - 1
+ )
+ {
+ msg = UIRes.I18N("CheckServerSettings");
+ return -1;
+ }
+
+ msg = UIRes.I18N("InitialConfiguration");
+
+ //取得默认配置
+ string result = Utils.GetEmbedText(SampleServer);
+ if (Utils.IsNullOrEmpty(result))
+ {
+ msg = UIRes.I18N("FailedGetDefaultConfiguration");
+ return -1;
+ }
+
+ //转成Json
+ V2rayConfig v2rayConfig = Utils.FromJson(result);
+ if (v2rayConfig == null)
+ {
+ msg = UIRes.I18N("FailedGenDefaultConfiguration");
+ return -1;
+ }
+
+ ////开始修改配置
+ log(config, ref v2rayConfig, true);
+
+ //vmess协议服务器配置
+ ServerInbound(config, ref v2rayConfig);
+
+ //传出设置
+ ServerOutbound(config, ref v2rayConfig);
+
+ Utils.ToJsonFile(v2rayConfig, fileName);
+
+ msg = string.Format(UIRes.I18N("SuccessfulConfiguration"), config.getSummary());
+ }
+ catch
+ {
+ msg = UIRes.I18N("FailedGenDefaultConfiguration");
+ return -1;
+ }
+ return 0;
+ }
+
+ ///
+ /// vmess协议服务器配置
+ ///
+ ///
+ ///
+ ///
+ private static int ServerInbound(Config config, ref V2rayConfig v2rayConfig)
+ {
+ try
+ {
+ var inbound = v2rayConfig.inbounds[0];
+ UsersItem usersItem;
+ if (inbound.settings.clients.Count <= 0)
+ {
+ usersItem = new UsersItem();
+ inbound.settings.clients.Add(usersItem);
+ }
+ else
+ {
+ usersItem = inbound.settings.clients[0];
+ }
+ //远程服务器端口
+ inbound.port = config.port();
+
+ //远程服务器用户ID
+ usersItem.id = config.id();
+ usersItem.alterId = config.alterId();
+ usersItem.email = Global.userEMail;
+
+ //远程服务器底层传输配置
+ StreamSettings streamSettings = inbound.streamSettings;
+ boundStreamSettings(config, "in", ref streamSettings);
+ }
+ catch
+ {
+ }
+ return 0;
+ }
+
+ ///
+ /// 传出设置
+ ///
+ ///
+ ///
+ ///
+ private static int ServerOutbound(Config config, ref V2rayConfig v2rayConfig)
+ {
+ try
+ {
+ if (v2rayConfig.outbounds[0] != null)
+ {
+ v2rayConfig.outbounds[0].settings = null;
+ }
+ }
+ catch
+ {
+ }
+ return 0;
+ }
+ #endregion
+
+ #region 导入(导出)客户端/服务端配置
+
+ ///
+ /// 导入v2ray客户端配置
+ ///
+ ///
+ ///
+ ///
+ public static VmessItem ImportFromClientConfig(string fileName, out string msg)
+ {
+ msg = string.Empty;
+ VmessItem vmessItem = new VmessItem();
+
+ try
+ {
+ //载入配置文件
+ string result = Utils.LoadResource(fileName);
+ if (Utils.IsNullOrEmpty(result))
+ {
+ msg = UIRes.I18N("FailedReadConfiguration");
+ return null;
+ }
+
+ //转成Json
+ V2rayConfig v2rayConfig = Utils.FromJson(result);
+ if (v2rayConfig == null)
+ {
+ msg = UIRes.I18N("FailedConversionConfiguration");
+ return null;
+ }
+
+ if (v2rayConfig.outbounds == null
+ || v2rayConfig.outbounds.Count <= 0)
+ {
+ msg = UIRes.I18N("IncorrectClientConfiguration");
+ return null;
+ }
+
+ var outbound = v2rayConfig.outbounds[0];
+ if (outbound == null
+ || Utils.IsNullOrEmpty(outbound.protocol)
+ || outbound.protocol != "vmess"
+ || outbound.settings == null
+ || outbound.settings.vnext == null
+ || outbound.settings.vnext.Count <= 0
+ || outbound.settings.vnext[0].users == null
+ || outbound.settings.vnext[0].users.Count <= 0)
+ {
+ msg = UIRes.I18N("IncorrectClientConfiguration");
+ return null;
+ }
+
+ vmessItem.security = Global.DefaultSecurity;
+ vmessItem.network = Global.DefaultNetwork;
+ vmessItem.headerType = Global.None;
+ vmessItem.address = outbound.settings.vnext[0].address;
+ vmessItem.port = outbound.settings.vnext[0].port;
+ vmessItem.id = outbound.settings.vnext[0].users[0].id;
+ vmessItem.alterId = outbound.settings.vnext[0].users[0].alterId;
+ vmessItem.remarks = string.Format("import@{0}", DateTime.Now.ToShortDateString());
+
+ //tcp or kcp
+ if (outbound.streamSettings != null
+ && outbound.streamSettings.network != null
+ && !Utils.IsNullOrEmpty(outbound.streamSettings.network))
+ {
+ vmessItem.network = outbound.streamSettings.network;
+ }
+
+ //tcp伪装http
+ if (outbound.streamSettings != null
+ && outbound.streamSettings.tcpSettings != null
+ && outbound.streamSettings.tcpSettings.header != null
+ && !Utils.IsNullOrEmpty(outbound.streamSettings.tcpSettings.header.type))
+ {
+ if (outbound.streamSettings.tcpSettings.header.type.Equals(Global.TcpHeaderHttp))
+ {
+ vmessItem.headerType = outbound.streamSettings.tcpSettings.header.type;
+ string request = Convert.ToString(outbound.streamSettings.tcpSettings.header.request);
+ if (!Utils.IsNullOrEmpty(request))
+ {
+ V2rayTcpRequest v2rayTcpRequest = Utils.FromJson(request);
+ if (v2rayTcpRequest != null
+ && v2rayTcpRequest.headers != null
+ && v2rayTcpRequest.headers.Host != null
+ && v2rayTcpRequest.headers.Host.Count > 0)
+ {
+ vmessItem.requestHost = v2rayTcpRequest.headers.Host[0];
+ }
+ }
+ }
+ }
+ //kcp伪装
+ if (outbound.streamSettings != null
+ && outbound.streamSettings.kcpSettings != null
+ && outbound.streamSettings.kcpSettings.header != null
+ && !Utils.IsNullOrEmpty(outbound.streamSettings.kcpSettings.header.type))
+ {
+ vmessItem.headerType = outbound.streamSettings.kcpSettings.header.type;
+ }
+
+ //ws
+ if (outbound.streamSettings != null
+ && outbound.streamSettings.wsSettings != null)
+ {
+ if (!Utils.IsNullOrEmpty(outbound.streamSettings.wsSettings.path))
+ {
+ vmessItem.path = outbound.streamSettings.wsSettings.path;
+ }
+ if (outbound.streamSettings.wsSettings.headers != null
+ && !Utils.IsNullOrEmpty(outbound.streamSettings.wsSettings.headers.Host))
+ {
+ vmessItem.requestHost = outbound.streamSettings.wsSettings.headers.Host;
+ }
+ }
+
+ //h2
+ if (outbound.streamSettings != null
+ && outbound.streamSettings.httpSettings != null)
+ {
+ if (!Utils.IsNullOrEmpty(outbound.streamSettings.httpSettings.path))
+ {
+ vmessItem.path = outbound.streamSettings.httpSettings.path;
+ }
+ if (outbound.streamSettings.httpSettings.host != null
+ && outbound.streamSettings.httpSettings.host.Count > 0)
+ {
+ vmessItem.requestHost = Utils.List2String(outbound.streamSettings.httpSettings.host);
+ }
+ }
+
+ //tls
+ if (outbound.streamSettings != null
+ && outbound.streamSettings.security != null
+ && outbound.streamSettings.security == Global.StreamSecurity)
+ {
+ vmessItem.streamSecurity = Global.StreamSecurity;
+ }
+ }
+ catch
+ {
+ msg = UIRes.I18N("IncorrectClientConfiguration");
+ return null;
+ }
+
+ return vmessItem;
+ }
+
+ ///
+ /// 导入v2ray服务端配置
+ ///
+ ///
+ ///
+ ///
+ public static VmessItem ImportFromServerConfig(string fileName, out string msg)
+ {
+ msg = string.Empty;
+ VmessItem vmessItem = new VmessItem();
+
+ try
+ {
+ //载入配置文件
+ string result = Utils.LoadResource(fileName);
+ if (Utils.IsNullOrEmpty(result))
+ {
+ msg = UIRes.I18N("FailedReadConfiguration");
+ return null;
+ }
+
+ //转成Json
+ V2rayConfig v2rayConfig = Utils.FromJson(result);
+ if (v2rayConfig == null)
+ {
+ msg = UIRes.I18N("FailedConversionConfiguration");
+ return null;
+ }
+
+ if (v2rayConfig.inbounds == null
+ || v2rayConfig.inbounds.Count <= 0)
+ {
+ msg = UIRes.I18N("IncorrectServerConfiguration");
+ return null;
+ }
+
+ var inbound = v2rayConfig.inbounds[0];
+ if (inbound == null
+ || Utils.IsNullOrEmpty(inbound.protocol)
+ || inbound.protocol != "vmess"
+ || inbound.settings == null
+ || inbound.settings.clients == null
+ || inbound.settings.clients.Count <= 0)
+ {
+ msg = UIRes.I18N("IncorrectServerConfiguration");
+ return null;
+ }
+
+ vmessItem.security = Global.DefaultSecurity;
+ vmessItem.network = Global.DefaultNetwork;
+ vmessItem.headerType = Global.None;
+ vmessItem.address = string.Empty;
+ vmessItem.port = inbound.port;
+ vmessItem.id = inbound.settings.clients[0].id;
+ vmessItem.alterId = inbound.settings.clients[0].alterId;
+
+ vmessItem.remarks = string.Format("import@{0}", DateTime.Now.ToShortDateString());
+
+ //tcp or kcp
+ if (inbound.streamSettings != null
+ && inbound.streamSettings.network != null
+ && !Utils.IsNullOrEmpty(inbound.streamSettings.network))
+ {
+ vmessItem.network = inbound.streamSettings.network;
+ }
+
+ //tcp伪装http
+ if (inbound.streamSettings != null
+ && inbound.streamSettings.tcpSettings != null
+ && inbound.streamSettings.tcpSettings.header != null
+ && !Utils.IsNullOrEmpty(inbound.streamSettings.tcpSettings.header.type))
+ {
+ if (inbound.streamSettings.tcpSettings.header.type.Equals(Global.TcpHeaderHttp))
+ {
+ vmessItem.headerType = inbound.streamSettings.tcpSettings.header.type;
+ string request = Convert.ToString(inbound.streamSettings.tcpSettings.header.request);
+ if (!Utils.IsNullOrEmpty(request))
+ {
+ V2rayTcpRequest v2rayTcpRequest = Utils.FromJson(request);
+ if (v2rayTcpRequest != null
+ && v2rayTcpRequest.headers != null
+ && v2rayTcpRequest.headers.Host != null
+ && v2rayTcpRequest.headers.Host.Count > 0)
+ {
+ vmessItem.requestHost = v2rayTcpRequest.headers.Host[0];
+ }
+ }
+ }
+ }
+ //kcp伪装
+ //if (v2rayConfig.outbound.streamSettings != null
+ // && v2rayConfig.outbound.streamSettings.kcpSettings != null
+ // && v2rayConfig.outbound.streamSettings.kcpSettings.header != null
+ // && !Utils.IsNullOrEmpty(v2rayConfig.outbound.streamSettings.kcpSettings.header.type))
+ //{
+ // cmbHeaderType.Text = v2rayConfig.outbound.streamSettings.kcpSettings.header.type;
+ //}
+
+ //ws
+ if (inbound.streamSettings != null
+ && inbound.streamSettings.wsSettings != null)
+ {
+ if (!Utils.IsNullOrEmpty(inbound.streamSettings.wsSettings.path))
+ {
+ vmessItem.path = inbound.streamSettings.wsSettings.path;
+ }
+ if (inbound.streamSettings.wsSettings.headers != null
+ && !Utils.IsNullOrEmpty(inbound.streamSettings.wsSettings.headers.Host))
+ {
+ vmessItem.requestHost = inbound.streamSettings.wsSettings.headers.Host;
+ }
+ }
+
+ //h2
+ if (inbound.streamSettings != null
+ && inbound.streamSettings.httpSettings != null)
+ {
+ if (!Utils.IsNullOrEmpty(inbound.streamSettings.httpSettings.path))
+ {
+ vmessItem.path = inbound.streamSettings.httpSettings.path;
+ }
+ if (inbound.streamSettings.httpSettings.host != null
+ && inbound.streamSettings.httpSettings.host.Count > 0)
+ {
+ vmessItem.requestHost = Utils.List2String(inbound.streamSettings.httpSettings.host);
+ }
+ }
+
+ //tls
+ if (inbound.streamSettings != null
+ && inbound.streamSettings.security != null
+ && inbound.streamSettings.security == Global.StreamSecurity)
+ {
+ vmessItem.streamSecurity = Global.StreamSecurity;
+ }
+ }
+ catch
+ {
+ msg = UIRes.I18N("IncorrectClientConfiguration");
+ return null;
+ }
+ return vmessItem;
+ }
+
+ ///
+ /// 从剪贴板导入URL
+ ///
+ ///
+ ///
+ ///
+ public static VmessItem ImportFromClipboardConfig(string clipboardData, out string msg)
+ {
+ msg = string.Empty;
+ VmessItem vmessItem = new VmessItem();
+
+ try
+ {
+ //载入配置文件
+ string result = clipboardData.TrimEx();// Utils.GetClipboardData();
+ if (Utils.IsNullOrEmpty(result))
+ {
+ msg = UIRes.I18N("FailedReadConfiguration");
+ return null;
+ }
+
+ if (result.StartsWith(Global.vmessProtocol))
+ {
+ int indexSplit = result.IndexOf("?");
+ if (indexSplit > 0)
+ {
+ vmessItem = ResolveVmess4Kitsunebi(result);
+ }
+ else
+ {
+ vmessItem.configType = (int)EConfigType.Vmess;
+ result = result.Substring(Global.vmessProtocol.Length);
+ result = Utils.Base64Decode(result);
+
+ //转成Json
+ VmessQRCode vmessQRCode = Utils.FromJson(result);
+ if (vmessQRCode == null)
+ {
+ msg = UIRes.I18N("FailedConversionConfiguration");
+ return null;
+ }
+ vmessItem.security = Global.DefaultSecurity;
+ vmessItem.network = Global.DefaultNetwork;
+ vmessItem.headerType = Global.None;
+
+
+ vmessItem.configVersion = Utils.ToInt(vmessQRCode.v);
+ vmessItem.remarks = Utils.ToString(vmessQRCode.ps);
+ vmessItem.address = Utils.ToString(vmessQRCode.add);
+ vmessItem.port = Utils.ToInt(vmessQRCode.port);
+ vmessItem.id = Utils.ToString(vmessQRCode.id);
+ vmessItem.alterId = Utils.ToInt(vmessQRCode.aid);
+
+ if (!Utils.IsNullOrEmpty(vmessQRCode.net))
+ {
+ vmessItem.network = vmessQRCode.net;
+ }
+ if (!Utils.IsNullOrEmpty(vmessQRCode.type))
+ {
+ vmessItem.headerType = vmessQRCode.type;
+ }
+
+ vmessItem.requestHost = Utils.ToString(vmessQRCode.host);
+ vmessItem.path = Utils.ToString(vmessQRCode.path);
+ vmessItem.streamSecurity = Utils.ToString(vmessQRCode.tls);
+ }
+
+ ConfigHandler.UpgradeServerVersion(ref vmessItem);
+ }
+ else if (result.StartsWith(Global.ssProtocol))
+ {
+ msg = UIRes.I18N("ConfigurationFormatIncorrect");
+
+ vmessItem.configType = (int)EConfigType.Shadowsocks;
+ result = result.Substring(Global.ssProtocol.Length);
+ //remark
+ int indexRemark = result.IndexOf("#");
+ if (indexRemark > 0)
+ {
+ try
+ {
+ vmessItem.remarks = WebUtility.UrlDecode(result.Substring(indexRemark + 1, result.Length - indexRemark - 1));
+ }
+ catch { }
+ result = result.Substring(0, indexRemark);
+ }
+ //part decode
+ int indexS = result.IndexOf("@");
+ if (indexS > 0)
+ {
+ result = Utils.Base64Decode(result.Substring(0, indexS)) + result.Substring(indexS, result.Length - indexS);
+ }
+ else
+ {
+ result = Utils.Base64Decode(result);
+ }
+
+ string[] arr1 = result.Split('@');
+ if (arr1.Length != 2)
+ {
+ return null;
+ }
+ string[] arr21 = arr1[0].Split(':');
+ //string[] arr22 = arr1[1].Split(':');
+ int indexPort = arr1[1].LastIndexOf(":");
+ if (arr21.Length != 2 || indexPort < 0)
+ {
+ return null;
+ }
+ vmessItem.address = arr1[1].Substring(0, indexPort);
+ vmessItem.port = Utils.ToInt(arr1[1].Substring(indexPort + 1, arr1[1].Length - (indexPort + 1)));
+ vmessItem.security = arr21[0];
+ vmessItem.id = arr21[1];
+ }
+ else if (result.StartsWith(Global.socksProtocol))
+ {
+ msg = UIRes.I18N("ConfigurationFormatIncorrect");
+
+ vmessItem.configType = (int)EConfigType.Socks;
+ result = result.Substring(Global.socksProtocol.Length);
+ //remark
+ int indexRemark = result.IndexOf("#");
+ if (indexRemark > 0)
+ {
+ try
+ {
+ vmessItem.remarks = WebUtility.UrlDecode(result.Substring(indexRemark + 1, result.Length - indexRemark - 1));
+ }
+ catch { }
+ result = result.Substring(0, indexRemark);
+ }
+ //part decode
+ int indexS = result.IndexOf("@");
+ if (indexS > 0)
+ {
+ }
+ else
+ {
+ result = Utils.Base64Decode(result);
+ }
+
+ string[] arr1 = result.Split('@');
+ if (arr1.Length != 2)
+ {
+ return null;
+ }
+ string[] arr21 = arr1[0].Split(':');
+ //string[] arr22 = arr1[1].Split(':');
+ int indexPort = arr1[1].LastIndexOf(":");
+ if (arr21.Length != 2 || indexPort < 0)
+ {
+ return null;
+ }
+ vmessItem.address = arr1[1].Substring(0, indexPort);
+ vmessItem.port = Utils.ToInt(arr1[1].Substring(indexPort + 1, arr1[1].Length - (indexPort + 1)));
+ vmessItem.security = arr21[0];
+ vmessItem.id = arr21[1];
+ }
+ else
+ {
+ msg = UIRes.I18N("NonvmessOrssProtocol");
+ return null;
+ }
+ }
+ catch
+ {
+ msg = UIRes.I18N("Incorrectconfiguration");
+ return null;
+ }
+
+ return vmessItem;
+ }
+
+
+ ///
+ /// 导出为客户端配置
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int Export2ClientConfig(Config config, string fileName, out string msg)
+ {
+ msg = string.Empty;
+ return GenerateClientConfig(config, fileName, true, out msg);
+ }
+
+ ///
+ /// 导出为服务端配置
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int Export2ServerConfig(Config config, string fileName, out string msg)
+ {
+ msg = string.Empty;
+ return GenerateServerConfig(config, fileName, out msg);
+ }
+
+ private static VmessItem ResolveVmess4Kitsunebi(string result)
+ {
+ VmessItem vmessItem = new VmessItem();
+
+ vmessItem.configType = (int)EConfigType.Vmess;
+ result = result.Substring(Global.vmessProtocol.Length);
+ int indexSplit = result.IndexOf("?");
+ if (indexSplit > 0)
+ {
+ result = result.Substring(0, indexSplit);
+ }
+ result = Utils.Base64Decode(result);
+
+ string[] arr1 = result.Split('@');
+ if (arr1.Length != 2)
+ {
+ return null;
+ }
+ string[] arr21 = arr1[0].Split(':');
+ string[] arr22 = arr1[1].Split(':');
+ if (arr21.Length != 2 || arr21.Length != 2)
+ {
+ return null;
+ }
+
+ vmessItem.address = arr22[0];
+ vmessItem.port = Utils.ToInt(arr22[1]);
+ vmessItem.security = arr21[0];
+ vmessItem.id = arr21[1];
+
+ vmessItem.network = Global.DefaultNetwork;
+ vmessItem.headerType = Global.None;
+ vmessItem.remarks = "Alien";
+ vmessItem.alterId = 0;
+
+ return vmessItem;
+ }
+
+ #endregion
+
+ }
+}
diff --git a/v2rayN/v2rayN/Handler/V2rayHandler.cs b/v2rayN/v2rayN/Handler/V2rayHandler.cs
new file mode 100644
index 00000000..244892c8
--- /dev/null
+++ b/v2rayN/v2rayN/Handler/V2rayHandler.cs
@@ -0,0 +1,165 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using v2rayN.Mode;
+
+namespace v2rayN.Handler
+{
+
+ ///
+ /// 消息委托
+ ///
+ /// 是否显示在托盘区
+ /// 内容
+ public delegate void ProcessDelegate(bool notify, string msg);
+
+ ///
+ /// v2ray进程处理类
+ ///
+ class V2rayHandler
+ {
+ private static string v2rayConfigRes = Global.v2rayConfigFileName;
+ private List lstV2ray;
+ public event ProcessDelegate ProcessEvent;
+ private int processId = 0;
+
+ public V2rayHandler()
+ {
+ lstV2ray = new List();
+ lstV2ray.Add("wv2ray");
+ lstV2ray.Add("v2ray");
+ }
+
+ ///
+ /// 载入V2ray
+ ///
+ public void LoadV2ray(Config config)
+ {
+ if (Global.reloadV2ray)
+ {
+ string msg = string.Empty;
+ string fileName = Utils.GetPath(v2rayConfigRes);
+ if (V2rayConfigHandler.GenerateClientConfig(config, fileName, false, out msg) != 0)
+ {
+ ShowMsg(false, msg);
+ }
+ else
+ {
+ ShowMsg(true, msg);
+ V2rayRestart();
+ }
+ }
+ }
+
+ ///
+ /// V2ray重启
+ ///
+ private void V2rayRestart()
+ {
+ V2rayStop();
+ V2rayStart();
+ }
+
+ ///
+ /// V2ray停止
+ ///
+ public void V2rayStop()
+ {
+ try
+ {
+ bool blExist = true;
+ if (processId > 0)
+ {
+ Process p1 = Process.GetProcessById(processId);
+ if (p1 != null)
+ {
+ p1.Kill();
+ blExist = false;
+ }
+ }
+ if (blExist)
+ {
+ foreach (string vName in lstV2ray)
+ {
+ Process[] killPro = Process.GetProcessesByName(vName);
+ foreach (Process p in killPro)
+ {
+ p.Kill();
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ ///
+ /// V2ray启动
+ ///
+ private void V2rayStart()
+ {
+ ShowMsg(false, string.Format(UIRes.I18N("StartService"), DateTime.Now.ToString()));
+
+ try
+ {
+ //查找v2ray文件是否存在
+ string fileName = string.Empty;
+ for (int k = 0; k < lstV2ray.Count; k++)
+ {
+ string vName = string.Format("{0}.exe", lstV2ray[k]);
+ vName = Utils.GetPath(vName);
+ if (File.Exists(vName))
+ {
+ fileName = vName;
+ break;
+ }
+ }
+ if (Utils.IsNullOrEmpty(fileName))
+ {
+ string msg = string.Format(UIRes.I18N("NotFoundCore"), @"https://github.com/v2ray/v2ray-core/releases");
+ ShowMsg(true, msg);
+ return;
+ }
+
+ Process p = new Process();
+ p.StartInfo.FileName = fileName;
+ p.StartInfo.UseShellExecute = false;
+ p.StartInfo.RedirectStandardOutput = true;
+ p.StartInfo.CreateNoWindow = true;
+ p.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
+ {
+ if (!String.IsNullOrEmpty(e.Data))
+ {
+ string msg = e.Data + Environment.NewLine;
+ ShowMsg(false, msg);
+ }
+ });
+ p.Start();
+ p.BeginOutputReadLine();
+ processId = p.Id;
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ string msg = ex.Message;
+ ShowMsg(true, msg);
+ }
+ }
+
+ ///
+ /// 消息委托
+ ///
+ ///
+ ///
+ private void ShowMsg(bool notify, string msg)
+ {
+ if (ProcessEvent != null)
+ {
+ ProcessEvent(notify, msg);
+ }
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/Handler/V2rayUpdateHandle.cs b/v2rayN/v2rayN/Handler/V2rayUpdateHandle.cs
new file mode 100644
index 00000000..2de80f26
--- /dev/null
+++ b/v2rayN/v2rayN/Handler/V2rayUpdateHandle.cs
@@ -0,0 +1,221 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Text;
+using Newtonsoft.Json;
+using v2rayN.Mode;
+using v2rayN.Properties;
+using v2rayN.HttpProxyHandler;
+using System.Diagnostics;
+
+namespace v2rayN.Handler
+{
+ ///
+ ///Update V2ray Core
+ ///
+ class V2rayUpdateHandle
+ {
+ public event EventHandler AbsoluteCompleted;
+
+ public event EventHandler UpdateCompleted;
+
+ public event ErrorEventHandler Error;
+
+ public string DownloadFileName
+ {
+ get
+ {
+ return "v2ray-windows.zip";
+ }
+ }
+
+ public class ResultEventArgs : EventArgs
+ {
+ public bool Success;
+ public string Msg;
+
+ public ResultEventArgs(bool success, string msg)
+ {
+ this.Success = success;
+ this.Msg = msg;
+ }
+ }
+
+ private string latestUrl = "https://github.com/v2ray/v2ray-core/releases/latest";
+ private const string coreURL = "https://github.com/v2ray/v2ray-core/releases/download/{0}/v2ray-windows-{1}.zip";
+ private int progressPercentage = -1;
+ private bool blFirst = true;
+ private long totalBytesToReceive = 0;
+ private DateTime totalDatetime = new DateTime();
+
+
+ public void AbsoluteV2rayCore(Config config)
+ {
+ ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; //TLS 1.2
+ ServicePointManager.DefaultConnectionLimit = 256;
+ WebRequest request = WebRequest.Create(latestUrl);
+ request.BeginGetResponse(new AsyncCallback(OnResponseV2rayCore), request);
+ }
+
+ private void OnResponseV2rayCore(IAsyncResult ar)
+ {
+ try
+ {
+ HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
+ HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);
+ string redirectUrl = response.ResponseUri.AbsoluteUri;
+ string version = redirectUrl.Substring(redirectUrl.LastIndexOf("/", StringComparison.Ordinal) + 1);
+
+ string osBit = string.Empty;
+ if (Environment.Is64BitProcess)
+ {
+ osBit = "64";
+ }
+ else
+ {
+ osBit = "32";
+ }
+ string url = string.Format(coreURL, version, osBit);
+ if (AbsoluteCompleted != null)
+ {
+ AbsoluteCompleted(this, new ResultEventArgs(true, url));
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+
+ if (Error != null)
+ Error(this, new ErrorEventArgs(ex));
+ }
+ }
+
+
+ public void DownloadFileAsync(Config config, string url)
+ {
+ try
+ {
+ ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; //TLS 1.2
+ ServicePointManager.DefaultConnectionLimit = 256;
+ if (UpdateCompleted != null)
+ {
+ UpdateCompleted(this, new ResultEventArgs(false, url));
+ }
+
+ progressPercentage = -1;
+
+ WebClientEx ws = new WebClientEx();
+ ws.DownloadFileCompleted += ws_DownloadFileCompleted;
+ ws.DownloadProgressChanged += ws_DownloadProgressChanged;
+ ws.DownloadFileAsync(new Uri(url), Utils.GetPath(DownloadFileName));
+ blFirst = true;
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+
+ if (Error != null)
+ Error(this, new ErrorEventArgs(ex));
+ }
+ }
+
+ void ws_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
+ {
+ if (blFirst)
+ {
+ totalBytesToReceive = e.TotalBytesToReceive - e.BytesReceived;
+ totalDatetime = DateTime.Now;
+ blFirst = false;
+ }
+ if (UpdateCompleted != null)
+ {
+ if (progressPercentage != e.ProgressPercentage && e.ProgressPercentage % 10 == 0)
+ {
+ progressPercentage = e.ProgressPercentage;
+ string msg = string.Format("...{0}%", e.ProgressPercentage);
+ UpdateCompleted(this, new ResultEventArgs(false, msg));
+ }
+ }
+ }
+
+ void ws_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
+ {
+ try
+ {
+ if (e.Error == null
+ || Utils.IsNullOrEmpty(e.Error.ToString()))
+ {
+ if (UpdateCompleted != null)
+ {
+ TimeSpan ts = (DateTime.Now - totalDatetime);
+ string speed = string.Format("{0} M/s", (totalBytesToReceive / ts.TotalMilliseconds / 1000).ToString("#0.##"));
+ UpdateCompleted(this, new ResultEventArgs(true, speed));
+ }
+ }
+ else
+ {
+ throw e.Error;
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+
+ if (Error != null)
+ Error(this, new ErrorEventArgs(ex));
+ }
+ }
+
+ ///
+ /// DownloadString
+ ///
+ ///
+ public void WebDownloadString(string url)
+ {
+ string source = string.Empty;
+ try
+ {
+ ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; //TLS 1.2
+ ServicePointManager.DefaultConnectionLimit = 256;
+
+ WebClientEx ws = new WebClientEx();
+ ws.DownloadStringCompleted += Ws_DownloadStringCompleted;
+ ws.DownloadStringAsync(new Uri(url));
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ private void Ws_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
+ {
+ try
+ {
+ if (e.Error == null
+ || Utils.IsNullOrEmpty(e.Error.ToString()))
+ {
+ string source = e.Result;
+ if (UpdateCompleted != null)
+ {
+ UpdateCompleted(this, new ResultEventArgs(true, source));
+ }
+ }
+ else
+ {
+ throw e.Error;
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+
+ if (Error != null)
+ Error(this, new ErrorEventArgs(ex));
+ }
+ }
+
+
+ }
+}
diff --git a/v2rayN/v2rayN/HttpProxyHandler/HttpProxyHandle.cs b/v2rayN/v2rayN/HttpProxyHandler/HttpProxyHandle.cs
new file mode 100644
index 00000000..fd11820b
--- /dev/null
+++ b/v2rayN/v2rayN/HttpProxyHandler/HttpProxyHandle.cs
@@ -0,0 +1,177 @@
+using System;
+using v2rayN.Mode;
+
+namespace v2rayN.HttpProxyHandler
+{
+ ///
+ /// 系统代理(http)总处理
+ /// 启动privoxy提供http协议
+ /// 使用SysProxy设置IE系统代理或者PAC模式
+ ///
+ class HttpProxyHandle
+ {
+ private static string GetTimestamp(DateTime value)
+ {
+ return value.ToString("MMddHHmmssfff");
+ }
+
+ public static void ReSetPACProxy(Config config)
+ {
+ if (config.listenerType == 2)
+ {
+ //SysProxyHandle.SetIEProxy(false, false, null, null);
+ //PACServerHandle.Stop();
+ }
+ Update(config, false);
+ }
+
+ public static bool Update(Config config, bool forceDisable)
+ {
+ int type = config.listenerType;
+
+ if (forceDisable)
+ {
+ type = 0;
+ }
+
+ try
+ {
+ if (type != 0)
+ {
+ var port = Global.sysAgentPort;
+ if (port <= 0)
+ {
+ return false;
+ }
+ if (type == 1)
+ {
+ PACServerHandle.Stop();
+ PACFileWatcherHandle.StopWatch();
+ SysProxyHandle.SetIEProxy(true, true, "127.0.0.1:" + port, null);
+ }
+ else if (type == 2)
+ {
+ string pacUrl = GetPacUrl();
+ SysProxyHandle.SetIEProxy(true, false, null, pacUrl);
+ PACServerHandle.Stop();
+ PACServerHandle.Init(config);
+ PACFileWatcherHandle.StartWatch(config);
+ }
+ else if (type == 3)
+ {
+ PACServerHandle.Stop();
+ PACFileWatcherHandle.StopWatch();
+ SysProxyHandle.SetIEProxy(false, false, null, null);
+ }
+ else if (type == 4)
+ {
+ string pacUrl = GetPacUrl();
+ SysProxyHandle.SetIEProxy(false, false, null, null);
+ PACServerHandle.Stop();
+ PACServerHandle.Init(config);
+ PACFileWatcherHandle.StartWatch(config);
+ }
+ }
+ else
+ {
+ SysProxyHandle.SetIEProxy(false, false, null, null);
+ PACServerHandle.Stop();
+ PACFileWatcherHandle.StopWatch();
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ return true;
+ }
+
+ ///
+ /// 启用系统代理(http)
+ ///
+ ///
+ public static void StartHttpAgent(Config config)
+ {
+ try
+ {
+ int localPort = config.GetLocalPort("socks");
+ if (localPort > 0)
+ {
+ PrivoxyHandler.Instance.Start(localPort, config);
+ if (PrivoxyHandler.Instance.RunningPort > 0)
+ {
+ Global.sysAgent = true;
+ Global.socksPort = localPort;
+ Global.sysAgentPort = PrivoxyHandler.Instance.RunningPort;
+ Global.pacPort = Global.sysAgentPort + 1;
+ }
+ }
+ }
+ catch
+ {
+ }
+ }
+
+ ///
+ /// 关闭系统代理
+ ///
+ ///
+ public static void CloseHttpAgent(Config config)
+ {
+ try
+ {
+ ////开启全局代理则关闭
+ //if (Global.sysAgent)
+ //{
+ PrivoxyHandler.Instance.Stop();
+
+ Global.sysAgent = false;
+ Global.socksPort = 0;
+ Global.sysAgentPort = 0;
+ Global.pacPort = 0;
+ //}
+ }
+ catch
+ {
+ }
+ }
+
+ ///
+ /// 重启系统代理(http)
+ ///
+ ///
+ ///
+ public static bool RestartHttpAgent(Config config, bool forced)
+ {
+ bool isRestart = false;
+ //强制重启或者socks端口变化
+ if (forced)
+ {
+ isRestart = true;
+ }
+ else
+ {
+ int localPort = config.GetLocalPort("socks");
+ if (localPort != Global.socksPort)
+ {
+ isRestart = true;
+ }
+ }
+ if (isRestart)
+ {
+ CloseHttpAgent(config);
+ StartHttpAgent(config);
+ return true;
+ }
+ return false;
+ }
+
+ public static string GetPacUrl()
+ {
+ string pacUrl = string.Format("http://127.0.0.1:{0}/pac/?t={1}", Global.pacPort,
+ GetTimestamp(DateTime.Now));
+
+ return pacUrl;
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/HttpProxyHandler/HttpWebServer.cs b/v2rayN/v2rayN/HttpProxyHandler/HttpWebServer.cs
new file mode 100644
index 00000000..906f26d9
--- /dev/null
+++ b/v2rayN/v2rayN/HttpProxyHandler/HttpWebServer.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Net;
+using System.Text;
+using System.Threading;
+
+namespace v2rayN.HttpProxyHandler
+{
+ public class HttpWebServer
+ {
+ private HttpListener _listener;
+ private Func _responderMethod;
+
+ public HttpWebServer(string[] prefixes, Func method)
+ {
+ try
+ {
+ _listener = new HttpListener();
+
+ if (!HttpListener.IsSupported)
+ throw new NotSupportedException(
+ "Needs Windows XP SP2, Server 2003 or later.");
+
+ // URI prefixes are required, for example
+ // "http://localhost:8080/index/".
+ if (prefixes == null || prefixes.Length == 0)
+ throw new ArgumentException("prefixes");
+
+ // A responder method is required
+ if (method == null)
+ throw new ArgumentException("method");
+
+ foreach (string s in prefixes)
+ _listener.Prefixes.Add(s);
+
+ _responderMethod = method;
+ _listener.Start();
+
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ throw;
+ }
+ }
+
+ public HttpWebServer(Func method, params string[] prefixes)
+ : this(prefixes, method) { }
+
+ public void Run()
+ {
+ ThreadPool.QueueUserWorkItem((o) =>
+ {
+ Utils.SaveLog("Webserver running...");
+ try
+ {
+ while (_listener.IsListening)
+ {
+ ThreadPool.QueueUserWorkItem((c) =>
+ {
+ var ctx = c as HttpListenerContext;
+ try
+ {
+ string address = ctx.Request.LocalEndPoint.Address.ToString();
+ string rstr = _responderMethod(address);
+ byte[] buf = Encoding.UTF8.GetBytes(rstr);
+ ctx.Response.StatusCode = 200;
+ ctx.Response.ContentType = "application/x-ns-proxy-autoconfig";
+ ctx.Response.ContentLength64 = buf.Length;
+ ctx.Response.OutputStream.Write(buf, 0, buf.Length);
+ }
+ catch
+ {
+ } // suppress any exceptions
+ finally
+ {
+ // always close the stream
+ ctx.Response.OutputStream.Close();
+ }
+ }, _listener.GetContext());
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ } // suppress any exceptions
+ });
+ }
+
+ public void Stop()
+ {
+ if (_listener != null)
+ {
+ _listener.Stop();
+ _listener.Close();
+ _listener = null;
+ }
+ }
+
+ }
+}
diff --git a/v2rayN/v2rayN/HttpProxyHandler/HttpWebServerB.cs b/v2rayN/v2rayN/HttpProxyHandler/HttpWebServerB.cs
new file mode 100644
index 00000000..78cbb0fc
--- /dev/null
+++ b/v2rayN/v2rayN/HttpProxyHandler/HttpWebServerB.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+
+namespace v2rayN.HttpProxyHandler
+{
+ public class HttpWebServerB
+ {
+ private TcpListener listener;
+ private int port;
+ private Func _responderMethod;
+
+ public HttpWebServerB(int port, Func method)
+ {
+ this.port = port;
+ this._responderMethod = method;
+
+ Thread thread = new Thread(StartListen);
+ thread.IsBackground = true;
+ thread.Start();
+ }
+
+ public void Stop()
+ {
+ if (listener != null)
+ {
+ listener.Stop();
+ listener = null;
+ }
+ }
+
+ private void StartListen()
+ {
+ listener = new TcpListener(IPAddress.Any, port);
+ listener.Start();
+ Utils.SaveLog("WebserverB running...");
+
+ while (true)
+ {
+ TcpClient socket = listener.AcceptTcpClient();
+ Thread thread = new Thread(new ParameterizedThreadStart(ProcessThread));
+ thread.Start(socket);
+ Thread.Sleep(1);
+ }
+ }
+ private void ProcessThread(object obj)
+ {
+ try
+ {
+ var socket = obj as TcpClient;
+
+ var inputStream = new BufferedStream(socket.GetStream());
+ var outputStream = new StreamWriter(new BufferedStream(socket.GetStream()));
+ if (inputStream.CanRead)
+ {
+ var data = ReadStream(inputStream);
+
+ if (data.Contains("/pac/"))
+ {
+ if (_responderMethod != null)
+ {
+ var address = ((IPEndPoint)socket.Client.LocalEndPoint).Address.ToString();
+ string pac = _responderMethod(address);
+
+ if (inputStream.CanWrite)
+ {
+ WriteStream(outputStream, pac);
+ }
+ }
+ }
+ }
+
+ outputStream.BaseStream.Flush();
+ inputStream = null;
+ outputStream = null;
+ socket.Close();
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ private string ReadStream(Stream inputStream)
+ {
+ int nextchar;
+ string data = "";
+ while (true)
+ {
+ nextchar = inputStream.ReadByte();
+ if (nextchar == '\n')
+ {
+ break;
+ }
+ if (nextchar == '\r')
+ {
+ continue;
+ }
+ if (nextchar == -1)
+ {
+ Thread.Sleep(1);
+ continue;
+ };
+ data += Convert.ToChar(nextchar);
+ }
+ return data;
+ }
+
+ private void WriteStream(StreamWriter outputStream, string pac)
+ {
+ var content_type = "application/x-ns-proxy-autoconfig";
+ outputStream.WriteLine("HTTP/1.1 200 OK");
+ outputStream.WriteLine(String.Format("Content-Type:{0}", content_type));
+ outputStream.WriteLine("Connection: close");
+ outputStream.WriteLine("");
+ outputStream.WriteLine(pac);
+ outputStream.Flush();
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/HttpProxyHandler/PACFileWatcherHandle.cs b/v2rayN/v2rayN/HttpProxyHandler/PACFileWatcherHandle.cs
new file mode 100644
index 00000000..08043d73
--- /dev/null
+++ b/v2rayN/v2rayN/HttpProxyHandler/PACFileWatcherHandle.cs
@@ -0,0 +1,45 @@
+using System.IO;
+using System.Windows.Forms;
+using v2rayN.Mode;
+
+namespace v2rayN.HttpProxyHandler
+{
+ ///
+ /// 提供PAC功能支持
+ ///
+ class PACFileWatcherHandle
+ {
+ private static FileSystemWatcher fileSystemWatcher;
+
+ private static long fileSize;
+
+ public static void StartWatch(Config config)
+ {
+ if (fileSystemWatcher == null)
+ {
+ fileSystemWatcher = new FileSystemWatcher(Utils.StartupPath());
+ fileSystemWatcher.Filter = "pac.txt";
+ fileSystemWatcher.NotifyFilter = NotifyFilters.Size;
+ fileSystemWatcher.Changed += (sender, args) =>
+ {
+ var fileInfo = new FileInfo(args.FullPath);
+ if (fileSize != fileInfo.Length)
+ {
+ fileSize = fileInfo.Length;
+ HttpProxyHandle.ReSetPACProxy(config);
+ }
+
+ };
+ }
+ fileSystemWatcher.EnableRaisingEvents = true;
+ }
+
+ public static void StopWatch()
+ {
+ if (fileSystemWatcher != null)
+ {
+ fileSystemWatcher.EnableRaisingEvents = false;
+ }
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/HttpProxyHandler/PACListHandle.cs b/v2rayN/v2rayN/HttpProxyHandler/PACListHandle.cs
new file mode 100644
index 00000000..2d021a3b
--- /dev/null
+++ b/v2rayN/v2rayN/HttpProxyHandler/PACListHandle.cs
@@ -0,0 +1,92 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Text;
+using Newtonsoft.Json;
+using v2rayN.Mode;
+using v2rayN.Properties;
+
+namespace v2rayN.HttpProxyHandler
+{
+ ///
+ /// 提供PAC功能支持
+ ///
+ class PACListHandle
+ {
+ public event EventHandler UpdateCompleted;
+
+ public event ErrorEventHandler Error;
+
+ public class ResultEventArgs : EventArgs
+ {
+ public bool Success;
+
+ public ResultEventArgs(bool success)
+ {
+ this.Success = success;
+ }
+ }
+
+ private const string GFWLIST_URL = "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt";
+
+ private static readonly IEnumerable IgnoredLineBegins = new[] { '!', '[' };
+
+ public void UpdatePACFromGFWList(Config config)
+ {
+ string url = GFWLIST_URL;
+ if (!Utils.IsNullOrEmpty(config.urlGFWList))
+ {
+ url = config.urlGFWList;
+ }
+
+ //默认用户已开启系统代理
+ //var httpProxy = config.inbound.FirstOrDefault(x => x.protocol=="http");
+ //if (httpProxy == null)
+ //{
+ // throw new Exception("未发现HTTP代理,无法设置代理更新");
+ //}
+ WebClient http = new WebClient();
+ //http.Headers.Add("Connection", "Close");
+ //http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), httpProxy.localPort);
+ http.DownloadStringCompleted += http_DownloadStringCompleted;
+ http.DownloadStringAsync(new Uri(url));
+ }
+
+ private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
+ {
+ try
+ {
+ File.WriteAllText(Utils.GetTempPath("gfwlist.txt"), e.Result, Encoding.UTF8);
+ List lines = ParseResult(e.Result);
+ string abpContent = Utils.UnGzip(Resources.abp_js);
+ abpContent = abpContent.Replace("__RULES__", JsonConvert.SerializeObject(lines, Formatting.Indented));
+ File.WriteAllText(Utils.GetPath(Global.pacFILE), abpContent, Encoding.UTF8);
+ if (UpdateCompleted != null) UpdateCompleted(this, new ResultEventArgs(true));
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+
+ if (Error != null) Error(this, new ErrorEventArgs(ex));
+ }
+ }
+
+ public static List ParseResult(string response)
+ {
+ byte[] bytes = Convert.FromBase64String(response);
+ string content = Encoding.UTF8.GetString(bytes);
+ List valid_lines = new List();
+ using (var sr = new StringReader(content))
+ {
+ foreach (var line in sr.NonWhiteSpaceLines())
+ {
+ if (line.BeginWithAny(IgnoredLineBegins))
+ continue;
+ valid_lines.Add(line);
+ }
+ }
+ return valid_lines;
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/HttpProxyHandler/PACServerHandle.cs b/v2rayN/v2rayN/HttpProxyHandler/PACServerHandle.cs
new file mode 100644
index 00000000..01561103
--- /dev/null
+++ b/v2rayN/v2rayN/HttpProxyHandler/PACServerHandle.cs
@@ -0,0 +1,188 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using v2rayN.Mode;
+using v2rayN.Properties;
+using v2rayN.Tool;
+
+namespace v2rayN.HttpProxyHandler
+{
+ ///
+ /// 提供PAC功能支持
+ ///
+ class PACServerHandle
+ {
+ private static int pacPort = 0;
+ private static HttpWebServer server;
+ private static HttpWebServerB serverB;
+
+ public static bool IsRunning
+ {
+ get
+ {
+ return (pacPort > 0);
+ }
+ }
+
+ public static void Init(Config config)
+ {
+ //if (InitServer("*"))
+ //{
+ // pacPort = Global.pacPort;
+ //}
+ if (InitServer("127.0.0.1"))
+ {
+ pacPort = Global.pacPort;
+ }
+ else if (InitServerB("127.0.0.1"))
+ {
+ pacPort = Global.pacPort;
+ }
+ else
+ {
+ Utils.SaveLog("Webserver init failed ");
+ pacPort = 0;
+ }
+ }
+
+ private static bool InitServer(string address)
+ {
+ try
+ {
+ if (pacPort != Global.pacPort)
+ {
+ if (server != null)
+ {
+ server.Stop();
+ server = null;
+ }
+
+ if (server == null)
+ {
+ string prefixes = string.Format("http://{0}:{1}/pac/", address, Global.pacPort);
+ Utils.SaveLog("Webserver prefixes " + prefixes);
+
+ server = new HttpWebServer(SendResponse, prefixes);
+ server.Run();
+
+ //pacPort = Global.pacPort;
+ }
+ }
+ Utils.SaveLog("Webserver at " + address);
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog("Webserver InitServer " + ex.Message);
+ return false;
+ }
+ return true;
+ }
+
+ public static bool InitServerB(string address)
+ {
+ try
+ {
+ if (pacPort != Global.pacPort)
+ {
+ if (serverB != null)
+ {
+ serverB.Stop();
+ serverB = null;
+ }
+
+ if (serverB == null)
+ {
+ serverB = new HttpWebServerB(Global.pacPort, SendResponse);
+ //pacPort = Global.pacPort;
+ }
+ }
+ Utils.SaveLog("WebserverB at " + address);
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog("WebserverB InitServer " + ex.Message);
+ return false;
+ }
+ return true;
+ }
+
+ public static string SendResponse(string address)
+ {
+ try
+ {
+ var pac = GetPacList(address);
+ return pac;
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog("Webserver SendResponse " + ex.Message);
+ return ex.Message;
+ }
+ }
+
+ public static void Stop()
+ {
+ //try
+ //{
+ // if (server != null)
+ // {
+ // server.Stop();
+ // server = null;
+ // }
+ //}
+ //catch (Exception ex)
+ //{
+ // Utils.SaveLog("Webserver Stop " + ex.Message);
+ //}
+
+ //try
+ //{
+ // if (httpWebServer == null)
+ // {
+ // return;
+ // }
+ // foreach (var key in httpWebServer.Keys)
+ // {
+ // Utils.SaveLog("Webserver Stop " + key.ToString());
+ // ((HttpWebServer)httpWebServer[key]).Stop();
+ // }
+ // httpWebServer.Clear();
+ //}
+ //catch (Exception ex)
+ //{
+ // Utils.SaveLog("Webserver Stop " + ex.Message);
+ //}
+ }
+
+
+ private static string GetPacList(string address)
+ {
+ var port = Global.sysAgentPort;
+ if (port <= 0)
+ {
+ return "No port";
+ }
+ try
+ {
+ List lstProxy = new List();
+ lstProxy.Add(string.Format("PROXY {0}:{1};", address, port));
+ var proxy = string.Join("", lstProxy.ToArray());
+
+ string strPacfile = Utils.GetPath(Global.pacFILE);
+ if (!File.Exists(strPacfile))
+ {
+ FileManager.UncompressFile(strPacfile, Resources.pac_txt);
+ }
+ var pac = File.ReadAllText(strPacfile, Encoding.UTF8);
+ pac = pac.Replace("__PROXY__", proxy);
+ return pac;
+ }
+ catch
+ {
+ }
+ return "No pac content";
+ }
+
+ }
+}
diff --git a/v2rayN/v2rayN/HttpProxyHandler/PrivoxyHandler.cs b/v2rayN/v2rayN/HttpProxyHandler/PrivoxyHandler.cs
new file mode 100644
index 00000000..169ed1df
--- /dev/null
+++ b/v2rayN/v2rayN/HttpProxyHandler/PrivoxyHandler.cs
@@ -0,0 +1,215 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using v2rayN.Mode;
+using v2rayN.Properties;
+using v2rayN.Tool;
+
+namespace v2rayN.HttpProxyHandler
+{
+ ///
+ /// Privoxy处理类,提供http协议代理
+ ///
+ class PrivoxyHandler
+ {
+ ///
+ /// 单例
+ ///
+ private static PrivoxyHandler instance;
+
+ private static int _uid;
+ private static string _uniqueConfigFile;
+ private static Job _privoxyJob;
+ private Process _process;
+ private int _runningPort;
+ private bool _isRunning;
+
+ static PrivoxyHandler()
+ {
+ try
+ {
+ _uid = Application.StartupPath.GetHashCode(); // Currently we use ss's StartupPath to identify different Privoxy instance.
+ _uniqueConfigFile = string.Format("privoxy_{0}.conf", _uid);
+ _privoxyJob = new Job();
+
+ FileManager.UncompressFile(Utils.GetTempPath("v2ray_privoxy.exe"), Resources.privoxy_exe);
+ FileManager.UncompressFile(Utils.GetTempPath("mgwz.dll"), Resources.mgwz_dll);
+ }
+ catch (IOException ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ private PrivoxyHandler()
+ {
+
+ }
+
+ ///
+ /// 单例
+ ///
+ public static PrivoxyHandler Instance
+ {
+ get
+ {
+ if (instance == null)
+ {
+ instance = new PrivoxyHandler();
+ }
+ return instance;
+ }
+ }
+
+ public int RunningPort
+ {
+ get
+ {
+ return _runningPort;
+ }
+ }
+
+ public bool IsRunning
+ {
+ get
+ {
+ return _isRunning;
+ }
+ }
+
+ public void Start(int localPort, Config config)
+ {
+ if (_process == null)
+ {
+ Process[] existingPrivoxy = Process.GetProcessesByName("v2ray_privoxy");
+ foreach (Process p in existingPrivoxy.Where(IsChildProcess))
+ {
+ KillProcess(p);
+ }
+ string privoxyConfig = Resources.privoxy_conf;
+ _runningPort = GetFreePort(localPort);
+ privoxyConfig = privoxyConfig.Replace("__SOCKS_PORT__", localPort.ToString());
+ privoxyConfig = privoxyConfig.Replace("__PRIVOXY_BIND_PORT__", _runningPort.ToString());
+ if (config.allowLANConn)
+ {
+ privoxyConfig = privoxyConfig.Replace("__PRIVOXY_BIND_IP__", "0.0.0.0");
+ }
+ else
+ {
+ privoxyConfig = privoxyConfig.Replace("__PRIVOXY_BIND_IP__", "127.0.0.1");
+ }
+ FileManager.ByteArrayToFile(Utils.GetTempPath(_uniqueConfigFile), Encoding.UTF8.GetBytes(privoxyConfig));
+
+ _process = new Process
+ {
+ // Configure the process using the StartInfo properties.
+ StartInfo =
+ {
+ FileName = "v2ray_privoxy.exe",
+ Arguments = _uniqueConfigFile,
+ WorkingDirectory = Utils.GetTempPath(),
+ WindowStyle = ProcessWindowStyle.Hidden,
+ UseShellExecute = true,
+ CreateNoWindow = true
+ }
+ };
+ _process.Start();
+
+ /*
+ * Add this process to job obj associated with this ss process, so that
+ * when ss exit unexpectedly, this process will be forced killed by system.
+ */
+ _privoxyJob.AddProcess(_process.Handle);
+ _isRunning = true;
+ }
+ }
+
+ public void Stop()
+ {
+ if (_process != null)
+ {
+ KillProcess(_process);
+ _process.Dispose();
+ _process = null;
+ _isRunning = false;
+ }
+ }
+
+ private static void KillProcess(Process p)
+ {
+ try
+ {
+ p.CloseMainWindow();
+ p.WaitForExit(100);
+ if (!p.HasExited)
+ {
+ p.Kill();
+ p.WaitForExit();
+ }
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ }
+ }
+
+ /*
+ * We won't like to kill other ss instances' v2ray_privoxy.exe.
+ * This function will check whether the given process is created
+ * by this process by checking the module path or command line.
+ *
+ * Since it's required to put ss in different dirs to run muti instances,
+ * different instance will create their unique "privoxy_UID.conf" where
+ * UID is hash of ss's location.
+ */
+
+ private static bool IsChildProcess(Process process)
+ {
+ try
+ {
+ /*
+ * Under PortableMode, we could identify it by the path of v2ray_privoxy.exe.
+ */
+ var path = process.MainModule.FileName;
+
+ return Utils.GetTempPath("v2ray_privoxy.exe").Equals(path);
+
+ }
+ catch (Exception ex)
+ {
+ Utils.SaveLog(ex.Message, ex);
+ /*
+ * Sometimes Process.GetProcessesByName will return some processes that
+ * are already dead, and that will cause exceptions here.
+ * We could simply ignore those exceptions.
+ */
+ //Logging.LogUsefulException(ex);
+ return false;
+ }
+ }
+
+ private int GetFreePort(int localPort)
+ {
+ int defaultPort = 8123;
+ try
+ {
+ //// TCP stack please do me a favor
+ //TcpListener l = new TcpListener(IPAddress.Loopback, 0);
+ //l.Start();
+ //var port = ((IPEndPoint)l.LocalEndpoint).Port;
+ //l.Stop();
+ //return port;
+ return localPort + 1;
+ }
+ catch (Exception ex)
+ {
+ // in case access denied
+ Utils.SaveLog(ex.Message, ex);
+ return defaultPort;
+ }
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/HttpProxyHandler/ProxySetting.cs b/v2rayN/v2rayN/HttpProxyHandler/ProxySetting.cs
new file mode 100644
index 00000000..638a1131
--- /dev/null
+++ b/v2rayN/v2rayN/HttpProxyHandler/ProxySetting.cs
@@ -0,0 +1,187 @@
+using Microsoft.Win32;
+using System;
+using System.Runtime.InteropServices;
+
+namespace v2rayN.HttpProxyHandler
+{
+ class ProxySetting
+ {
+ public static bool UnsetProxy()
+ {
+ return SetProxy(null, null);
+ }
+ public static bool SetProxy(string strProxy)
+ {
+ return SetProxy(strProxy, null);
+ }
+
+ public static bool SetProxy(string strProxy, string exceptions)
+ {
+ InternetPerConnOptionList list = new InternetPerConnOptionList();
+
+ int optionCount = Utils.IsNullOrEmpty(strProxy) ? 1 : (Utils.IsNullOrEmpty(exceptions) ? 2 : 3);
+ InternetConnectionOption[] options = new InternetConnectionOption[optionCount];
+ // USE a proxy server ...
+ options[0].m_Option = PerConnOption.INTERNET_PER_CONN_FLAGS;
+ options[0].m_Value.m_Int = (int)((optionCount < 2) ? PerConnFlags.PROXY_TYPE_DIRECT : (PerConnFlags.PROXY_TYPE_DIRECT | PerConnFlags.PROXY_TYPE_PROXY));
+ // use THIS proxy server
+ if (optionCount > 1)
+ {
+ options[1].m_Option = PerConnOption.INTERNET_PER_CONN_PROXY_SERVER;
+ options[1].m_Value.m_StringPtr = Marshal.StringToHGlobalAuto(strProxy);
+ // except for these addresses ...
+ if (optionCount > 2)
+ {
+ options[2].m_Option = PerConnOption.INTERNET_PER_CONN_PROXY_BYPASS;
+ options[2].m_Value.m_StringPtr = Marshal.StringToHGlobalAuto(exceptions);
+ }
+ }
+
+ // default stuff
+ list.dwSize = Marshal.SizeOf(list);
+ list.szConnection = IntPtr.Zero;
+ list.dwOptionCount = options.Length;
+ list.dwOptionError = 0;
+
+
+ int optSize = Marshal.SizeOf(typeof(InternetConnectionOption));
+ // make a pointer out of all that ...
+ IntPtr optionsPtr = Marshal.AllocCoTaskMem(optSize * options.Length);
+ // copy the array over into that spot in memory ...
+ for (int i = 0; i < options.Length; ++i)
+ {
+ IntPtr opt = new IntPtr(optionsPtr.ToInt32() + (i * optSize));
+ Marshal.StructureToPtr(options[i], opt, false);
+ }
+
+ list.options = optionsPtr;
+
+ // and then make a pointer out of the whole list
+ IntPtr ipcoListPtr = Marshal.AllocCoTaskMem((Int32)list.dwSize);
+ Marshal.StructureToPtr(list, ipcoListPtr, false);
+
+ // and finally, call the API method!
+ int returnvalue = NativeMethods.InternetSetOption(IntPtr.Zero,
+ InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION,
+ ipcoListPtr, list.dwSize) ? -1 : 0;
+ if (returnvalue == 0)
+ { // get the error codes, they might be helpful
+ returnvalue = Marshal.GetLastWin32Error();
+ }
+ // FREE the data ASAP
+ Marshal.FreeCoTaskMem(optionsPtr);
+ Marshal.FreeCoTaskMem(ipcoListPtr);
+ if (returnvalue > 0)
+ { // throw the error codes, they might be helpful
+ //throw new Win32Exception(Marshal.GetLastWin32Error());
+ }
+
+ return (returnvalue < 0);
+ }
+
+
+ #region WinInet structures
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public struct InternetPerConnOptionList
+ {
+ public int dwSize; // size of the INTERNET_PER_CONN_OPTION_LIST struct
+ public IntPtr szConnection; // connection name to set/query options
+ public int dwOptionCount; // number of options to set/query
+ public int dwOptionError; // on error, which option failed
+ //[MarshalAs(UnmanagedType.)]
+ public IntPtr options;
+ };
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public struct InternetConnectionOption
+ {
+ static readonly int Size;
+ public PerConnOption m_Option;
+ public InternetConnectionOptionValue m_Value;
+ static InternetConnectionOption()
+ {
+ InternetConnectionOption.Size = Marshal.SizeOf(typeof(InternetConnectionOption));
+ }
+
+ // Nested Types
+ [StructLayout(LayoutKind.Explicit)]
+ public struct InternetConnectionOptionValue
+ {
+ // Fields
+ [FieldOffset(0)]
+ public System.Runtime.InteropServices.ComTypes.FILETIME m_FileTime;
+ [FieldOffset(0)]
+ public int m_Int;
+ [FieldOffset(0)]
+ public IntPtr m_StringPtr;
+ }
+ }
+ #endregion
+
+ #region WinInet enums
+ //
+ // options manifests for Internet{Query|Set}Option
+ //
+ public enum InternetOption : uint
+ {
+ INTERNET_OPTION_PER_CONNECTION_OPTION = 75
+ }
+
+ //
+ // Options used in INTERNET_PER_CONN_OPTON struct
+ //
+ public enum PerConnOption
+ {
+ INTERNET_PER_CONN_FLAGS = 1, // Sets or retrieves the connection type. The Value member will contain one or more of the values from PerConnFlags
+ INTERNET_PER_CONN_PROXY_SERVER = 2, // Sets or retrieves a string containing the proxy servers.
+ INTERNET_PER_CONN_PROXY_BYPASS = 3, // Sets or retrieves a string containing the URLs that do not use the proxy server.
+ INTERNET_PER_CONN_AUTOCONFIG_URL = 4//, // Sets or retrieves a string containing the URL to the automatic configuration script.
+
+ }
+
+ //
+ // PER_CONN_FLAGS
+ //
+ [Flags]
+ public enum PerConnFlags
+ {
+ PROXY_TYPE_DIRECT = 0x00000001, // direct to net
+ PROXY_TYPE_PROXY = 0x00000002, // via named proxy
+ PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, // autoproxy URL
+ PROXY_TYPE_AUTO_DETECT = 0x00000008 // use autoproxy detection
+ }
+ #endregion
+
+ internal static class NativeMethods
+ {
+ [DllImport("WinInet.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool InternetSetOption(IntPtr hInternet, InternetOption dwOption, IntPtr lpBuffer, int dwBufferLength);
+ }
+
+ //判断是否使用代理
+ public static bool UsedProxy()
+ {
+ RegistryKey rk = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings", true);
+ if (rk.GetValue("ProxyEnable").ToString() == "1")
+ {
+ rk.Close();
+ return true;
+ }
+ else
+ {
+ rk.Close();
+ return false;
+ }
+ }
+ //获得代理的IP和端口
+ public static string GetProxyProxyServer()
+ {
+ RegistryKey rk = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings", true);
+ string ProxyServer = rk.GetValue("ProxyServer").ToString();
+ rk.Close();
+ return ProxyServer;
+
+ }
+ }
+}
diff --git a/v2rayN/v2rayN/HttpProxyHandler/SysProxyHandle.cs b/v2rayN/v2rayN/HttpProxyHandler/SysProxyHandle.cs
new file mode 100644
index 00000000..a2397740
--- /dev/null
+++ b/v2rayN/v2rayN/HttpProxyHandler/SysProxyHandle.cs
@@ -0,0 +1,182 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+using Newtonsoft.Json;
+using v2rayN.Mode;
+using v2rayN.Properties;
+using v2rayN.Tool;
+
+namespace v2rayN.HttpProxyHandler
+{
+ class SysProxyHandle
+ {
+ private const string _userWininetConfigFile = "user-wininet.json";
+
+ private static string _queryStr;
+
+ // In general, this won't change
+ // format:
+ //
+ //
+ //
+ //