Update VAR.Json

This commit is contained in:
2016-12-06 02:42:46 +01:00
parent 3498ada6ff
commit 1d3929a147
9 changed files with 278 additions and 138 deletions

View File

@@ -28,7 +28,7 @@ namespace VAR.Focus.Web.Code.BusinessLogic
public static List<T> LoadList<T>(string file, List<Type> types) public static List<T> LoadList<T>(string file, List<Type> types)
{ {
List<T> listResult = new List<T>(); List<T> listResult = new List<T>();
JSONParser parser = new JSONParser(); JsonParser parser = new JsonParser();
Type typeResult = typeof(T); Type typeResult = typeof(T);
if (typeResult.IsInterface == false) if (typeResult.IsInterface == false)
{ {
@@ -62,7 +62,7 @@ namespace VAR.Focus.Web.Code.BusinessLogic
public static bool SaveList(string file, object data) public static bool SaveList(string file, object data)
{ {
JSONWriter writter = new JSONWriter(true); JsonWriter writter = new JsonWriter(true);
string strJsonUsers = writter.Write(data); string strJsonUsers = writter.Write(data);
string filePath = GetLocalPath(string.Format("priv/{0}.json", file)); string filePath = GetLocalPath(string.Format("priv/{0}.json", file));
File.WriteAllText(filePath, strJsonUsers); File.WriteAllText(filePath, strJsonUsers);

View File

@@ -21,7 +21,7 @@ namespace VAR.Focus.Web.Code
public static void ResponseObject(this HttpContext context, object obj) public static void ResponseObject(this HttpContext context, object obj)
{ {
var jsonWritter = new JSONWriter(true); var jsonWritter = new JsonWriter(true);
context.Response.ContentType = "text/json"; context.Response.ContentType = "text/json";
string strObject = jsonWritter.Write(obj); string strObject = jsonWritter.Write(obj);
context.Response.Write(strObject); context.Response.Write(strObject);

View File

@@ -1,20 +1,23 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
namespace VAR.Focus.Web.Code.JSON namespace VAR.Focus.Web.Code.JSON
{ {
public class JSONParser public class JsonParser
{ {
#region Declarations #region Declarations
private const int MaxRecursiveCount = 20;
private ParserContext _ctx; private ParserContext _ctx;
private bool _tainted = false; private bool _tainted = false;
private List<Type> _knownTypes = new List<Type>(); private List<Type> _knownTypes = new List<Type>();
#endregion #endregion Declarations
#region Properties #region Properties
@@ -28,7 +31,7 @@ namespace VAR.Focus.Web.Code.JSON
get { return _knownTypes; } get { return _knownTypes; }
} }
#endregion #endregion Properties
#region Private methods #region Private methods
@@ -40,8 +43,8 @@ namespace VAR.Focus.Web.Code.JSON
if (_dictProperties.ContainsKey(type)) { typeProperties = _dictProperties[type]; } if (_dictProperties.ContainsKey(type)) { typeProperties = _dictProperties[type]; }
else else
{ {
lock(_dictProperties){ lock (_dictProperties)
{
if (_dictProperties.ContainsKey(type)) { typeProperties = _dictProperties[type]; } if (_dictProperties.ContainsKey(type)) { typeProperties = _dictProperties[type]; }
else else
{ {
@@ -64,7 +67,7 @@ namespace VAR.Focus.Web.Code.JSON
count++; count++;
} }
} }
return ((float)count / typeProperties.Length); return ((float)count / (float)typeProperties.Length);
} }
private object ConvertToType(Dictionary<string, object> obj, Type type) private object ConvertToType(Dictionary<string, object> obj, Type type)
@@ -172,32 +175,116 @@ namespace VAR.Focus.Web.Code.JSON
{ {
scratch.Append((char)ParseHexShort()); scratch.Append((char)ParseHexShort());
} }
else
{
// StrictRules: Mark as tainted on unknown escaped character
_tainted = true;
}
c = _ctx.Next(); c = _ctx.Next();
} }
else if (c == '"') else if (c == '"')
{ {
_ctx.Next();
break; break;
} }
else else
{ {
// StrictRules: Mark as tainted on ilegal characters
if (c == '\t' || c == '\n') { _tainted = true; }
scratch.Append(c); scratch.Append(c);
c = _ctx.Next(); c = _ctx.Next();
} }
} while (!_ctx.AtEnd()); } while (!_ctx.AtEnd());
if (c == '"')
{
_ctx.Next();
}
return scratch.ToString(); return scratch.ToString();
} }
private string ParseString() private string ParseSingleQuotedString()
{
StringBuilder scratch = new StringBuilder();
char c = _ctx.SkipWhite();
if (c == '\'')
{
c = _ctx.Next();
}
do
{
if (c == '\\')
{
c = _ctx.Next();
if (c == '\'')
{
scratch.Append('\'');
}
else if (c == '\\')
{
scratch.Append('\\');
}
else if (c == '/')
{
scratch.Append('/');
}
else if (c == 'b')
{
scratch.Append('\b');
}
else if (c == 'f')
{
scratch.Append('\f');
}
else if (c == 'n')
{
scratch.Append('\n');
}
else if (c == 'r')
{
scratch.Append('\r');
}
else if (c == 't')
{
scratch.Append('\t');
}
else if (c == 'u')
{
scratch.Append((char)ParseHexShort());
}
else
{
// StrictRules: Mark as tainted on unknown escaped character
_tainted = true;
}
c = _ctx.Next();
}
else if (c == '\'')
{
_ctx.Next();
break;
}
else
{
// StrictRules: Mark as tainted on ilegal characters
if (c == '\t' || c == '\n') { _tainted = true; }
scratch.Append(c);
c = _ctx.Next();
}
} while (!_ctx.AtEnd());
return scratch.ToString();
}
private string ParseString(bool mustBeQuoted = false)
{ {
char c = _ctx.SkipWhite(); char c = _ctx.SkipWhite();
if (c == '"') if (c == '"')
{ {
return ParseQuotedString(); return ParseQuotedString();
} }
if (c == '\'')
{
_tainted = true;
return ParseSingleQuotedString();
}
if (mustBeQuoted) { _tainted = true; }
StringBuilder scratch = new StringBuilder(); StringBuilder scratch = new StringBuilder();
while (!_ctx.AtEnd() while (!_ctx.AtEnd()
@@ -214,7 +301,9 @@ namespace VAR.Focus.Web.Code.JSON
{ {
StringBuilder scratch = new StringBuilder(); StringBuilder scratch = new StringBuilder();
bool isFloat = false; bool isFloat = false;
bool isExp = false;
int numberLenght = 0; int numberLenght = 0;
int expLenght = 0;
char c; char c;
c = _ctx.SkipWhite(); c = _ctx.SkipWhite();
@@ -226,18 +315,30 @@ namespace VAR.Focus.Web.Code.JSON
} }
// Integer part // Integer part
bool leadingZeroes = true;
int leadingZeroesLenght = 0;
while (char.IsDigit(c)) while (char.IsDigit(c))
{ {
// Count leading zeroes
if (leadingZeroes && c == '0') { leadingZeroesLenght++; }
else { leadingZeroes = false; }
scratch.Append(c); scratch.Append(c);
c = _ctx.Next(); c = _ctx.Next();
numberLenght++; numberLenght++;
} }
// StrictRules: Mark as tainted with leading zeroes
if ((leadingZeroesLenght > 0 && leadingZeroesLenght != numberLenght) || leadingZeroesLenght > 1)
{
_tainted = true;
}
// Decimal part // Decimal part
if (c == '.') if (c == '.')
{ {
isFloat = true; isFloat = true;
scratch.Append('.'); scratch.Append(".");
c = _ctx.Next(); c = _ctx.Next();
while (char.IsDigit(c)) while (char.IsDigit(c))
{ {
@@ -257,105 +358,169 @@ namespace VAR.Focus.Web.Code.JSON
if (c == 'e' || c == 'E') if (c == 'e' || c == 'E')
{ {
isFloat = true; isFloat = true;
isExp = true;
scratch.Append('E'); scratch.Append('E');
c = _ctx.Next(); c = _ctx.Next();
if (c == '+' || c == '-') if (c == '+' || c == '-')
{ {
scratch.Append(c); scratch.Append(c);
c = _ctx.Next();
} }
while (char.IsDigit(c)) while (char.IsDigit(c))
{ {
scratch.Append(c); scratch.Append(c);
c = _ctx.Next(); c = _ctx.Next();
numberLenght++; numberLenght++;
expLenght++;
} }
} }
// Build number object from the parsed string if (isExp && expLenght == 0)
{
_tainted = true;
return null;
}
// Build number from the parsed string
string s = scratch.ToString(); string s = scratch.ToString();
return isFloat ? (numberLenght < 17) ? (object)double.Parse(s) if (isFloat)
: decimal.Parse(s) : (numberLenght < 19) ? int.Parse(s) {
: (object)int.Parse(s); if (numberLenght < 17)
{
return Convert.ToDouble(s, CultureInfo.InvariantCulture);
}
else
{
return Convert.ToDecimal(s, CultureInfo.InvariantCulture);
}
}
else
{
return Convert.ToInt32(s);
}
} }
private List<object> ParseArray() private List<object> ParseArray(int recursiveCount = 1)
{ {
// StrictRules: Mark as tainted when MaxRecursiveCount is exceeded
if (recursiveCount >= MaxRecursiveCount) { _tainted = true; }
bool correct = false;
char c = _ctx.SkipWhite(); char c = _ctx.SkipWhite();
List<object> array = new List<object>(); List<object> array = new List<object>();
if (c == '[') if (c == '[')
{ {
_ctx.Next(); _ctx.Next();
} }
bool? expectValue = null;
do do
{ {
c = _ctx.SkipWhite(); c = _ctx.SkipWhite();
if (c == ']') if (c == ']')
{ {
// StrictRules: Mark as tainted when unexpected end of array
if (expectValue == true) { _tainted = true; }
correct = true;
_ctx.Next(); _ctx.Next();
break; break;
} }
else if (c == ',') else if (c == ',')
{ {
// StrictRules: Mark as tainted when unexpected comma on array
if (expectValue == true || array.Count == 0) { _tainted = true; }
_ctx.Next(); _ctx.Next();
expectValue = true;
} }
else else
{ {
array.Add(ParseValue()); // StrictRules: Mark as tainted when unexpected value on array
if (expectValue == false) { _tainted = true; }
array.Add(ParseValue(recursiveCount + 1));
expectValue = false;
} }
} while (!_ctx.AtEnd()); } while (!_ctx.AtEnd());
if (correct == false)
{
_tainted = true;
}
return array; return array;
} }
private Dictionary<string, object> ParseObject() private Dictionary<string, object> ParseObject(int recursiveCount = 1)
{ {
// StrictRules: Mark as tainted when MaxRecursiveCount is exceeded
if (recursiveCount >= MaxRecursiveCount) { _tainted = true; }
bool correct = false;
char c = _ctx.SkipWhite(); char c = _ctx.SkipWhite();
Dictionary<string, object> obj = new Dictionary<string, object>(); Dictionary<string, object> obj = new Dictionary<string, object>();
if (c == '{') if (c == '{')
{ {
_ctx.Next(); _ctx.Next();
c = _ctx.SkipWhite();
} }
string attributeName; string attributeName = null;
object attributeValue; object attributeValue;
bool? expectedKey = null;
bool? expectedValue = null;
do do
{ {
attributeName = ParseString();
c = _ctx.SkipWhite(); c = _ctx.SkipWhite();
if (c == ':') if (c == ':')
{ {
_ctx.Next(); _ctx.Next();
attributeValue = ParseValue(); if (expectedValue == true)
if (attributeName.Length > 0)
{ {
attributeValue = ParseValue(recursiveCount + 1);
obj.Add(attributeName, attributeValue); obj.Add(attributeName, attributeValue);
expectedKey = null;
expectedValue = false;
} }
} }
else if (c == ',') else if (c == ',')
{ {
_ctx.Next(); _ctx.Next();
c = _ctx.SkipWhite(); c = _ctx.SkipWhite();
expectedKey = true;
expectedValue = false;
} }
else if (c == '}') else if (c == '}')
{ {
// StrictRules: Mark as tainted on unexpected end of object
if (expectedValue == true || expectedKey == true)
{
_tainted = true;
}
correct = true;
_ctx.Next(); _ctx.Next();
break; break;
} }
else else
{ {
// Unexpected character if (expectedKey != false)
_tainted = true; {
break; attributeName = ParseString(true);
c = _ctx.SkipWhite();
expectedKey = false;
expectedValue = true;
}
else
{
// Unexpected character
_tainted = true;
break;
}
} }
} while (!_ctx.AtEnd()); } while (!_ctx.AtEnd());
if (obj.Count == 0) if (correct == false)
{ {
return null; _tainted = true;
} }
return obj; return obj;
} }
private object ParseValue() private object ParseValue(int recusiveCount = 1)
{ {
object token = null; object token = null;
char c = _ctx.SkipWhite(); char c = _ctx.SkipWhite();
@@ -364,13 +529,22 @@ namespace VAR.Focus.Web.Code.JSON
case '"': case '"':
token = ParseQuotedString(); token = ParseQuotedString();
break; break;
case '\'':
// StrictRules: Mark as tainted when parsing single quoted strings
_tainted = true;
token = ParseSingleQuotedString();
break;
case '{': case '{':
Dictionary<string, object> obj = ParseObject(); Dictionary<string, object> obj = ParseObject(recusiveCount);
token = TryConvertToTypes(obj); token = TryConvertToTypes(obj);
break; break;
case '[': case '[':
token = ParseArray(); token = ParseArray(recusiveCount);
break; break;
default: default:
if (char.IsDigit(c) || c == '-') if (char.IsDigit(c) || c == '-')
{ {
@@ -429,7 +603,7 @@ namespace VAR.Focus.Web.Code.JSON
return input.Substring(i + 1); return input.Substring(i + 1);
} }
#endregion #endregion Private methods
#region Public methods #region Public methods
@@ -440,60 +614,24 @@ namespace VAR.Focus.Web.Code.JSON
_tainted = false; _tainted = false;
_ctx.Mark(); _ctx.Mark();
object obj = ParseValue(); object obj = ParseValue();
_ctx.SkipWhite();
if (_ctx.AtEnd()) if (_ctx.AtEnd())
{ {
// StrictRules: Mark as tainted when top level is not object or array
if (obj is string || obj is decimal || obj is int || obj is double || obj is float)
{
_tainted = true;
}
return obj; return obj;
} }
// "But wait, there is more!" // StrictRules: Mark as tainted when there is more content
int idx = 0; _tainted = true;
string name = "";
string strInvalidPrev = "";
Dictionary<string, object> superObject = new Dictionary<string, object>();
do
{
// Add the object to the superObject
if (!_tainted && name.Length > 0 && obj != null)
{
if (name.Length == 0)
{
name = string.Format("{0:D2}", idx);
}
superObject.Add(name, obj);
idx++;
name = "";
}
else
{
string strInvalid = _ctx.GetMarked();
strInvalid = strInvalid.Trim();
if (strInvalidPrev.Length > 0
&& "=".CompareTo(strInvalid) == 0)
{
name = CleanIdentifier(strInvalidPrev);
}
else
{
name = "";
}
strInvalidPrev = strInvalid;
}
// Check end return obj;
if (_ctx.AtEnd())
{
break;
}
// Get next object
_tainted = false;
_ctx.Mark();
obj = ParseValue();
} while (true);
return superObject;
} }
#endregion #endregion Public methods
} }
} }

View File

@@ -6,7 +6,7 @@ using System.Text;
namespace VAR.Focus.Web.Code.JSON namespace VAR.Focus.Web.Code.JSON
{ {
public class JSONWriter public class JsonWriter
{ {
#region Declarations #region Declarations
@@ -15,38 +15,40 @@ namespace VAR.Focus.Web.Code.JSON
private int _indentChars = 4; private int _indentChars = 4;
private int _indentThresold = 3; private int _indentThresold = 3;
#endregion #endregion Declarations
#region Creator #region Creator
public JSONWriter() { } public JsonWriter()
public JSONWriter(int indentChars)
{ {
_indent = true;
_indentChars = indentChars;
_useTabForIndent = false;
} }
public JSONWriter(bool useTabForIndent) public JsonWriter(int indentChars)
{ {
_indent = true; this._indent = true;
_useTabForIndent = useTabForIndent; this._indentChars = indentChars;
this._useTabForIndent = false;
} }
#endregion public JsonWriter(bool useTabForIndent)
{
this._indent = true;
this._useTabForIndent = useTabForIndent;
}
#endregion Creator
#region Private methods #region Private methods
private bool IsValue(object obj) private bool IsValue(Object obj)
{ {
if (obj == null) if (obj == null)
{ {
return true; return true;
} }
if ((obj is float) || (obj is double) || if ((obj is float) || (obj is double) ||
(obj is short) || (obj is int) || (obj is long) (obj is System.Int16) || (obj is System.Int32) || (obj is System.Int64)
|| (obj is string) || (obj is bool)) || (obj is String) || (obj is Boolean))
{ {
return true; return true;
} }
@@ -87,8 +89,8 @@ namespace VAR.Focus.Web.Code.JSON
else if (c == '\n') { sbOutput.Append("\\n"); } else if (c == '\n') { sbOutput.Append("\\n"); }
else if (c == '\r') { sbOutput.Append("\\r"); } else if (c == '\r') { sbOutput.Append("\\r"); }
else if (c == '\t') { sbOutput.Append("\\t"); } else if (c == '\t') { sbOutput.Append("\\t"); }
else if (c < 32 || c >= 127) { sbOutput.AppendFormat("\\u{0:X04}", (int)c); }
else { sbOutput.Append(c); } else { sbOutput.Append(c); }
// FIXME: Unicode characters
} }
sbOutput.Append('"'); sbOutput.Append('"');
} }
@@ -101,20 +103,20 @@ namespace VAR.Focus.Web.Code.JSON
sbOutput.Append("null"); sbOutput.Append("null");
} }
else if ((obj is float) || (obj is double) || else if ((obj is float) || (obj is double) ||
(obj is short) || (obj is int) || (obj is long)) (obj is System.Int16) || (obj is System.Int32) || (obj is System.Int64))
{ {
// Numbers // Numbers
sbOutput.Append(obj.ToString()); sbOutput.Append(obj.ToString());
} }
else if (obj is string) else if (obj is String)
{ {
// Strings // Strings
WriteString(sbOutput, (string)obj); WriteString(sbOutput, (String)obj);
} }
else if (obj is bool) else if (obj is Boolean)
{ {
// Booleans // Booleans
sbOutput.Append(((bool)obj) ? "true" : "false"); sbOutput.Append(((Boolean)obj) ? "true" : "false");
} }
else if (obj is DateTime) else if (obj is DateTime)
{ {
@@ -147,7 +149,7 @@ namespace VAR.Focus.Web.Code.JSON
} }
} }
private void WriteList(StringBuilder sbOutput, object obj, int level) private void WriteList(StringBuilder sbOutput, Object obj, int level)
{ {
IEnumerable list = (IEnumerable)obj; IEnumerable list = (IEnumerable)obj;
int n = 0; int n = 0;
@@ -197,7 +199,7 @@ namespace VAR.Focus.Web.Code.JSON
sbOutput.Append(" ]"); sbOutput.Append(" ]");
} }
private void WriteObject(StringBuilder sbOutput, object obj, int level) private void WriteObject(StringBuilder sbOutput, Object obj, int level)
{ {
IDictionary map = (IDictionary)obj; IDictionary map = (IDictionary)obj;
int n = map.Count; int n = map.Count;
@@ -250,7 +252,7 @@ namespace VAR.Focus.Web.Code.JSON
sbOutput.Append(" }"); sbOutput.Append(" }");
} }
private void WriteReflectedObject(StringBuilder sbOutput, object obj, int level) private void WriteReflectedObject(StringBuilder sbOutput, Object obj, int level)
{ {
Type type = obj.GetType(); Type type = obj.GetType();
PropertyInfo[] rawProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); PropertyInfo[] rawProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
@@ -319,17 +321,17 @@ namespace VAR.Focus.Web.Code.JSON
sbOutput.Append(" }"); sbOutput.Append(" }");
} }
#endregion #endregion Private methods
#region Public methods #region Public methods
public string Write(object obj) public String Write(Object obj)
{ {
StringBuilder sbOutput = new StringBuilder(); StringBuilder sbOutput = new StringBuilder();
WriteValue(sbOutput, obj, 0, true); WriteValue(sbOutput, obj, 0, true);
return sbOutput.ToString(); return sbOutput.ToString();
} }
#endregion #endregion Public methods
} }
} }

View File

@@ -6,71 +6,71 @@ namespace VAR.Focus.Web.Code.JSON
{ {
#region Declarations #region Declarations
private string text; private string _text;
private int length; private int _length;
private int i; private int _i;
private int markStart; private int _markStart;
#endregion #endregion Declarations
#region Creator #region Creator
public ParserContext(string text) public ParserContext(string text)
{ {
this.text = text; _text = text;
length = text.Length; _length = text.Length;
i = 0; _i = 0;
markStart = 0; _markStart = 0;
} }
#endregion #endregion Creator
#region Public methods #region Public methods
public char SkipWhite() public char SkipWhite()
{ {
while (i < length && char.IsWhiteSpace(text[i])) while (_i < _length && char.IsWhiteSpace(_text[_i]))
{ {
i++; _i++;
} }
if (AtEnd()) if (AtEnd())
{ {
return (char)0; return (char)0;
} }
return text[i]; return _text[_i];
} }
public char Next() public char Next()
{ {
i++; _i++;
if (AtEnd()) if (AtEnd())
{ {
return (char)0; return (char)0;
} }
return text[i]; return _text[_i];
} }
public bool AtEnd() public bool AtEnd()
{ {
return i >= length; return _i >= _length;
} }
public void Mark() public void Mark()
{ {
markStart = i; _markStart = _i;
} }
public string GetMarked() public string GetMarked()
{ {
if (i < length && markStart < length) if (_i < _length && _markStart < _length)
{ {
return text.Substring(markStart, i); return _text.Substring(_markStart, _i - _markStart);
} }
else else
{ {
if (markStart < length) if (_markStart < _length)
{ {
return text.Substring(markStart, length); return _text.Substring(_markStart, _length - _markStart);
} }
else else
{ {
@@ -79,6 +79,6 @@ namespace VAR.Focus.Web.Code.JSON
} }
} }
#endregion #endregion Public methods
} }
} }

View File

@@ -114,7 +114,7 @@ namespace VAR.Focus.Web.Controls
{"ConfirmDelete", "Are you sure to delete?"}, {"ConfirmDelete", "Are you sure to delete?"},
} }, } },
}; };
JSONWriter jsonWriter = new JSONWriter(); JsonWriter jsonWriter = new JsonWriter();
StringBuilder sbCfg = new StringBuilder(); StringBuilder sbCfg = new StringBuilder();
sbCfg.AppendFormat("<script>\n"); sbCfg.AppendFormat("<script>\n");
sbCfg.AppendFormat("var {0} = {1};\n", strCfgName, jsonWriter.Write(cfg)); sbCfg.AppendFormat("var {0} = {1};\n", strCfgName, jsonWriter.Write(cfg));

View File

@@ -155,7 +155,7 @@ namespace VAR.Focus.Web.Controls
{"Disconnected", "Disconnected"}, {"Disconnected", "Disconnected"},
} }, } },
}; };
JSONWriter jsonWriter = new JSONWriter(); JsonWriter jsonWriter = new JsonWriter();
StringBuilder sbCfg = new StringBuilder(); StringBuilder sbCfg = new StringBuilder();
sbCfg.AppendFormat("<script>\n"); sbCfg.AppendFormat("<script>\n");
sbCfg.AppendFormat("var {0} = {1};\n", strCfgName, jsonWriter.Write(cfg)); sbCfg.AppendFormat("var {0} = {1};\n", strCfgName, jsonWriter.Write(cfg));

View File

@@ -14,7 +14,7 @@ namespace VAR.Focus.Web.Pages
public void ProcessRequest(HttpContext context) public void ProcessRequest(HttpContext context)
{ {
var jsonWritter = new JSONWriter(true); var jsonWritter = new JsonWriter(true);
context.Response.Write("<pre><code>"); context.Response.Write("<pre><code>");
context.Response.Write(jsonWritter.Write(context.Request)); context.Response.Write(jsonWritter.Write(context.Request));
context.Response.Write("</code></pre>"); context.Response.Write("</code></pre>");

View File

@@ -118,8 +118,8 @@
<Compile Include="Code\ScriptsBundler.cs" /> <Compile Include="Code\ScriptsBundler.cs" />
<Compile Include="Code\StylesBundler.cs" /> <Compile Include="Code\StylesBundler.cs" />
<Compile Include="GlobalRouter.cs" /> <Compile Include="GlobalRouter.cs" />
<Compile Include="Code\JSON\JSONParser.cs" /> <Compile Include="Code\JSON\JsonParser.cs" />
<Compile Include="Code\JSON\JSONWriter.cs" /> <Compile Include="Code\JSON\JsonWriter.cs" />
<Compile Include="Pages\FrmError.cs"> <Compile Include="Pages\FrmError.cs">
<SubType>ASPXCodeBehind</SubType> <SubType>ASPXCodeBehind</SubType>
</Compile> </Compile>