summaryrefslogtreecommitdiff
path: root/Data/DefaultContent/Libraries
diff options
context:
space:
mode:
Diffstat (limited to 'Data/DefaultContent/Libraries')
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Class.lua38
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Animation/Animation.lua0
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Animation/init.lua6
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Core/Camera.lua5
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Core/Component.lua11
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Core/Game.lua14
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Core/GameObject.lua7
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Core/Sprite.lua21
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/GL/init.lua20
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Math/Math.lua21
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Math/Matrix33.lua7
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Math/Matrix44.lua73
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Math/Quaternion.lua14
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Math/Vector2.lua5
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Math/Vector3.lua5
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Math/Vector4.lua45
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Math/init.lua16
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Rendering/Color.lua36
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Rendering/Color32.lua36
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Rendering/init.lua13
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Utils/EventCenter.lua23
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Utils/StateMachine.lua0
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/Utils/Util.lua0
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Engine/init.lua5
-rw-r--r--Data/DefaultContent/Libraries/GameLab/Enum.lua9
-rw-r--r--Data/DefaultContent/Libraries/GameLab/InternalClass.lua12
-rw-r--r--Data/DefaultContent/Libraries/GameLab/init.lua41
-rw-r--r--Data/DefaultContent/Libraries/LiteJson/LICENSE20
-rw-r--r--Data/DefaultContent/Libraries/LiteJson/README.md46
-rw-r--r--Data/DefaultContent/Libraries/LiteJson/bench/bench_all.lua6
-rw-r--r--Data/DefaultContent/Libraries/LiteJson/bench/bench_decode.lua75
-rw-r--r--Data/DefaultContent/Libraries/LiteJson/bench/bench_encode.lua63
-rw-r--r--Data/DefaultContent/Libraries/LiteJson/bench/get_json_libs.sh15
-rw-r--r--Data/DefaultContent/Libraries/LiteJson/bench/util/bench.lua62
-rw-r--r--Data/DefaultContent/Libraries/LiteJson/json.lua388
-rw-r--r--Data/DefaultContent/Libraries/LiteJson/test/test.lua245
-rw-r--r--Data/DefaultContent/Libraries/containers/README.md202
-rw-r--r--Data/DefaultContent/Libraries/containers/list.lua199
-rw-r--r--Data/DefaultContent/Libraries/containers/queue.lua111
-rw-r--r--Data/DefaultContent/Libraries/containers/stack.lua67
-rw-r--r--Data/DefaultContent/Libraries/containers/tuple.lua60
-rw-r--r--Data/DefaultContent/Libraries/containers/vector.lua122
-rw-r--r--Data/DefaultContent/Libraries/inspect/.travis.yml36
-rw-r--r--Data/DefaultContent/Libraries/inspect/CHANGELOG.md39
-rw-r--r--Data/DefaultContent/Libraries/inspect/MIT-LICENSE.txt20
-rw-r--r--Data/DefaultContent/Libraries/inspect/README.md253
-rw-r--r--Data/DefaultContent/Libraries/inspect/inspect.lua334
-rw-r--r--Data/DefaultContent/Libraries/inspect/rockspecs/inspect-1.2-2.rockspec23
-rw-r--r--Data/DefaultContent/Libraries/inspect/rockspecs/inspect-2.0-1.rockspec23
-rw-r--r--Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-1.rockspec23
-rw-r--r--Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-2.rockspec23
-rw-r--r--Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-3.rockspec23
-rw-r--r--Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-4.rockspec23
-rw-r--r--Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.1.1-0.rockspec23
-rw-r--r--Data/DefaultContent/Libraries/inspect/spec/inspect_spec.lua460
-rw-r--r--Data/DefaultContent/Libraries/inspect/spec/unindent.lua39
-rw-r--r--Data/DefaultContent/Libraries/json4lua/README.md52
-rw-r--r--Data/DefaultContent/Libraries/json4lua/doc/INSTALL.txt4
-rw-r--r--Data/DefaultContent/Libraries/json4lua/doc/LICENCE.txt21
-rw-r--r--Data/DefaultContent/Libraries/json4lua/doc/README.txt5
-rw-r--r--Data/DefaultContent/Libraries/json4lua/doc/VERSION.txt4
-rw-r--r--Data/DefaultContent/Libraries/json4lua/doc/cgilua_patch.html187
-rw-r--r--Data/DefaultContent/Libraries/json4lua/doc/index.html394
-rw-r--r--Data/DefaultContent/Libraries/json4lua/doc/pics/json4lua.gifbin0 -> 5023 bytes
-rw-r--r--Data/DefaultContent/Libraries/json4lua/doc/pics/lunartone.gifbin0 -> 312 bytes
-rw-r--r--Data/DefaultContent/Libraries/json4lua/examples/example.lua23
-rw-r--r--Data/DefaultContent/Libraries/json4lua/examples/jsonrpc.lua21
-rw-r--r--Data/DefaultContent/Libraries/json4lua/examples/tests.lua223
-rw-r--r--Data/DefaultContent/Libraries/json4lua/examples/timetrials.lua46
-rw-r--r--Data/DefaultContent/Libraries/json4lua/json/json.lua427
-rw-r--r--Data/DefaultContent/Libraries/json4lua/json/rpc.lua107
-rw-r--r--Data/DefaultContent/Libraries/json4lua/json/rpcserver.lua78
-rw-r--r--Data/DefaultContent/Libraries/json4lua/json4lua-1.0.0-1.rockspec32
-rw-r--r--Data/DefaultContent/Libraries/lbase64/.gitignore3
-rw-r--r--Data/DefaultContent/Libraries/lbase64/.travis.yml25
-rw-r--r--Data/DefaultContent/Libraries/lbase64/README.md48
-rw-r--r--Data/DefaultContent/Libraries/lbase64/base64.lua201
-rw-r--r--Data/DefaultContent/Libraries/lbase64/bench.lua76
-rw-r--r--Data/DefaultContent/Libraries/lbase64/rockspec/base64-1.5-1.rockspec20
-rw-r--r--Data/DefaultContent/Libraries/lbase64/rockspec/base64-1.5-2.rockspec20
-rw-r--r--Data/DefaultContent/Libraries/lbase64/rockspec/base64-1.5-3.rockspec20
-rw-r--r--Data/DefaultContent/Libraries/lbase64/test.lua47
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/.gitignore2
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/AUTHORS2
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/LICENSE22
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/README.md93
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/lua/config.ld4
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/lua/csv.lua557
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/lua/test.lua102
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/makefile14
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/rockspecs/csv-1-1.rockspec24
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/rockspecs/csv-scm-1.rockspec23
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/test-data/BOM.csv3
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/test-data/bars.txt7
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/test-data/blank-line.csv2
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/test-data/embedded-newlines.csv8
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/test-data/embedded-quotes.csv2
-rw-r--r--Data/DefaultContent/Libraries/lua-csv/test-data/header.csv3
-rw-r--r--Data/DefaultContent/Libraries/luafun/.gitignore4
-rw-r--r--Data/DefaultContent/Libraries/luafun/.travis.yml74
-rw-r--r--Data/DefaultContent/Libraries/luafun/CONTRIBUTING.md20
-rw-r--r--Data/DefaultContent/Libraries/luafun/COPYING.md27
-rw-r--r--Data/DefaultContent/Libraries/luafun/README.md107
-rw-r--r--Data/DefaultContent/Libraries/luafun/debian/.gitignore8
-rw-r--r--Data/DefaultContent/Libraries/luafun/debian/changelog5
-rw-r--r--Data/DefaultContent/Libraries/luafun/debian/compat1
-rw-r--r--Data/DefaultContent/Libraries/luafun/debian/control20
-rw-r--r--Data/DefaultContent/Libraries/luafun/debian/copyright31
-rw-r--r--Data/DefaultContent/Libraries/luafun/debian/lua-fun.docs1
-rw-r--r--Data/DefaultContent/Libraries/luafun/debian/lua5.1.dh-lua.conf4
-rw-r--r--Data/DefaultContent/Libraries/luafun/debian/lua5.2.dh-lua.conf1
-rw-r--r--Data/DefaultContent/Libraries/luafun/debian/lua5.3.dh-lua.conf1
-rw-r--r--Data/DefaultContent/Libraries/luafun/debian/patches/series0
-rw-r--r--Data/DefaultContent/Libraries/luafun/debian/rules12
-rw-r--r--Data/DefaultContent/Libraries/luafun/debian/source/format1
-rw-r--r--Data/DefaultContent/Libraries/luafun/debian/watch6
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/.gitignore1
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/Makefile153
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/_static/.keep0
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/_templates/layout.html14
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/about.rst42
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/basic.rst141
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/compositions.rst140
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/conf.py247
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/filtering.rst121
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/generators.rst233
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/getting_started.rst254
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/index.rst29
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/indexing.rst74
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/intro.rst69
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/logo.pngbin0 -> 14370 bytes
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/logo.svg758
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/make.bat190
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/operators.rst203
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/reducing.rst323
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/reference.rst14
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/slicing.rst246
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/transformations.rst87
-rw-r--r--Data/DefaultContent/Libraries/luafun/doc/under_the_hood.rst154
-rw-r--r--Data/DefaultContent/Libraries/luafun/fun-scm-1.rockspec34
-rw-r--r--Data/DefaultContent/Libraries/luafun/fun.lua1058
-rw-r--r--Data/DefaultContent/Libraries/luafun/rpm/lua-fun.spec76
-rw-r--r--Data/DefaultContent/Libraries/luafun/tests/.gitignore1
-rw-r--r--Data/DefaultContent/Libraries/luafun/tests/basic.lua332
-rw-r--r--Data/DefaultContent/Libraries/luafun/tests/compositions.lua170
-rw-r--r--Data/DefaultContent/Libraries/luafun/tests/filtering.lua102
-rw-r--r--Data/DefaultContent/Libraries/luafun/tests/generators.lua287
-rw-r--r--Data/DefaultContent/Libraries/luafun/tests/indexing.lua83
-rw-r--r--Data/DefaultContent/Libraries/luafun/tests/operators.lua322
-rw-r--r--Data/DefaultContent/Libraries/luafun/tests/reducing.lua289
-rw-r--r--Data/DefaultContent/Libraries/luafun/tests/runtest114
-rw-r--r--Data/DefaultContent/Libraries/luafun/tests/slicing.lua339
-rw-r--r--Data/DefaultContent/Libraries/luafun/tests/transformations.lua107
-rw-r--r--Data/DefaultContent/Libraries/md5.lua/.travis.yml34
-rw-r--r--Data/DefaultContent/Libraries/md5.lua/CHANGELOG.md5
-rw-r--r--Data/DefaultContent/Libraries/md5.lua/MIT-LICENSE.txt20
-rw-r--r--Data/DefaultContent/Libraries/md5.lua/README.md62
-rw-r--r--Data/DefaultContent/Libraries/md5.lua/md5.lua396
-rw-r--r--Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.0-0.rockspec21
-rw-r--r--Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.0-1.rockspec21
-rw-r--r--Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.0-2.rockspec21
-rw-r--r--Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.1-0.rockspec21
-rw-r--r--Data/DefaultContent/Libraries/md5.lua/spec/md5_spec.lua40
-rw-r--r--Data/DefaultContent/Libraries/middleclass/.travis.yml36
-rw-r--r--Data/DefaultContent/Libraries/middleclass/CHANGELOG.md55
-rw-r--r--Data/DefaultContent/Libraries/middleclass/MIT-LICENSE.txt20
-rw-r--r--Data/DefaultContent/Libraries/middleclass/README.md80
-rw-r--r--Data/DefaultContent/Libraries/middleclass/UPDATING.md69
-rw-r--r--Data/DefaultContent/Libraries/middleclass/middleclass.lua183
-rw-r--r--Data/DefaultContent/Libraries/middleclass/performance/run.lua43
-rw-r--r--Data/DefaultContent/Libraries/middleclass/performance/time.lua13
-rw-r--r--Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-3.0-0.rockspec21
-rw-r--r--Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-3.1-0.rockspec21
-rw-r--r--Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-3.2-0.rockspec21
-rw-r--r--Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-4.0-0.rockspec21
-rw-r--r--Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-4.1-0.rockspec21
-rw-r--r--Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-4.1.1-0.rockspec21
-rw-r--r--Data/DefaultContent/Libraries/middleclass/spec/class_spec.lua28
-rw-r--r--Data/DefaultContent/Libraries/middleclass/spec/classes_spec.lua138
-rw-r--r--Data/DefaultContent/Libraries/middleclass/spec/default_methods_spec.lua236
-rw-r--r--Data/DefaultContent/Libraries/middleclass/spec/instances_spec.lua65
-rw-r--r--Data/DefaultContent/Libraries/middleclass/spec/metamethods_lua_5_2.lua85
-rw-r--r--Data/DefaultContent/Libraries/middleclass/spec/metamethods_lua_5_3.lua106
-rw-r--r--Data/DefaultContent/Libraries/middleclass/spec/metamethods_spec.lua317
-rw-r--r--Data/DefaultContent/Libraries/middleclass/spec/mixins_spec.lua53
-rw-r--r--Data/DefaultContent/Libraries/socket/README.txt1
-rw-r--r--Data/DefaultContent/Libraries/socket/core.dllbin0 -> 104448 bytes
187 files changed, 15883 insertions, 0 deletions
diff --git a/Data/DefaultContent/Libraries/GameLab/Class.lua b/Data/DefaultContent/Libraries/GameLab/Class.lua
new file mode 100644
index 0000000..62369e1
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Class.lua
@@ -0,0 +1,38 @@
+-- Declare class
+
+local _class = function (className)
+ local class = {}
+ local pkgName = (type(className) == "string") and string.match(className, "^(.+)%.%w+$") or ""
+ local shortName = (type(className) == "string") and string.match(className, "%.*(%w+)$") or ""
+ class._type = { -- 类型元数æ®ï¼ŒGameLab的类型都会包å«è¿™äº›
+ mode = "lua",
+ name = shortName or "",
+ package = pkgName or "",
+ fullName = className
+ }
+ class.__index = class
+ class.New = function(...)
+ local instance = {}
+ setmetatable(instance, class)
+ instance:Ctor(...)
+ return instance
+ end
+ return class
+end
+
+-- æä¾›ClassNameå’ŒPkgName作为类型的元数æ®ï¼Œå¯ä»¥ç•™ç©ºï¼Œä½†æ˜¯æœ€å¥½æä¾›ï¼Œä¼šä½œä¸ºç±»åž‹åˆ¤æ–­çš„便®
+local Class = function(className)
+ local cls = _class(className)
+ cls.Extend = function(childName)
+ local child = _class(childName)
+ if cls then
+ setmetatable(child, cls)
+ child.base = cls
+ end
+ return child
+ end
+ return cls
+end
+
+GameLab.Class = Class
+return Class \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Animation/Animation.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Animation/Animation.lua
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Animation/Animation.lua
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Animation/init.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Animation/init.lua
new file mode 100644
index 0000000..032f42d
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Animation/init.lua
@@ -0,0 +1,6 @@
+GameLab.Animation = GameLab.Animation or {}
+local m = GameLab.Animation
+
+
+
+return m \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Core/Camera.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Core/Camera.lua
new file mode 100644
index 0000000..5fcfbe7
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Core/Camera.lua
@@ -0,0 +1,5 @@
+local Camera = {}
+
+
+
+return Camera \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Core/Component.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Core/Component.lua
new file mode 100644
index 0000000..00bf2ca
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Core/Component.lua
@@ -0,0 +1,11 @@
+local Component = {}
+
+Component.New = function()
+
+end
+
+Component.GetGameObject = function()
+
+end
+
+Jin.Component = Component \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Core/Game.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Core/Game.lua
new file mode 100644
index 0000000..51ce25f
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Core/Game.lua
@@ -0,0 +1,14 @@
+
+-- Game entry
+
+local Game = {}
+
+Game.OnEvent = function(e)
+
+end
+
+Game.MainLoop = function()
+
+end
+
+return Game \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Core/GameObject.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Core/GameObject.lua
new file mode 100644
index 0000000..ee0d143
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Core/GameObject.lua
@@ -0,0 +1,7 @@
+local GameObject = {}
+
+GameObject.AddComponent = function(self, comp)
+
+end
+
+Jin.GameObject = GameObject
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Core/Sprite.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Core/Sprite.lua
new file mode 100644
index 0000000..47cb50d
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Core/Sprite.lua
@@ -0,0 +1,21 @@
+-- ¶ÔQuadµÄ·â×°£¬¸üÄÜÊʺÏ2DÓÎÏ·¿ª·¢
+local Sprite = {}
+
+Sprite.New = function(quad)
+ local spr = {}
+ spr.quad = Jin.Quad.New(quad)
+ spr.pivot = Jin.Vector2.New(0.5, 0)
+ spr.transform = Jin.Transform.New()
+ spr.depth = 0
+ return spr
+end
+
+Sprite.SetDepth = function(self, depth)
+ spr.depth = depth
+end
+
+Sprite.SetTexture = function(self, tex, reset_quad)
+
+end
+
+Jin.Sprite = Sprite \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/GL/init.lua b/Data/DefaultContent/Libraries/GameLab/Engine/GL/init.lua
new file mode 100644
index 0000000..f69d1f6
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/GL/init.lua
@@ -0,0 +1,20 @@
+local GL = GameLab.Engine.GL or {}
+GameLab.Engine.GL = GL
+
+local Matrix44 = GameLab.find("GameLab.Engine.Math.Matrix44")
+
+GL.LoadPixelMatrix = function(l, r, b, t)
+ local ortho = Matrix44.New()
+ ortho:SetOrtho(l, r, b, t, 0.1, 10)
+ GL.MatrixMode(GL.EMatrixMode.Projection)
+ GL.LoadIdentity()
+ GL.LoadMatrix(ortho)
+ GL.MatrixMode(GL.EMatrixMode.ModelView)
+ GL.LoadIdentity()
+end
+
+GL.LoadPixelMatrixTL = function (l, r, b, t)
+
+end
+
+return GL \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Math/Math.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Math.lua
new file mode 100644
index 0000000..0bbe7f0
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Math.lua
@@ -0,0 +1,21 @@
+-- 数学函数
+local m = GameLab.Engine.Math or {}
+GameLab.Engine.Math = m
+
+m.Abs = function(n)
+
+end
+
+m.Lerp = function (a, b, t)
+
+end
+
+m.Round = function (n)
+
+end
+
+m.Sign = function(n)
+
+end
+
+return m \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Math/Matrix33.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Matrix33.lua
new file mode 100644
index 0000000..8cb7e72
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Matrix33.lua
@@ -0,0 +1,7 @@
+local Matrix33 = GameLab.Class("GameLab.Engine.Math.Matrix33")
+
+Matrix33.Ctor = function(self)
+
+end
+
+return Matrix33 \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Math/Matrix44.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Matrix44.lua
new file mode 100644
index 0000000..2347207
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Matrix44.lua
@@ -0,0 +1,73 @@
+local Matrix44 = GameLab.Class("GameLab.Engine.Math.Matrix44")
+
+Matrix44.Ctor = function(self)
+ for r = 0, 3 do
+ for c = 0, 3 do
+ self["m"..r..c] = 0
+ end
+ end
+end
+
+Matrix44.Clear = function(self)
+ for r = 0, 3 do
+ for c = 0, 3 do
+ self["m"..r..c] = 0
+ end
+ end
+end
+
+Matrix44.SetRow = function(self, row, value)
+
+end
+
+Matrix44.SetColum = function(self, colum, value)
+
+end
+
+Matrix44.Set = function(self, row, colum ,value)
+
+end
+
+Matrix44.GetColum = function(self, colum)
+
+end
+
+Matrix44.GetRow = function(self, row)
+
+end
+
+-- note: n>0, f>0
+Matrix44.SetOrtho = function(self, l, r, b, t, n, f)
+ self:Clear()
+ self.m00 = 2 / (r - l)
+ self.m03 = (r + l) / (l - r)
+ self.m11 = 2 / (t - b)
+ self.m13 = (t + b) / (b - t)
+ self.m22 = 2 / (n - f)
+ self.m23 = (f + n) / (n - f)
+ self.m33 = 1
+end
+
+-- note: n>0, f>0
+Matrix44.SetFrustum = function(self, l, r, b, t, n, f)
+ self:Clear()
+ self.m00 = 2 * n / (r - l)
+ self.m02 = (r + l) / (r - l)
+ self.m11 = 2 * n / (t - b)
+ self.m12 = (t + b) / (t - b)
+ self.m22 = (f + n) / (n - f)
+ self.m23 = 2 * f * n / (n - f)
+ self.m32 = -1
+end
+
+-- note: n>0, f>0
+Matrix44.SetPerspective = function(self, fov, aspect, near, far)
+ self:Clear()
+ self.m00 = 1 / (aspect * math.tan(fov/2))
+ self.m11 = 1 / math.tan(fov/2)
+ self.m22 = (far + near) / (near - far)
+ self.m23 = 2 * far * near / (near - far)
+ self.m32 = -1
+end
+
+return Matrix44 \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Math/Quaternion.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Quaternion.lua
new file mode 100644
index 0000000..4d690e3
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Quaternion.lua
@@ -0,0 +1,14 @@
+local Quaternion = {}
+
+Quaternion.Ctor = function(self)
+ self.x = 0
+ self.y = 0
+ self.z = 0
+ self.w = 0
+end
+
+Quaternion.Euler = function(euler)
+
+end
+
+return Quaternion \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Math/Vector2.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Vector2.lua
new file mode 100644
index 0000000..5697797
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Vector2.lua
@@ -0,0 +1,5 @@
+local Vector2 = GameLab.Class("GameLab.Engine.Math.Vector2")
+
+
+
+return Vector2 \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Math/Vector3.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Vector3.lua
new file mode 100644
index 0000000..caa28a4
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Vector3.lua
@@ -0,0 +1,5 @@
+local Vector3 = GameLab.Class("GameLab.Engine.Math.Vector3")
+
+
+
+return Vector3 \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Math/Vector4.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Vector4.lua
new file mode 100644
index 0000000..e232c93
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Math/Vector4.lua
@@ -0,0 +1,45 @@
+local Vector4 = GameLab.Class("GameLab.Engine.Math.Vector4")
+
+Vector4.Ctor = function (self, x, y, z, w)
+ self.x = x or 0
+ self.y = y or 0
+ self.z = z or 0
+ self.w = w or 0
+end
+
+Vector4.Magnitude = function (self)
+
+end
+
+Vector4.Normalized = function (self)
+
+end
+
+Vector4.SqrMagnitude = function (self)
+
+end
+
+Vector4.Distance = function (self, to)
+
+end
+
+Vector4.Dot = function(self, v)
+
+end
+
+Vector4.Lerp = function(self, v, t)
+
+end
+
+Vector4.Project = function (self, v)
+
+end
+
+Vector4.Scale = function(self, scale)
+
+end
+
+Vector4.one = Vector4.New(1,1,1,1)
+Vector4.zero = Vector4.New(0,0,0,0)
+
+return Vector4 \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Math/init.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Math/init.lua
new file mode 100644
index 0000000..eb75db7
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Math/init.lua
@@ -0,0 +1,16 @@
+local m = GameLab.Engine.Math or {}
+GameLab.Engine.Math = m
+
+local import = GameLab.import(...)
+
+import("Math")
+m.Vector2 = import("Vector2")
+m.Vector3 = import("Vector3")
+m.Vector4 = import("Vector4")
+m.Matrix44 = import("Matrix44")
+m.Matrix33 = import("Matrix33")
+m.Quaternion = import("Quaternion")
+
+GameLab.Debug.Log("GameLab.Engine.Math loaded")
+
+return m \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Rendering/Color.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Rendering/Color.lua
new file mode 100644
index 0000000..bf908a4
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Rendering/Color.lua
@@ -0,0 +1,36 @@
+local Color = GameLab.Class("GameLab.Engine.Rendering.Color")
+
+Color.Ctor = function(self, r, g, b, a)
+ self.r = r
+ self.g = g
+ self.b = b
+ self.a = a
+end
+
+Color.ToColor32 = function(self)
+ local Color32 = GameLab.find("GameLab.Engine.Rendering.Color32")
+ local c32 = Color32.New()
+ c32.r = self.r * 255
+ c32.g = self.g * 255
+ c32.b = self.b * 255
+ c32.a = self.a * 255
+ return c32
+end
+
+Color.Clear = function(self)
+ self.r = 0
+ self.g = 0
+ self.b = 0
+ self.a = 0
+end
+
+Color.red = Color.New(1,0,0,1)
+Color.green = Color.New(0,1,0,1)
+Color.blue = Color.New(0,0,1,1)
+Color.magenta = Color.New(1,0,1,1)
+Color.red = Color.New(1,0,0,1)
+Color.yellow = Color.New(1,1,0,1)
+Color.black = Color.New(0,0,0,1)
+Color.white = Color.New(1,1,1,1)
+
+return Color \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Rendering/Color32.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Rendering/Color32.lua
new file mode 100644
index 0000000..d108dfb
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Rendering/Color32.lua
@@ -0,0 +1,36 @@
+local Color32 = GameLab.Class("GameLab.Engine.Rendering.Color32")
+
+Color32.Ctor = function(self, r, g, b, a)
+ self.r = r
+ self.g = g
+ self.b = b
+ self.a = a
+end
+
+Color32.ToColor = function(self)
+ local Color = GameLab.find("GameLab.Engine.Rendering.Color")
+ local c = Color.New()
+ c.r = self.r / 255
+ c.g = self.g / 255
+ c.b = self.b / 255
+ c.a = self.a / 255
+ return c
+end
+
+Color32.Clear = function(self)
+ self.r = 0
+ self.g = 0
+ self.b = 0
+ self.a = 0
+end
+
+Color32.red = Color32.New(255,0,0,255)
+Color32.green = Color32.New(0,255,0,255)
+Color32.blue = Color32.New(0,0,255,255)
+Color32.magenta = Color32.New(255,0,255,255)
+Color32.red = Color32.New(255,0,0,255)
+Color32.yellow = Color32.New(255,255,0,255)
+Color32.black = Color32.New(0,0,0,255)
+Color32.white = Color32.New(255,255,255,255)
+
+return Color32 \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Rendering/init.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Rendering/init.lua
new file mode 100644
index 0000000..d9b4e3e
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Rendering/init.lua
@@ -0,0 +1,13 @@
+local m = GameLab.Engine.Rendering or {}
+GameLab.Engine.Rendering = m
+
+local import = GameLab.import(...)
+
+m.Color = import("Color")
+m.Color32 = import("Color32")
+
+m.LoadTexture = function(path)
+
+end
+
+return m \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Utils/EventCenter.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Utils/EventCenter.lua
new file mode 100644
index 0000000..664ecba
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Utils/EventCenter.lua
@@ -0,0 +1,23 @@
+local EventCenter = {}
+
+EventCenter.Subscribe = function(event, callback)
+
+end
+
+EventCenter.Unsubscribe = function(event, callback)
+
+end
+
+EventCenter.UnsubscribeAll = function(event)
+
+end
+
+EventCenter.Publish = function(event, ...)
+
+end
+
+EventCenter.Clear = function()
+
+end
+
+Jin.EventCenter = EventCenter \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Utils/StateMachine.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Utils/StateMachine.lua
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Utils/StateMachine.lua
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/Utils/Util.lua b/Data/DefaultContent/Libraries/GameLab/Engine/Utils/Util.lua
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/Utils/Util.lua
diff --git a/Data/DefaultContent/Libraries/GameLab/Engine/init.lua b/Data/DefaultContent/Libraries/GameLab/Engine/init.lua
new file mode 100644
index 0000000..f6f46a4
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Engine/init.lua
@@ -0,0 +1,5 @@
+GameLab.Engine = GameLab.Engine or {}
+
+local import = GameLab.import(...)
+
+return GameLab.Engine \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/Enum.lua b/Data/DefaultContent/Libraries/GameLab/Enum.lua
new file mode 100644
index 0000000..d1a1ae0
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/Enum.lua
@@ -0,0 +1,9 @@
+-- Declare enum
+
+
+local Enum = function()
+
+end
+
+
+GameLab.Enum = Enum \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/InternalClass.lua b/Data/DefaultContent/Libraries/GameLab/InternalClass.lua
new file mode 100644
index 0000000..36ad568
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/InternalClass.lua
@@ -0,0 +1,12 @@
+local Class = GameLab.Class or require("GameLab.Class")
+
+-- å£°æ˜Žç±»çš„åŒæ—¶æ·»åŠ åˆ°G表
+local InternalClass = function(className)
+ local cls = Class(className)
+ _G[className] = className
+ return cls
+end
+
+GameLab.InternalClass = InternalClass
+
+return InternalClass \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/GameLab/init.lua b/Data/DefaultContent/Libraries/GameLab/init.lua
new file mode 100644
index 0000000..c87ace3
--- /dev/null
+++ b/Data/DefaultContent/Libraries/GameLab/init.lua
@@ -0,0 +1,41 @@
+GameLab = GameLab or {}
+
+-- methods
+-- 用于模å—çš„init.lua中加载模å—内的脚本
+GameLab.import = function(packageName)
+ local _import = function(path)
+ local name = packageName .. "." .. path
+ local m = require(name)
+ --package.loaded[name] = m
+ return m
+ end
+ return _import
+end
+
+-- 用于相对路径包å«
+-- GameLab.require = function(className)
+-- local packageName = (type(className) == "string") and string.match(className, "^(.+)%.%w+$") or ""
+-- local _require = function(path)
+-- local name = packageName .. "." .. path
+-- local m = require(name)
+-- return m
+-- end
+-- return _require
+-- end
+
+GameLab.find = function(fullName)
+ if _G[fullName] ~= nil then
+ return _G[fullName]
+ end
+ if package.loaded[fullName] ~= nil then
+ return package.loaded[fullName]
+ end
+ return require(fullName)
+end
+
+-- classes
+GameLab.Class = require("GameLab.Class")
+
+GameLab.InternalClass = require("GameLab.InternalClass")
+
+return GameLab \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/LiteJson/LICENSE b/Data/DefaultContent/Libraries/LiteJson/LICENSE
new file mode 100644
index 0000000..9eb37b1
--- /dev/null
+++ b/Data/DefaultContent/Libraries/LiteJson/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2020 rxi
+
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Data/DefaultContent/Libraries/LiteJson/README.md b/Data/DefaultContent/Libraries/LiteJson/README.md
new file mode 100644
index 0000000..96b9b66
--- /dev/null
+++ b/Data/DefaultContent/Libraries/LiteJson/README.md
@@ -0,0 +1,46 @@
+# ![json.lua](https://cloud.githubusercontent.com/assets/3920290/9281532/99e5e0cc-42bd-11e5-8fce-eaff2f7fc681.png)
+A lightweight JSON library for Lua
+
+
+## Features
+* Implemented in pure Lua: works with 5.1, 5.2, 5.3 and JIT
+* Fast: generally outperforms other pure Lua JSON implementations
+ ([benchmark scripts](bench/))
+* Tiny: around 280sloc, 9kb
+* Proper error messages, *eg:* `expected '}' or ',' at line 203 col 30`
+
+
+## Usage
+The [json.lua](json.lua?raw=1) file should be dropped into an existing project
+and required by it:
+```lua
+json = require "json"
+```
+The library provides the following functions:
+
+#### json.encode(value)
+Returns a string representing `value` encoded in JSON.
+```lua
+json.encode({ 1, 2, 3, { x = 10 } }) -- Returns '[1,2,3,{"x":10}]'
+```
+
+#### json.decode(str)
+Returns a value representing the decoded JSON string.
+```lua
+json.decode('[1,2,3,{"x":10}]') -- Returns { 1, 2, 3, { x = 10 } }
+```
+
+## Notes
+* Trying to encode values which are unrepresentable in JSON will never result
+ in type conversion or other magic: sparse arrays, tables with mixed key types
+ or invalid numbers (NaN, -inf, inf) will raise an error
+* `null` values contained within an array or object are converted to `nil` and
+ are therefore lost upon decoding
+* *Pretty* encoding is not supported, `json.encode()` only encodes to a compact
+ format
+
+
+## License
+This library is free software; you can redistribute it and/or modify it under
+the terms of the MIT license. See [LICENSE](LICENSE) for details.
+
diff --git a/Data/DefaultContent/Libraries/LiteJson/bench/bench_all.lua b/Data/DefaultContent/Libraries/LiteJson/bench/bench_all.lua
new file mode 100644
index 0000000..3f99e99
--- /dev/null
+++ b/Data/DefaultContent/Libraries/LiteJson/bench/bench_all.lua
@@ -0,0 +1,6 @@
+
+print("[decode]")
+loadfile("bench_decode.lua")()
+print()
+print("[encode]")
+loadfile("bench_encode.lua")()
diff --git a/Data/DefaultContent/Libraries/LiteJson/bench/bench_decode.lua b/Data/DefaultContent/Libraries/LiteJson/bench/bench_decode.lua
new file mode 100644
index 0000000..6c2e93a
--- /dev/null
+++ b/Data/DefaultContent/Libraries/LiteJson/bench/bench_decode.lua
@@ -0,0 +1,75 @@
+local bench = require "util.bench"
+
+
+local libs = {
+ "../json.lua", -- https://github.com/rxi/json.lua
+ "dkjson.lua", -- https://github.com/LuaDist/dkjson
+ "jfjson.lua", -- http://regex.info/blog/lua/json
+ --"json4lua.lua", -- https://github.com/craigmj/json4lua
+}
+
+
+-- JSON string: wikipedia example stored 1000 times in an array
+local text = "[" .. string.rep([[{
+ "firstName": "John",
+ "lastName": "Smith",
+ "isAlive": true,
+ "age": 25,
+ "address": {
+ "streetAddress": "21 2nd Street",
+ "city": "New York",
+ "state": "NY",
+ "postalCode": "10021-3100"
+ },
+ "phoneNumbers": [
+ {
+ "type": "home",
+ "number": "212 555-1234"
+ },
+ {
+ "type": "office",
+ "number": "646 555-4567"
+ }
+ ],
+ "children": [],
+ "spouse": null
+}, ]], 1000):sub(1, -3) .. "]"
+
+
+-- As this is meant to be a pure Lua benchmark, we remove the ability to
+-- require 'lpeg' so dkjson doesn't use it for parsing. (Incidentally json.lua
+-- seems to outperform libraries which use lpeg when both are using LuaJIT)
+local _require = require
+require = function(modname)
+ if modname == "lpeg" then error() end
+ return _require(modname)
+end
+
+-- Run benchmarks, store results
+local results = {}
+
+for i, name in ipairs(libs) do
+ local f = loadfile(name)
+ if not f then
+ error( "failed to load '" .. name .. "'; run './get_json_libs.sh'" )
+ end
+ local json = f()
+
+ -- Remap functions to work for jfjson.lua
+ if name == "jfjson.lua" then
+ local _encode, _decode = json.encode, json.decode
+ json.encode = function(...) return _encode(json, ...) end
+ json.decode = function(...) return _decode(json, ...) end
+ end
+
+ -- Warmup (for LuaJIT)
+ bench.run(name, 1, function() json.decode(text) end)
+
+ -- Run and push results
+ local res = bench.run(name, 10, function() json.decode(text) end)
+ table.insert(results, res)
+end
+
+
+bench.print_system_info()
+bench.print_results(results)
diff --git a/Data/DefaultContent/Libraries/LiteJson/bench/bench_encode.lua b/Data/DefaultContent/Libraries/LiteJson/bench/bench_encode.lua
new file mode 100644
index 0000000..426f7c8
--- /dev/null
+++ b/Data/DefaultContent/Libraries/LiteJson/bench/bench_encode.lua
@@ -0,0 +1,63 @@
+local bench = require "util.bench"
+
+
+local libs = {
+ "../json.lua", -- https://github.com/rxi/json.lua
+ "dkjson.lua", -- https://github.com/LuaDist/dkjson
+ "jfjson.lua", -- http://regex.info/blog/lua/json
+ "json4lua.lua", -- https://github.com/craigmj/json4lua
+}
+
+
+-- Build table which will be encoded: wikipedia example stored 1000 times
+local data = {}
+for i = 1, 1000 do
+ table.insert(data, {
+ firstName = "John",
+ lastName = "Smith",
+ isAlive = true,
+ age = 25,
+ address = {
+ streetAddress = "21 2nd Street",
+ city = "New York",
+ state = "NY",
+ postalCode = "10021-3100"
+ },
+ phoneNumbers = {
+ { type = "home", number = "212 555-1234" },
+ { type = "office", number = "646 555-4567" }
+ },
+ children = {},
+ spouse = nil
+ })
+end
+
+
+-- Run benchmarks
+local results = {}
+
+for i, name in ipairs(libs) do
+ local f = loadfile(name)
+ if not f then
+ error( "failed to load '" .. name .. "'; run './get_json_libs.sh'" )
+ end
+ local json = f()
+
+ -- Handle special cases
+ if name == "jfjson.lua" then
+ local _encode, _decode = json.encode, json.decode
+ json.encode = function(...) return _encode(json, ...) end
+ json.decode = function(...) return _decode(json, ...) end
+ end
+
+ -- Warmup (for LuaJIT)
+ bench.run(name, 1, function() json.encode(data) end)
+
+ -- Run and push results
+ local res = bench.run(name, 10, function() json.encode(data) end)
+ table.insert(results, res)
+end
+
+
+bench.print_system_info()
+bench.print_results(results)
diff --git a/Data/DefaultContent/Libraries/LiteJson/bench/get_json_libs.sh b/Data/DefaultContent/Libraries/LiteJson/bench/get_json_libs.sh
new file mode 100644
index 0000000..ecb4525
--- /dev/null
+++ b/Data/DefaultContent/Libraries/LiteJson/bench/get_json_libs.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# Downloads other JSON libraries for use in the benchmark scripts
+
+# Remove libraries
+rm dkjson.lua 2>/dev/null
+rm jfjson.lua 2>/dev/null
+rm json4lua.lua 2>/dev/null
+
+# Get libraries
+echo "Downloading json libs..."
+curl -sS -o dkjson.lua "https://raw.githubusercontent.com/LuaDist/dkjson/master/dkjson.lua"
+curl -sS -o json4lua.lua "https://raw.githubusercontent.com/craigmj/json4lua/master/json/json.lua"
+curl -sS -o jfjson.lua "http://regex.info/code/JSON.lua"
+
+echo "Done"
diff --git a/Data/DefaultContent/Libraries/LiteJson/bench/util/bench.lua b/Data/DefaultContent/Libraries/LiteJson/bench/util/bench.lua
new file mode 100644
index 0000000..9f02738
--- /dev/null
+++ b/Data/DefaultContent/Libraries/LiteJson/bench/util/bench.lua
@@ -0,0 +1,62 @@
+local bench = {}
+
+local unpack = unpack or table.unpack
+local fmt = string.format
+
+
+function bench.run(name, count, func)
+ -- Run bench
+ local res = {}
+ for i = 1, count do
+ local start_time = os.clock()
+ func()
+ table.insert(res, (os.clock() - start_time))
+ end
+ -- Calculate average
+ local avg = 0
+ for i, v in ipairs(res) do
+ avg = avg + v
+ end
+ avg = avg / #res
+ -- Build and return result table
+ return {
+ name = name,
+ avg = avg,
+ min = math.min(unpack(res)),
+ max = math.max(unpack(res)),
+ all = res,
+ }
+end
+
+
+function bench.get_cpu_name()
+ local fp = io.open("/proc/cpuinfo", "rb")
+ if not fp then
+ return "unknown"
+ end
+ local text = fp:read("*a")
+ return text:match("model name%s*:%s*(.-)\n")
+end
+
+
+function bench.print_system_info()
+ print( fmt("Lua version : %s", jit and jit.version or _VERSION) )
+ print( fmt("CPU name : %s", bench.get_cpu_name()) )
+end
+
+
+function bench.print_results(results)
+ -- Find best average
+ local best = math.huge
+ for i, v in ipairs(results) do
+ best = math.min(best, v.avg)
+ end
+ -- Print results
+ for i, v in ipairs(results) do
+ print( fmt("%-13s : %.03gs [x%1.3g] (min: %.03gs, max %.03gs)",
+ v.name, v.avg, v.avg / best, v.min, v.max) )
+ end
+end
+
+
+return bench
diff --git a/Data/DefaultContent/Libraries/LiteJson/json.lua b/Data/DefaultContent/Libraries/LiteJson/json.lua
new file mode 100644
index 0000000..711ef78
--- /dev/null
+++ b/Data/DefaultContent/Libraries/LiteJson/json.lua
@@ -0,0 +1,388 @@
+--
+-- json.lua
+--
+-- Copyright (c) 2020 rxi
+--
+-- Permission is hereby granted, free of charge, to any person obtaining a copy of
+-- this software and associated documentation files (the "Software"), to deal in
+-- the Software without restriction, including without limitation the rights to
+-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-- of the Software, and to permit persons to whom the Software is furnished to do
+-- so, subject to the following conditions:
+--
+-- The above copyright notice and this permission notice shall be included in all
+-- copies or substantial portions of the Software.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-- SOFTWARE.
+--
+
+local json = { _version = "0.1.2" }
+
+-------------------------------------------------------------------------------
+-- Encode
+-------------------------------------------------------------------------------
+
+local encode
+
+local escape_char_map = {
+ [ "\\" ] = "\\",
+ [ "\"" ] = "\"",
+ [ "\b" ] = "b",
+ [ "\f" ] = "f",
+ [ "\n" ] = "n",
+ [ "\r" ] = "r",
+ [ "\t" ] = "t",
+}
+
+local escape_char_map_inv = { [ "/" ] = "/" }
+for k, v in pairs(escape_char_map) do
+ escape_char_map_inv[v] = k
+end
+
+
+local function escape_char(c)
+ return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte()))
+end
+
+
+local function encode_nil(val)
+ return "null"
+end
+
+
+local function encode_table(val, stack)
+ local res = {}
+ stack = stack or {}
+
+ -- Circular reference?
+ if stack[val] then error("circular reference") end
+
+ stack[val] = true
+
+ if rawget(val, 1) ~= nil or next(val) == nil then
+ -- Treat as array -- check keys are valid and it is not sparse
+ local n = 0
+ for k in pairs(val) do
+ if type(k) ~= "number" then
+ error("invalid table: mixed or invalid key types")
+ end
+ n = n + 1
+ end
+ if n ~= #val then
+ error("invalid table: sparse array")
+ end
+ -- Encode
+ for i, v in ipairs(val) do
+ table.insert(res, encode(v, stack))
+ end
+ stack[val] = nil
+ return "[" .. table.concat(res, ",") .. "]"
+
+ else
+ -- Treat as an object
+ for k, v in pairs(val) do
+ if type(k) ~= "string" then
+ error("invalid table: mixed or invalid key types")
+ end
+ table.insert(res, encode(k, stack) .. ":" .. encode(v, stack))
+ end
+ stack[val] = nil
+ return "{" .. table.concat(res, ",") .. "}"
+ end
+end
+
+
+local function encode_string(val)
+ return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
+end
+
+
+local function encode_number(val)
+ -- Check for NaN, -inf and inf
+ if val ~= val or val <= -math.huge or val >= math.huge then
+ error("unexpected number value '" .. tostring(val) .. "'")
+ end
+ return string.format("%.14g", val)
+end
+
+
+local type_func_map = {
+ [ "nil" ] = encode_nil,
+ [ "table" ] = encode_table,
+ [ "string" ] = encode_string,
+ [ "number" ] = encode_number,
+ [ "boolean" ] = tostring,
+}
+
+
+encode = function(val, stack)
+ local t = type(val)
+ local f = type_func_map[t]
+ if f then
+ return f(val, stack)
+ end
+ error("unexpected type '" .. t .. "'")
+end
+
+
+function json.encode(val)
+ return ( encode(val) )
+end
+
+
+-------------------------------------------------------------------------------
+-- Decode
+-------------------------------------------------------------------------------
+
+local parse
+
+local function create_set(...)
+ local res = {}
+ for i = 1, select("#", ...) do
+ res[ select(i, ...) ] = true
+ end
+ return res
+end
+
+local space_chars = create_set(" ", "\t", "\r", "\n")
+local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",")
+local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u")
+local literals = create_set("true", "false", "null")
+
+local literal_map = {
+ [ "true" ] = true,
+ [ "false" ] = false,
+ [ "null" ] = nil,
+}
+
+
+local function next_char(str, idx, set, negate)
+ for i = idx, #str do
+ if set[str:sub(i, i)] ~= negate then
+ return i
+ end
+ end
+ return #str + 1
+end
+
+
+local function decode_error(str, idx, msg)
+ local line_count = 1
+ local col_count = 1
+ for i = 1, idx - 1 do
+ col_count = col_count + 1
+ if str:sub(i, i) == "\n" then
+ line_count = line_count + 1
+ col_count = 1
+ end
+ end
+ error( string.format("%s at line %d col %d", msg, line_count, col_count) )
+end
+
+
+local function codepoint_to_utf8(n)
+ -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa
+ local f = math.floor
+ if n <= 0x7f then
+ return string.char(n)
+ elseif n <= 0x7ff then
+ return string.char(f(n / 64) + 192, n % 64 + 128)
+ elseif n <= 0xffff then
+ return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128)
+ elseif n <= 0x10ffff then
+ return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128,
+ f(n % 4096 / 64) + 128, n % 64 + 128)
+ end
+ error( string.format("invalid unicode codepoint '%x'", n) )
+end
+
+
+local function parse_unicode_escape(s)
+ local n1 = tonumber( s:sub(1, 4), 16 )
+ local n2 = tonumber( s:sub(7, 10), 16 )
+ -- Surrogate pair?
+ if n2 then
+ return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)
+ else
+ return codepoint_to_utf8(n1)
+ end
+end
+
+
+local function parse_string(str, i)
+ local res = ""
+ local j = i + 1
+ local k = j
+
+ while j <= #str do
+ local x = str:byte(j)
+
+ if x < 32 then
+ decode_error(str, j, "control character in string")
+
+ elseif x == 92 then -- `\`: Escape
+ res = res .. str:sub(k, j - 1)
+ j = j + 1
+ local c = str:sub(j, j)
+ if c == "u" then
+ local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1)
+ or str:match("^%x%x%x%x", j + 1)
+ or decode_error(str, j - 1, "invalid unicode escape in string")
+ res = res .. parse_unicode_escape(hex)
+ j = j + #hex
+ else
+ if not escape_chars[c] then
+ decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string")
+ end
+ res = res .. escape_char_map_inv[c]
+ end
+ k = j + 1
+
+ elseif x == 34 then -- `"`: End of string
+ res = res .. str:sub(k, j - 1)
+ return res, j + 1
+ end
+
+ j = j + 1
+ end
+
+ decode_error(str, i, "expected closing quote for string")
+end
+
+
+local function parse_number(str, i)
+ local x = next_char(str, i, delim_chars)
+ local s = str:sub(i, x - 1)
+ local n = tonumber(s)
+ if not n then
+ decode_error(str, i, "invalid number '" .. s .. "'")
+ end
+ return n, x
+end
+
+
+local function parse_literal(str, i)
+ local x = next_char(str, i, delim_chars)
+ local word = str:sub(i, x - 1)
+ if not literals[word] then
+ decode_error(str, i, "invalid literal '" .. word .. "'")
+ end
+ return literal_map[word], x
+end
+
+
+local function parse_array(str, i)
+ local res = {}
+ local n = 1
+ i = i + 1
+ while 1 do
+ local x
+ i = next_char(str, i, space_chars, true)
+ -- Empty / end of array?
+ if str:sub(i, i) == "]" then
+ i = i + 1
+ break
+ end
+ -- Read token
+ x, i = parse(str, i)
+ res[n] = x
+ n = n + 1
+ -- Next token
+ i = next_char(str, i, space_chars, true)
+ local chr = str:sub(i, i)
+ i = i + 1
+ if chr == "]" then break end
+ if chr ~= "," then decode_error(str, i, "expected ']' or ','") end
+ end
+ return res, i
+end
+
+
+local function parse_object(str, i)
+ local res = {}
+ i = i + 1
+ while 1 do
+ local key, val
+ i = next_char(str, i, space_chars, true)
+ -- Empty / end of object?
+ if str:sub(i, i) == "}" then
+ i = i + 1
+ break
+ end
+ -- Read key
+ if str:sub(i, i) ~= '"' then
+ decode_error(str, i, "expected string for key")
+ end
+ key, i = parse(str, i)
+ -- Read ':' delimiter
+ i = next_char(str, i, space_chars, true)
+ if str:sub(i, i) ~= ":" then
+ decode_error(str, i, "expected ':' after key")
+ end
+ i = next_char(str, i + 1, space_chars, true)
+ -- Read value
+ val, i = parse(str, i)
+ -- Set
+ res[key] = val
+ -- Next token
+ i = next_char(str, i, space_chars, true)
+ local chr = str:sub(i, i)
+ i = i + 1
+ if chr == "}" then break end
+ if chr ~= "," then decode_error(str, i, "expected '}' or ','") end
+ end
+ return res, i
+end
+
+
+local char_func_map = {
+ [ '"' ] = parse_string,
+ [ "0" ] = parse_number,
+ [ "1" ] = parse_number,
+ [ "2" ] = parse_number,
+ [ "3" ] = parse_number,
+ [ "4" ] = parse_number,
+ [ "5" ] = parse_number,
+ [ "6" ] = parse_number,
+ [ "7" ] = parse_number,
+ [ "8" ] = parse_number,
+ [ "9" ] = parse_number,
+ [ "-" ] = parse_number,
+ [ "t" ] = parse_literal,
+ [ "f" ] = parse_literal,
+ [ "n" ] = parse_literal,
+ [ "[" ] = parse_array,
+ [ "{" ] = parse_object,
+}
+
+
+parse = function(str, idx)
+ local chr = str:sub(idx, idx)
+ local f = char_func_map[chr]
+ if f then
+ return f(str, idx)
+ end
+ decode_error(str, idx, "unexpected character '" .. chr .. "'")
+end
+
+
+function json.decode(str)
+ if type(str) ~= "string" then
+ error("expected argument of type string, got " .. type(str))
+ end
+ local res, idx = parse(str, next_char(str, 1, space_chars, true))
+ idx = next_char(str, idx, space_chars, true)
+ if idx <= #str then
+ decode_error(str, idx, "trailing garbage")
+ end
+ return res
+end
+
+
+return json
diff --git a/Data/DefaultContent/Libraries/LiteJson/test/test.lua b/Data/DefaultContent/Libraries/LiteJson/test/test.lua
new file mode 100644
index 0000000..74470b2
--- /dev/null
+++ b/Data/DefaultContent/Libraries/LiteJson/test/test.lua
@@ -0,0 +1,245 @@
+
+local json = loadfile("../json.lua")()
+
+
+local fmt = string.format
+
+local function test(name, func)
+ xpcall(function()
+ func()
+ print( fmt("[pass] %s", name) )
+ end, function(err)
+ print( fmt("[fail] %s : %s", name, err) )
+ end)
+end
+
+
+local function equal(a, b)
+ -- Handle table
+ if type(a) == "table" and type(b) == "table" then
+ for k in pairs(a) do
+ if not equal(a[k], b[k]) then
+ return false
+ end
+ end
+ for k in pairs(b) do
+ if not equal(b[k], a[k]) then
+ return false
+ end
+ end
+ return true
+ end
+ -- Handle scalar
+ return a == b
+end
+
+
+test("numbers", function()
+ local t = {
+ [ "123.456" ] = 123.456,
+ [ "-123" ] = -123,
+ [ "-567.765" ] = -567.765,
+ [ "12.3" ] = 12.3,
+ [ "0" ] = 0,
+ [ "0.10000000012" ] = 0.10000000012,
+ }
+ for k, v in pairs(t) do
+ local res = json.decode(k)
+ assert( res == v, fmt("expected '%s', got '%s'", k, res) )
+ local res = json.encode(v)
+ assert( res == k, fmt("expected '%s', got '%s'", v, res) )
+ end
+ assert( json.decode("13e2") == 13e2 )
+ assert( json.decode("13E+2") == 13e2 )
+ assert( json.decode("13e-2") == 13e-2 )
+end)
+
+
+test("literals", function()
+ assert( json.decode("true") == true )
+ assert( json.encode(true) == "true" )
+ assert( json.decode("false") == false )
+ assert( json.encode(false) == "false" )
+ assert( json.decode("null") == nil )
+ assert( json.encode(nil) == "null")
+end)
+
+
+test("strings", function()
+ local s = ""
+ assert( s == json.decode( json.encode(s) ) )
+ local s = "\\"
+ assert( s == json.decode( json.encode(s) ) )
+ local s = "Hello world"
+ assert( s == json.decode( json.encode(s) ) )
+ local s = "\0 \13 \27"
+ assert( s == json.decode( json.encode(s) ) )
+ local s = "\0\r\n\8"
+ assert( s == json.decode( json.encode(s) ) )
+end)
+
+
+test("unicode", function()
+ local s = "ã“ã‚“ã«ã¡ã¯ä¸–界"
+ assert( s == json.decode( json.encode(s) ) )
+end)
+
+
+test("arrays", function()
+ local t = { "cat", "dog", "owl" }
+ assert( equal( t, json.decode( json.encode(t) ) ) )
+end)
+
+
+test("objects", function()
+ local t = { x = 10, y = 20, z = 30 }
+ assert( equal( t, json.decode( json.encode(t) ) ) )
+end)
+
+
+--test("strict decode", function()
+-- local t = {
+-- '{x : 1}',
+-- '{x : hello}',
+-- "{'x' : 1}",
+-- '{"x" : nil}',
+-- '{"x" : 0x10}',
+-- '{"x" : 001}',
+-- '{"x" : .1}',
+-- '{"x" : 1, }',
+-- '[1, 2, 3, ]',
+-- }
+-- for i, v in ipairs(t) do
+-- local status = pcall(json.decode, v)
+-- assert( not status, fmt("'%s' was parsed without error", v) )
+-- end
+--end)
+
+
+test("decode invalid", function()
+ local t = {
+ '',
+ ' ',
+ '{',
+ '[',
+ '{"x" : ',
+ '{"x" : 1',
+ '{"x" : z }',
+ '{"x" : 123z }',
+ '{x : 123 }',
+ '{10 : 123 }',
+ '{]',
+ '[}',
+ '"a',
+ '10 xx',
+ '{}123'
+ }
+ for i, v in ipairs(t) do
+ local status = pcall(json.decode, v)
+ assert( not status, fmt("'%s' was parsed without error", v) )
+ end
+end)
+
+
+test("decode invalid string", function()
+ local t = {
+ [["\z"]],
+ [["\1"]],
+ [["\u000z"]],
+ [["\ud83d\ude0q"]],
+ '"x\ny"',
+ '"x\0y"',
+ }
+ for i, v in ipairs(t) do
+ local status, err = pcall(json.decode, v)
+ assert( not status, fmt("'%s' was parsed without error", v) )
+ end
+end)
+
+
+test("decode escape", function()
+ local t = {
+ [ [["\u263a"]] ] = '☺',
+ [ [["\ud83d\ude02"]] ] = '😂',
+ [ [["\r\n\t\\\""]] ] = '\r\n\t\\"',
+ [ [["\\"]] ] = '\\',
+ [ [["\\\\"]] ] = '\\\\',
+ [ [["\/"]] ] = '/',
+ [ [["\\u \u263a"]] ] = [[\u ☺]],
+ }
+ for k, v in pairs(t) do
+ local res = json.decode(k)
+ assert( res == v, fmt("expected '%s', got '%s'", v, res) )
+ end
+end)
+
+
+test("decode empty", function()
+ local t = {
+ [ '[]' ] = {},
+ [ '{}' ] = {},
+ [ '""' ] = "",
+ }
+ for k, v in pairs(t) do
+ local res = json.decode(k)
+ assert( equal(res, v), fmt("'%s' did not equal expected", k) )
+ end
+end)
+
+
+test("decode collection", function()
+ local t = {
+ [ '[1, 2, 3, 4, 5, 6]' ] = {1, 2, 3, 4, 5, 6},
+ [ '[1, 2, 3, "hello"]' ] = {1, 2, 3, "hello"},
+ [ '{ "name": "test", "id": 231 }' ] = {name = "test", id = 231},
+ [ '{"x":1,"y":2,"z":[1,2,3]}' ] = {x = 1, y = 2, z = {1, 2, 3}},
+ }
+ for k, v in pairs(t) do
+ local res = json.decode(k)
+ assert( equal(res, v), fmt("'%s' did not equal expected", k) )
+ end
+end)
+
+
+test("encode invalid", function()
+ local t = {
+ { [1000] = "b" },
+ { [ function() end ] = 12 },
+ { nil, 2, 3, 4 },
+ { x = 10, [1] = 2 },
+ { [1] = "a", [3] = "b" },
+ { x = 10, [4] = 5 },
+ }
+ for i, v in ipairs(t) do
+ local status, res = pcall(json.encode, v)
+ assert( not status, fmt("encoding idx %d did not result in an error", i) )
+ end
+end)
+
+
+test("encode invalid number", function()
+ local t = {
+ math.huge, -- inf
+ -math.huge, -- -inf
+ math.huge * 0, -- NaN
+ }
+ for i, v in ipairs(t) do
+ local status, res = pcall(json.encode, v)
+ assert( not status, fmt("encoding '%s' did not result in an error", v) )
+ end
+end)
+
+
+test("encode escape", function()
+ local t = {
+ [ '"x"' ] = [["\"x\""]],
+ [ 'x\ny' ] = [["x\ny"]],
+ [ 'x\0y' ] = [["x\u0000y"]],
+ [ 'x\27y' ] = [["x\u001by"]],
+ [ '\r\n\t\\"' ] = [["\r\n\t\\\""]],
+ }
+ for k, v in pairs(t) do
+ local res = json.encode(k)
+ assert( res == v, fmt("'%s' was not escaped properly", k) )
+ end
+end)
diff --git a/Data/DefaultContent/Libraries/containers/README.md b/Data/DefaultContent/Libraries/containers/README.md
new file mode 100644
index 0000000..cba8776
--- /dev/null
+++ b/Data/DefaultContent/Libraries/containers/README.md
@@ -0,0 +1,202 @@
+# Lua-ADT(5.1分支和5.2分支)
+å°è£…çš„luaæ•°æ®ç»“æž„, 元组(tuple)ã€åŠ¨æ€æ•°ç»„(vector)ã€åŒå‘链表(list)ã€é˜Ÿåˆ—(queue)ã€æ ˆ(stack)。
+纯lua方法å°è£…,没有使用oop,延续lua的简æ´çš„风格。å°è£…的数æ®ç»“构能安全使用,在语言层é¢è¿‡æ»¤æŽ‰éžæ³•æ“作,使其使用更加简å•高效。
+
+所有的类型都支æŒ#获å–长度.
+> eg.
+```lua
+ local tuple = require("tuple")
+ local v = tuple.create({2,3,6})
+ print(#v)
+ ---3
+```
+
+### 元组(tuple)
+需è¦ç”¨tableçš„åŠ¨æ€æ•°ç»„åˆå§‹åŒ–(䏿”¯æŒhashtable),åªå¯¹å¤–公开é历,修改关闭。
+
+é历:
+```lua
+ local tuple = require("tuple")
+ local v = tuple.create({2,3,6})
+
+ for i,v in ipairs(v) do --åªæ”¯æŒipairsé历,抛弃了pairs(因为原则上我们是数组,ä¸å­˜åœ¨key)
+ print(i,v)
+ end
+ ---1 2
+ ---2 3
+ ---3 6
+
+ print(v) --é‡å†™äº†__tostring,方便快速æµè§ˆæ•°æ®
+ ---2,3,6
+
+ v[2] = 9 --因为对修改关闭了所以这地方修改会抛出错误
+ ---lua: .\tuple.lua:33: >> Dee: Limited access
+ ---stack traceback:
+ ---[C]: in function 'error'
+```
+
+### åŠ¨æ€æ•°ç»„(vector)
+实现高效的éåŽ†å’Œä¿®æ”¹ï¼Œä½†æ˜¯æ–°å¢žå’Œåˆ é™¤éƒ½ä¸æ˜¯çº¿æ€§æ—¶é—´å¤æ‚度。基本上就是lua table的数组,但是luaçš„table我们会一ä¸å°å¿ƒå°±æžæˆä¸è¿žç»­çš„。比如:
+```lua
+ local t = {2,4}
+ t[4] = 9
+
+ print(#t) -- 2
+```
+#### 方法:
+ * add --尾添加(高效的æ“作)
+ * insert --æ’å…¥(会有内存整ç†)
+ * addRange --尾添加一个表,
+ * removeAt
+ * remove
+ * contains
+ * indexOf
+ * sort
+ * find
+
+#### eg.
+```lua
+ local vector = require("vector")
+ local v = vector.create()
+
+ v:add(4)
+ v:add(5)
+ v:add(6)
+ v:add(7)
+
+ for i,v in ipairs(v) do
+ print(i,v)
+ end
+ ---1 4
+ ---2 5
+ ---3 6
+ ---4 7
+
+ print(v)
+ ---4,5,6,7
+
+ v[4] = 9 --修改值
+
+ print(v)
+ ---4,5,6,9
+
+ v[7] = 9
+ ---lua: .\vector.lua:101: outrange of vector
+ ---stack traceback:
+ --- [C]: in function 'assert'
+```
+
+### åŒå‘链表(list)
+å¼¥è¡¥åŠ¨æ€æ•°ç»„增删的ä¸è¶³ï¼Œæä¾›å¢žåˆ æ•ˆçŽ‡ï¼Œä½†æ˜¯é历和修改效率比较低
+
+#### 方法:
+ * addFirst --头添加
+ * addLast --尾添加
+ * addBefore --node剿·»åŠ 
+ * addAfter --nodeåŽæ·»åŠ 
+ * removeNode --删除node
+ * remove --æ ¹æ®å€¼ç§»é™¤
+ * find --查找node
+#### eg.
+```lua
+ local vector = require("list")
+ local v = list.create()
+
+ v.addFirst(1)
+ v.addLast(2)
+ print(v)
+ ---1,2
+
+ local node = v.find(1)
+ node.value = 9
+ print(v)
+ ---9,2
+
+ v.removeNode(node)
+ print(v)
+ ---2
+
+ v.addLast(10)
+ v.addLast(20)
+ v.addLast(30)
+ print(v)
+ ---2,10,20,30
+
+ for _,i,v in ipairs(v) do --ç¬¬ä¸€ä¸ªå‚æ•°æ˜¯node, i: index, v: value
+ print(i,v)
+ end
+ ---1 2
+ ---2 10
+ ---3 20
+ ---4 30
+```
+### æ ˆ(stack)
+FILO先进åŽå‡º, 对修改关闭,关闭é历,åªèƒ½é€šè¿‡æ–¹æ³•修改数æ®
+#### 方法:
+ * push --添加
+ * pop --移除
+ * peek --返回栈顶数æ®
+ * clear --清空
+#### eg.
+```lua
+ local stack = require("stack")
+ local v = stack.create()
+
+ v.push(1)
+ v.push(2)
+ v.push(5)
+
+ print(v)
+ ---5,2,1
+ print(v.len)
+ ---3
+ v.pop()
+ print(v)
+ ---2,1
+ v.clear()
+ print(v.len)
+ ---0
+```
+### 队列(queue)
+FIFO,先进先出,因为是队首删除所以ä¸èƒ½ä½¿ç”¨table.remove
+#### 方法:
+ * enqueue --添加
+ * dequeue --移除
+ * peek --返回栈顶数æ®
+ * clear --清空
+ * #queue --获å–长度
+#### eg.
+```lua
+local queue = require("queue")
+-- lua table
+local cnt = 10000 * 1
+
+local t = {}
+for i=1,cnt do
+t[i] = i
+end
+
+local time = os.clock()
+while #t > 0 do
+-- table.remove(t)
+ table.remove(t, 1)
+end
+print(os.clock() - time)
+---1.037s
+
+local v = queue.create()
+
+for i=1,cnt do
+ v.enqueue(i)
+end
+
+
+local time1 = os.clock()
+while v.len > 10 do
+ v.dequeue()
+end
+print(os.clock() - time1)
+---0.005s
+```
+1wæ¡æ•°æ®ï¼Œlua table直接删除表头的耗时1.037s,queue耗时0.005s,而且queueæ•´ç†å†…存的步长å¯ä»¥è°ƒæ•´ï¼Œè€—æ—¶å¯ä»¥è¿›æ­¥ä¸€æé«˜.
+
diff --git a/Data/DefaultContent/Libraries/containers/list.lua b/Data/DefaultContent/Libraries/containers/list.lua
new file mode 100644
index 0000000..59233b9
--- /dev/null
+++ b/Data/DefaultContent/Libraries/containers/list.lua
@@ -0,0 +1,199 @@
+---
+--- Generated by EmmyLua(https://github.com/EmmyLua)
+--- Created by Dee.
+--- DateTime: 2019/3/7 14:00
+--- 高效增删有åºè¡¨ï¼Œä½Žæ•ˆé历
+---
+
+--[[
+é历:
+ for _,idx, value in ipairs(l) do .. end
+ for _, value in pairs(l) do ... end
+]]
+
+list = list or {}
+
+function list.create()
+ local lenght = 0
+ -- 类似stl的方å¼ï¼Œå¤´å°¾åªæ˜¯ä½œä¸ºæŒ‡é’ˆä½¿ç”¨
+ local first = {front = nil, next = nil, value = nil}
+ local last = {front = nil, next = nil, value = nil}
+ first.next = last
+ last.front = first
+
+
+ ---查找值
+ ---@param value
+ ---@return node
+ local find = function(value)
+ local ret = nil
+ local nextNode = first
+ while nextNode do
+ nextNode = nextNode.next
+ if nextNode.value == value then
+ ret = nextNode
+ break
+ end
+ end
+
+ return ret
+ end
+
+ ---查找(æ ¹æ®ä¸‹æ ‡æŸ¥æ‰¾)
+ ---@param idx 下标
+ ---@return node
+ local findByIdx = function(idx)
+ local i = 0
+ local ret
+ local nextNode = first
+ while nextNode and i < lenght do
+ i = i+1
+ nextNode = nextNode.next
+ if i == idx then
+ ret = nextNode
+ break
+ end
+ end
+
+ return ret
+ end
+
+ ---在node剿·»åŠ 
+ ---@param node
+ ---@param v
+ local addBefore = function(node, v)
+ assert(node)
+
+ local frontNode = node.front
+ local newNode = {}
+ newNode.front = frontNode
+ newNode.next = node
+ newNode.value = v
+ node.front = newNode
+ frontNode.next = newNode
+
+ lenght = lenght+1
+ end
+
+ ---在nodeåŽæ·»åŠ 
+ ---@param node
+ ---@param v
+ local addAfter = function(node, v)
+ assert(node)
+ local nextNode = node.next
+ local newNode = {}
+ newNode.front = node
+ newNode.next = nextNode
+ newNode.value = v
+ node.next = newNode
+ nextNode.front = newNode
+
+ lenght = lenght+1
+ end
+
+ ---在队首添加
+ ---@param v
+ local addFirst = function(v)
+ addAfter(first, v)
+ end
+
+ ---在队尾添加
+ ---@param v
+ local addLast = function(v)
+ addBefore(last, v)
+ end
+
+ ---删除节点
+ ---@param node
+ local removeNode = function(node)
+ assert(node)
+
+ local frontNode = node.front
+ local nextNode = node.next
+
+ if frontNode == nil then
+ first = nextNode
+ else
+ frontNode.next = nextNode
+ end
+
+ if nextNode ~= nil then
+ nextNode.front = frontNode
+ end
+ lenght = lenght - 1
+ end
+
+ ---删除节点
+ ---@param v
+ local remove = function(v)
+ local node = find(v)
+ if node then
+ removeNode(node)
+ end
+ end
+
+ local t = {
+ addFirst = addFirst,
+ addLast = addLast,
+ addBefore = addBefore,
+ addAfter = addAfter,
+ removeNode = removeNode,
+ remove = remove,
+ find = find,
+ findByIdx = findByIdx
+ }
+
+ local mt = {
+ __index = function(i_t, key)
+ return findByIdx(key)
+ end,
+ __newindex = function(i_t,k,v)
+ local node = findByIdx(k)
+ if not node then
+ error("out range: "..k)
+ else
+ node.value = v
+ end
+ end,
+ __tostring = function()
+ local ret = {}
+ local next = first.next
+ while next and next ~= last do
+ ret[#ret+1] = next.value
+ next = next.next
+ end
+
+ return table.concat(ret, ',')
+ end,
+ __len = function(v)
+ return lenght
+ end,
+ --迭代器返回node-value
+ __ipairs = function(i_t)
+ local idx = 0
+ local function iter(i_t, node)
+ idx = idx + 1
+ if node and node.next ~= last then
+ return node.next, idx, node.next.value
+ end
+ end
+
+ return iter, t, first
+ end,
+ __pairs = function(i_t)
+ local function iter(i_t, node)
+ if node and node.next ~= last then
+ return node.next, node.next.value
+ end
+ end
+
+ return iter, t, first
+ end
+ }
+
+ setmetatable(t, mt)
+
+ return t
+end
+
+return list \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/containers/queue.lua b/Data/DefaultContent/Libraries/containers/queue.lua
new file mode 100644
index 0000000..126daa8
--- /dev/null
+++ b/Data/DefaultContent/Libraries/containers/queue.lua
@@ -0,0 +1,111 @@
+---
+--- Generated by EmmyLua(https://github.com/EmmyLua)
+--- Created by Dee.
+--- DateTime: 2019/3/7 11:27
+--- FIFO
+---
+
+queue = queue or {}
+
+---@return Queue
+function queue.create()
+ ---æ•°æ®å®¹å™¨
+ local data = {}
+ ---æ•°æ®é•¿åº¦
+ local lenght = 0
+ ---队首索引
+ local first = 1
+
+ ---获å–队首值
+ local peek = function()
+ return data[first]
+ end
+
+ ---压入数æ®
+ local enqueue = function(v)
+ assert(v ~= nil, "nil value")
+ first = lenght == 0 and 1 or first
+ lenght = lenght + 1
+ table.insert(data, first+lenght-1, v)
+ end
+
+ ---弹出数æ®
+ local dequeue = function()
+ assert(lenght > 0, "nill queue")
+
+ local ret = peek()
+ data[first] = nil
+ first = first+1
+ lenght = lenght - 1
+ first = lenght == 0 and 1 or first
+
+ if math.fmod(first, 4) == 0 then
+ local tmp = {}
+ table.move(data, first, first + lenght, 1, tmp)
+
+ first = 1
+ data = nil
+ data = tmp
+ end
+
+ return ret
+ end
+
+ local clear = function()
+ data = {}
+ first = 1
+ lenght = 0
+ end
+
+ local __tostring = function()
+ local tmp = {}
+ for i=1,lenght do
+ tmp[i] = data[i + first - 1]
+ end
+ return table.concat(tmp, ",")
+ end
+
+ local __len = function()
+ return lenght
+ end
+
+ local __index = function(i_t, key)
+ error(">> Dee: Limited access")
+ end
+
+ local __newindex = function(i_t, key, v)
+ error(">> Dee: Limited access")
+ end
+
+ local __ipairs = function(i_t)
+ local idx = 0
+ local function iter(i_t)
+ idx = idx + 1
+ if idx <= lenght then
+ return idx, data[first + idx - 1]
+ end
+ end
+
+ return iter
+ end
+
+ local __pairs = function(i_t)
+ error(">> Dee: Limited access")
+ end
+
+ local mt = {__tostring = __tostring, __index = __index, __newindex = __newindex, __ipairs = __ipairs, __pairs = __pairs, __len = __len}
+
+ ---@class Queue
+ local t = {
+ enqueue = enqueue,
+ dequeue = dequeue,
+ peek = peek,
+ clear = clear
+ }
+
+ setmetatable(t, mt)
+
+ return t
+end
+
+return queue
diff --git a/Data/DefaultContent/Libraries/containers/stack.lua b/Data/DefaultContent/Libraries/containers/stack.lua
new file mode 100644
index 0000000..d828c81
--- /dev/null
+++ b/Data/DefaultContent/Libraries/containers/stack.lua
@@ -0,0 +1,67 @@
+--堆栈实现
+stack = stack or {}
+
+function stack.create()
+ local data = {}
+
+ local function push(v)
+ assert(v)
+ table.insert(data, v)
+ end
+
+ local function pop()
+ assert(#data > 0)
+ table.remove(data)
+ end
+
+ local function peek()
+ return #data > 0 and data[#data] or nil
+ end
+
+ local function clear()
+ for i=1,#data do
+ data[i] = nil
+ end
+ end
+
+
+
+ local __tostring = function()
+ local tmp = {}
+ for i,v in ipairs(data) do
+ tmp[#data+1 - i] = v
+ end
+ return table.concat(tmp, ",")
+ end
+
+ local __index = function(i_t, key)
+ error(">> Dee: Limited access")
+ end
+
+ local __len = function()
+ return #data
+ end
+
+ local __newindex = function(i_t, key, v)
+ error(">> Dee: Limited access")
+ end
+
+ local __ipairs = function()
+ error(">> Dee: Limited access")
+ end
+
+ local mt = {__tostring = __tostring, __index = __index, __newindex = __newindex, __ipairs = __ipairs, __pairs = __ipairs, __len = __len}
+
+ local t = {
+ push = push,
+ pop = pop,
+ peek = peek,
+ clear = clear
+ }
+
+ setmetatable(t, mt)
+
+ return t
+end
+
+return stack \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/containers/tuple.lua b/Data/DefaultContent/Libraries/containers/tuple.lua
new file mode 100644
index 0000000..0646d5a
--- /dev/null
+++ b/Data/DefaultContent/Libraries/containers/tuple.lua
@@ -0,0 +1,60 @@
+---
+--- Generated by EmmyLua(https://github.com/EmmyLua)
+--- Created by Dee.
+--- DateTime: 2019/3/7 14:00
+--- 元組,å°ä¿®æ”¹é—œé–‰
+---
+
+tuple = tuple or {}
+
+function tuple.create(i_data)
+ assert(type(i_data) == "table", ">> Dee: shoudle create with table")
+
+ local data = {}
+ for k,v in pairs(i_data) do
+ data[#data+1] = v
+ end
+
+ local t = {}
+
+ local __tostring = function()
+ return table.concat(data, ",")
+ end
+
+ local __index = function(i_t, key)
+ return data[key]
+ end
+
+ local __newindex = function(i_t, key, v)
+ error(">> Dee: Limited access")
+ end
+
+ local __pairs = function()
+ error(">> Dee: Limited access")
+ end
+
+ local __ipairs = function(i_t)
+ local idx = 0
+ local function iter(i_t)
+ idx = idx + 1
+ if idx <= #data then
+ return idx, data[idx]
+ end
+ end
+
+ return iter
+ end
+
+ local __len = function(v)
+ return #data
+ end
+
+ local mt = {__tostring = __tostring, __index = __index, __newindex = __newindex, __pairs =__pairs, __ipairs = __ipairs, __len = __len}
+
+ setmetatable(t, mt)
+
+ return t
+ end
+
+
+return tuple \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/containers/vector.lua b/Data/DefaultContent/Libraries/containers/vector.lua
new file mode 100644
index 0000000..0b349ce
--- /dev/null
+++ b/Data/DefaultContent/Libraries/containers/vector.lua
@@ -0,0 +1,122 @@
+---
+--- Generated by EmmyLua(https://github.com/EmmyLua)
+--- Created by Dee.
+--- DateTime: 2019/3/7 14:00
+--- 快速é历修改,低效的增删
+---
+
+vector = vector or {}
+
+function vector.create()
+ local t = {}
+
+
+ ---尾添加元素(高效)
+ function t:add(v)
+ rawset(self, #self + 1, v)
+ end
+
+ ---æ’å…¥(低效)
+ ---@param k ä½ç½®
+ ---@param v 值
+ function t:insert(k, v)
+ assert(k > 0 and k <= #self, "outrange of vector")
+
+ local cnt = #self
+ for i = cnt, k, -1 do
+ rawset(self, i+1, self[i])
+ end
+
+ rawset(self, k, v)
+ end
+
+ ---值的索引
+ ---@return -1ä¸å­˜åœ¨
+ function t:indexOf(i_v)
+ assert(type(self) == 'table')
+
+ local ret = -1
+ local cnt = #self
+ for i = 1, #self do
+ if self[i] == i_v then
+ ret = i
+ end
+ end
+
+ return ret
+ end
+
+ ---是å¦å­˜åœ¨æŸå…ƒç´ 
+ function t:contains(v)
+ assert(type(self) == 'table')
+ return self:indexOf(v) ~= -1
+ end
+
+ ---æ ¹æ®ä¸‹æ ‡ç´¢å¼•移除元素(低效)
+ function t:removeAt(idx)
+ assert(idx <= #self)
+ table.remove(self, idx)
+ end
+
+ ---删除值(éžè´ªå©ª)
+ ---@return 删除ä½ç½® -1未删除
+ function t:remove(v)
+ local ret = self:indexOf(v)
+ if ret ~= -1 then
+ self:removeAt(ret)
+ end
+
+ return ret
+ end
+
+ ---删除所有值
+ function t:removeAll(v)
+ assert(type(self) == 'table')
+ error(">>Dee: wait ...")
+ end
+
+ ---排åº
+ function t:sort(comparer)
+ assert(type(self) == 'table')
+ table.sort(self, comparer)
+ end
+
+ ---匹é…
+ ---@param 匹é…函数
+ ---@return idx,value
+ function t:find(matcher)
+ assert(type(self) == 'table')
+
+ local _idx, _value = -1, nil
+ local cnt = #self
+ for i = 1, cnt do
+ if matcher(i, self[i]) then
+ _value = self[i]
+ _idx = i
+ break
+ end
+ end
+
+ return _idx, _value
+ end
+
+ --------------------------------metatable---------------------------------------
+ t.__newindex = function(i_t,k,v)
+ error(">> Dee: [], replace with add()")
+ end
+
+ t.__tostring = function(i_t)
+ return table.concat(i_t, ',')
+ end
+
+ t.__pairs = function(...)
+ error(">> Dee: Limited access")
+ end
+
+ setmetatable(t, t)
+ -----------------------------------------------------------------------
+
+ return t
+end
+
+return vector \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/inspect/.travis.yml b/Data/DefaultContent/Libraries/inspect/.travis.yml
new file mode 100644
index 0000000..91f7f93
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/.travis.yml
@@ -0,0 +1,36 @@
+language: python
+sudo: false
+
+env:
+ - LUA="lua=5.1"
+ - LUA="lua=5.2"
+ - LUA="lua=5.3"
+ - LUA="luajit=2.0"
+ - LUA="luajit=2.1"
+
+before_install:
+ - pip install hererocks
+ - hererocks lua_install -r^ --$LUA
+ - export PATH=$PATH:$PWD/lua_install/bin # Add directory with all installed binaries to PATH
+
+install:
+ - luarocks install luacheck
+ - luarocks install busted
+ - luarocks install luacov
+ - luarocks install luacov-coveralls
+
+script:
+ - luacheck --std max+busted *.lua spec
+ - busted --verbose --coverage
+
+after_success:
+ - luacov-coveralls --exclude $TRAVIS_BUILD_DIR/lua_install
+
+branches:
+ except:
+ - gh-pages
+
+notifications:
+ email:
+ on_success: change
+ on_failure: always
diff --git a/Data/DefaultContent/Libraries/inspect/CHANGELOG.md b/Data/DefaultContent/Libraries/inspect/CHANGELOG.md
new file mode 100644
index 0000000..bc2311b
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/CHANGELOG.md
@@ -0,0 +1,39 @@
+## v3.1.1
+
+* Better handling of LuaJIT's `ctype` and `cdata` values (#34, thanks @akopytov)
+
+## v3.1.0
+
+* Fixes bug: all control codes are escaped correctly (instead of only the named ones such as \n).
+ Example: \1 becomes \\1 (or \\001 when followed by a digit)
+* Fixes bug when using the `process` option in recursive tables
+* Overriding global `tostring` with inspect no longer results in an error.
+* Simplifies id generation, using less tables and metatables.
+
+## v3.0.3
+* Fixes a bug which sometimes displayed struct-like parts of tables as sequence-like due
+ to the way rawlen/the # operator are implemented.
+
+## v3.0.2
+* Fixes a bug when a table was garbage-collected while inspect was trying to render it
+
+## v3.0.1
+* Fixes a bug when dealing with tables which have a __len metamethod in Lua >= 5.2
+
+## v3.0.0
+
+The basic functionality remains as before, but there's one backwards-incompatible change if you used `options.filter`.
+
+* **Removed** `options.filter`
+* **Added** `options.process`, which can be used to do the same as `options.filter`, and more.
+* **Added** two new constants, `inspect.METATABLE` and `inspect.KEY`
+* **Added** `options.indent` & `options.newline`.
+
+
+## v2.0.0
+
+* Ability to deal with LuaJit's custom types
+* License change from BSD to MIT
+* Moved second parameter (depth) to options (options.depth)
+* Added a new parameter, options.filter.
+* Reimplemented some parts of the system without object orientation
diff --git a/Data/DefaultContent/Libraries/inspect/MIT-LICENSE.txt b/Data/DefaultContent/Libraries/inspect/MIT-LICENSE.txt
new file mode 100644
index 0000000..555835c
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/MIT-LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright (c) 2013 Enrique García Cota
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Data/DefaultContent/Libraries/inspect/README.md b/Data/DefaultContent/Libraries/inspect/README.md
new file mode 100644
index 0000000..e9c6f86
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/README.md
@@ -0,0 +1,253 @@
+inspect.lua
+===========
+
+[![Build Status](https://travis-ci.org/kikito/inspect.lua.png?branch=master)](https://travis-ci.org/kikito/inspect.lua)
+[![Coverage Status](https://coveralls.io/repos/github/kikito/inspect.lua/badge.svg?branch=master)](https://coveralls.io/github/kikito/inspect.lua?branch=master)
+
+
+This library transforms any Lua value into a human-readable representation. It is especially useful for debugging errors in tables.
+
+The objective here is human understanding (i.e. for debugging), not serialization or compactness.
+
+Examples of use
+===============
+
+`inspect` has the following declaration: `local str = inspect(value, <options>)`.
+
+`value` can be any Lua value.
+
+`inspect` transforms simple types (like strings or numbers) into strings.
+
+```lua
+assert(inspect(1) == "1")
+assert(inspect("Hello") == '"Hello"')
+```
+
+Tables, on the other hand, are rendered in a way a human can read easily.
+
+"Array-like" tables are rendered horizontally:
+
+```lua
+assert(inspect({1,2,3,4}) == "{ 1, 2, 3, 4 }")
+```
+
+"Dictionary-like" tables are rendered with one element per line:
+
+```lua
+assert(inspect({a=1,b=2}) == [[{
+ a = 1,
+ b = 2
+}]])
+```
+
+The keys will be sorted alphanumerically when possible.
+
+"Hybrid" tables will have the array part on the first line, and the dictionary part just below them:
+
+```lua
+assert(inspect({1,2,3,b=2,a=1}) == [[{ 1, 2, 3,
+ a = 1,
+ b = 2
+}]])
+```
+
+Subtables are indented with two spaces per level.
+
+```lua
+assert(inspect({a={b=2}}) == [[{
+ a = {
+ b = 2
+ }
+}]])
+```
+
+Functions, userdata and any other custom types from Luajit are simply as `<function x>`, `<userdata x>`, etc.:
+
+```lua
+assert(inspect({ f = print, ud = some_user_data, thread = a_thread} ) == [[{
+ f = <function 1>,
+ u = <userdata 1>,
+ thread = <thread 1>
+}]])
+```
+
+If the table has a metatable, inspect will include it at the end, in a special field called `<metatable>`:
+
+```lua
+assert(inspect(setmetatable({a=1}, {b=2}) == [[{
+ a = 1
+ <metatable> = {
+ b = 2
+ }
+}]]))
+```
+
+`inspect` can handle tables with loops inside them. It will print `<id>` right before the table is printed out the first time, and replace the whole table with `<table id>` from then on, preventing infinite loops.
+
+```lua
+local a = {1, 2}
+local b = {3, 4, a}
+a[3] = b -- a references b, and b references a
+assert(inspect(a) == "<1>{ 1, 2, { 3, 4, <table 1> } }")
+```
+
+Notice that since both `a` appears more than once in the expression, it is prefixed by `<1>` and replaced by `<table 1>` every time it appears later on.
+
+### options
+
+`inspect` has a second parameter, called `options`. It is not mandatory, but when it is provided, it must be a table.
+
+#### options.depth
+
+`options.depth` sets the maximum depth that will be printed out.
+When the max depth is reached, `inspect` will stop parsing tables and just return `{...}`:
+
+```lua
+
+local t5 = {a = {b = {c = {d = {e = 5}}}}}
+
+assert(inspect(t5, {depth = 4}) == [[{
+ a = {
+ b = {
+ c = {
+ d = {...}
+ }
+ }
+ }
+}]])
+
+assert(inspect(t5, {depth = 2}) == [[{
+ a = {
+ b = {...}
+ }
+}]])
+
+```
+
+`options.depth` defaults to infinite (`math.huge`).
+
+#### options.newline & options.indent
+
+These are the strings used by `inspect` to respectively add a newline and indent each level of a table.
+
+By default, `options.newline` is `"\n"` and `options.indent` is `" "` (two spaces).
+
+``` lua
+local t = {a={b=1}}
+
+assert(inspect(t) == [[{
+ a = {
+ b = 1
+ }
+}]])
+
+assert(inspect(t, {newline='@', indent="++"}), "{@++a = {@++++b = 1@++}@}"
+```
+
+#### options.process
+
+`options.process` is a function which allow altering the passed object before transforming it into a string.
+A typical way to use it would be to remove certain values so that they don't appear at all.
+
+`options.process` has the following signature:
+
+``` lua
+local processed_item = function(item, path)
+```
+
+* `item` is either a key or a value on the table, or any of its subtables
+* `path` is an array-like table built with all the keys that have been used to reach `item`, from the root.
+ * For values, it is just a regular list of keys. For example, to reach the 1 in `{a = {b = 1}}`, the `path`
+ will be `{'a', 'b'}`
+ * For keys, the special value `inspect.KEY` is inserted. For example, to reach the `c` in `{a = {b = {c = 1}}}`,
+ the path will be `{'a', 'b', 'c', inspect.KEY }`
+ * For metatables, the special value `inspect.METATABLE` is inserted. For `{a = {b = 1}}}`, the path
+ `{'a', {b = 1}, inspect.METATABLE}` means "the metatable of the table `{b = 1}`".
+* `processed_item` is the value returned by `options.process`. If it is equal to `item`, then the inspected
+ table will look unchanged. If it is different, then the table will look different; most notably, if it's `nil`,
+ the item will dissapear on the inspected table.
+
+#### Examples
+
+Remove a particular metatable from the result:
+
+``` lua
+local t = {1,2,3}
+local mt = {b = 2}
+setmetatable(t, mt)
+
+local remove_mt = function(item)
+ if item ~= mt then return item end
+end
+
+-- mt does not appear
+assert(inspect(t, {process = remove_mt}) == "{ 1, 2, 3 }")
+```
+
+The previous exaple only works for a particular metatable. If you want to make *all* metatables, you can use the `path` parameter to check
+wether the last element is `inspect.METATABLE`, and return `nil` instead of the item:
+
+``` lua
+local t, mt = ... -- (defined as before)
+
+local remove_all_metatables = function(item, path)
+ if path[#path] ~= inspect.METATABLE then return item end
+end
+
+assert(inspect(t, {process = remove_all_metatables}) == "{ 1, 2, 3 }")
+```
+
+Filter a value:
+
+```lua
+local anonymize_password = function(item, path)
+ if path[#path] == 'password' then return "XXXX" end
+ return item
+end
+
+local info = {user = 'peter', password = 'secret'}
+
+assert(inspect(info, {process = anonymize_password}) == [[{
+ password = "XXXX",
+ user = "peter"
+}]])
+```
+
+Gotchas / Warnings
+==================
+
+This method is *not* appropriate for saving/restoring tables. It is meant to be used by the programmer mainly while debugging a program.
+
+Installation
+============
+
+If you are using luarocks, just run
+
+ luarocks install inspect
+
+Otherwise, you can just copy the inspect.lua file somewhere in your projects (maybe inside a /lib/ folder) and require it accordingly.
+
+Remember to store the value returned by require somewhere! (I suggest a local variable named inspect, although others might like table.inspect)
+
+ local inspect = require 'inspect'
+ -- or --
+ local inspect = require 'lib.inspect'
+
+Also, make sure to read the license; the text of that license file must appear somewhere in your projects' files. For your convenience, it's included at the begining of inspect.lua.
+
+Specs
+=====
+
+This project uses [busted](http://olivinelabs.com/busted/) for its specs. If you want to run the specs, you will have to install busted first. Then just execute the following from the root inspect folder:
+
+ busted
+
+Change log
+==========
+
+Read it on the CHANGELOG.md file
+
+
+
+
+
diff --git a/Data/DefaultContent/Libraries/inspect/inspect.lua b/Data/DefaultContent/Libraries/inspect/inspect.lua
new file mode 100644
index 0000000..e2e3806
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/inspect.lua
@@ -0,0 +1,334 @@
+local inspect ={
+ _VERSION = 'inspect.lua 3.1.0',
+ _URL = 'http://github.com/kikito/inspect.lua',
+ _DESCRIPTION = 'human-readable representations of tables',
+ _LICENSE = [[
+ MIT LICENSE
+
+ Copyright (c) 2013 Enrique García Cota
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ ]]
+}
+
+local tostring = tostring
+
+inspect.KEY = setmetatable({}, {__tostring = function() return 'inspect.KEY' end})
+inspect.METATABLE = setmetatable({}, {__tostring = function() return 'inspect.METATABLE' end})
+
+local function rawpairs(t)
+ return next, t, nil
+end
+
+-- Apostrophizes the string if it has quotes, but not aphostrophes
+-- Otherwise, it returns a regular quoted string
+local function smartQuote(str)
+ if str:match('"') and not str:match("'") then
+ return "'" .. str .. "'"
+ end
+ return '"' .. str:gsub('"', '\\"') .. '"'
+end
+
+-- \a => '\\a', \0 => '\\0', 31 => '\31'
+local shortControlCharEscapes = {
+ ["\a"] = "\\a", ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n",
+ ["\r"] = "\\r", ["\t"] = "\\t", ["\v"] = "\\v"
+}
+local longControlCharEscapes = {} -- \a => nil, \0 => \000, 31 => \031
+for i=0, 31 do
+ local ch = string.char(i)
+ if not shortControlCharEscapes[ch] then
+ shortControlCharEscapes[ch] = "\\"..i
+ longControlCharEscapes[ch] = string.format("\\%03d", i)
+ end
+end
+
+local function escape(str)
+ return (str:gsub("\\", "\\\\")
+ :gsub("(%c)%f[0-9]", longControlCharEscapes)
+ :gsub("%c", shortControlCharEscapes))
+end
+
+local function isIdentifier(str)
+ return type(str) == 'string' and str:match( "^[_%a][_%a%d]*$" )
+end
+
+local function isSequenceKey(k, sequenceLength)
+ return type(k) == 'number'
+ and 1 <= k
+ and k <= sequenceLength
+ and math.floor(k) == k
+end
+
+local defaultTypeOrders = {
+ ['number'] = 1, ['boolean'] = 2, ['string'] = 3, ['table'] = 4,
+ ['function'] = 5, ['userdata'] = 6, ['thread'] = 7
+}
+
+local function sortKeys(a, b)
+ local ta, tb = type(a), type(b)
+
+ -- strings and numbers are sorted numerically/alphabetically
+ if ta == tb and (ta == 'string' or ta == 'number') then return a < b end
+
+ local dta, dtb = defaultTypeOrders[ta], defaultTypeOrders[tb]
+ -- Two default types are compared according to the defaultTypeOrders table
+ if dta and dtb then return defaultTypeOrders[ta] < defaultTypeOrders[tb]
+ elseif dta then return true -- default types before custom ones
+ elseif dtb then return false -- custom types after default ones
+ end
+
+ -- custom types are sorted out alphabetically
+ return ta < tb
+end
+
+-- For implementation reasons, the behavior of rawlen & # is "undefined" when
+-- tables aren't pure sequences. So we implement our own # operator.
+local function getSequenceLength(t)
+ local len = 1
+ local v = rawget(t,len)
+ while v ~= nil do
+ len = len + 1
+ v = rawget(t,len)
+ end
+ return len - 1
+end
+
+local function getNonSequentialKeys(t)
+ local keys, keysLength = {}, 0
+ local sequenceLength = getSequenceLength(t)
+ for k,_ in rawpairs(t) do
+ if not isSequenceKey(k, sequenceLength) then
+ keysLength = keysLength + 1
+ keys[keysLength] = k
+ end
+ end
+ table.sort(keys, sortKeys)
+ return keys, keysLength, sequenceLength
+end
+
+local function countTableAppearances(t, tableAppearances)
+ tableAppearances = tableAppearances or {}
+
+ if type(t) == 'table' then
+ if not tableAppearances[t] then
+ tableAppearances[t] = 1
+ for k,v in rawpairs(t) do
+ countTableAppearances(k, tableAppearances)
+ countTableAppearances(v, tableAppearances)
+ end
+ countTableAppearances(getmetatable(t), tableAppearances)
+ else
+ tableAppearances[t] = tableAppearances[t] + 1
+ end
+ end
+
+ return tableAppearances
+end
+
+local copySequence = function(s)
+ local copy, len = {}, #s
+ for i=1, len do copy[i] = s[i] end
+ return copy, len
+end
+
+local function makePath(path, ...)
+ local keys = {...}
+ local newPath, len = copySequence(path)
+ for i=1, #keys do
+ newPath[len + i] = keys[i]
+ end
+ return newPath
+end
+
+local function processRecursive(process, item, path, visited)
+ if item == nil then return nil end
+ if visited[item] then return visited[item] end
+
+ local processed = process(item, path)
+ if type(processed) == 'table' then
+ local processedCopy = {}
+ visited[item] = processedCopy
+ local processedKey
+
+ for k,v in rawpairs(processed) do
+ processedKey = processRecursive(process, k, makePath(path, k, inspect.KEY), visited)
+ if processedKey ~= nil then
+ processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey), visited)
+ end
+ end
+
+ local mt = processRecursive(process, getmetatable(processed), makePath(path, inspect.METATABLE), visited)
+ if type(mt) ~= 'table' then mt = nil end -- ignore not nil/table __metatable field
+ setmetatable(processedCopy, mt)
+ processed = processedCopy
+ end
+ return processed
+end
+
+
+
+-------------------------------------------------------------------
+
+local Inspector = {}
+local Inspector_mt = {__index = Inspector}
+
+function Inspector:puts(...)
+ local args = {...}
+ local buffer = self.buffer
+ local len = #buffer
+ for i=1, #args do
+ len = len + 1
+ buffer[len] = args[i]
+ end
+end
+
+function Inspector:down(f)
+ self.level = self.level + 1
+ f()
+ self.level = self.level - 1
+end
+
+function Inspector:tabify()
+ self:puts(self.newline, string.rep(self.indent, self.level))
+end
+
+function Inspector:alreadyVisited(v)
+ return self.ids[v] ~= nil
+end
+
+function Inspector:getId(v)
+ local id = self.ids[v]
+ if not id then
+ local tv = type(v)
+ id = (self.maxIds[tv] or 0) + 1
+ self.maxIds[tv] = id
+ self.ids[v] = id
+ end
+ return tostring(id)
+end
+
+function Inspector:putKey(k)
+ if isIdentifier(k) then return self:puts(k) end
+ self:puts("[")
+ self:putValue(k)
+ self:puts("]")
+end
+
+function Inspector:putTable(t)
+ if t == inspect.KEY or t == inspect.METATABLE then
+ self:puts(tostring(t))
+ elseif self:alreadyVisited(t) then
+ self:puts('<table ', self:getId(t), '>')
+ elseif self.level >= self.depth then
+ self:puts('{...}')
+ else
+ if self.tableAppearances[t] > 1 then self:puts('<', self:getId(t), '>') end
+
+ local nonSequentialKeys, nonSequentialKeysLength, sequenceLength = getNonSequentialKeys(t)
+ local mt = getmetatable(t)
+
+ self:puts('{')
+ self:down(function()
+ local count = 0
+ for i=1, sequenceLength do
+ if count > 0 then self:puts(',') end
+ self:puts(' ')
+ self:putValue(t[i])
+ count = count + 1
+ end
+
+ for i=1, nonSequentialKeysLength do
+ local k = nonSequentialKeys[i]
+ if count > 0 then self:puts(',') end
+ self:tabify()
+ self:putKey(k)
+ self:puts(' = ')
+ self:putValue(t[k])
+ count = count + 1
+ end
+
+ if type(mt) == 'table' then
+ if count > 0 then self:puts(',') end
+ self:tabify()
+ self:puts('<metatable> = ')
+ self:putValue(mt)
+ end
+ end)
+
+ if nonSequentialKeysLength > 0 or type(mt) == 'table' then -- result is multi-lined. Justify closing }
+ self:tabify()
+ elseif sequenceLength > 0 then -- array tables have one extra space before closing }
+ self:puts(' ')
+ end
+
+ self:puts('}')
+ end
+end
+
+function Inspector:putValue(v)
+ local tv = type(v)
+
+ if tv == 'string' then
+ self:puts(smartQuote(escape(v)))
+ elseif tv == 'number' or tv == 'boolean' or tv == 'nil' or
+ tv == 'cdata' or tv == 'ctype' then
+ self:puts(tostring(v))
+ elseif tv == 'table' then
+ self:putTable(v)
+ else
+ self:puts('<', tv, ' ', self:getId(v), '>')
+ end
+end
+
+-------------------------------------------------------------------
+
+function inspect.inspect(root, options)
+ options = options or {}
+
+ local depth = options.depth or math.huge
+ local newline = options.newline or '\n'
+ local indent = options.indent or ' '
+ local process = options.process
+
+ if process then
+ root = processRecursive(process, root, {}, {})
+ end
+
+ local inspector = setmetatable({
+ depth = depth,
+ level = 0,
+ buffer = {},
+ ids = {},
+ maxIds = {},
+ newline = newline,
+ indent = indent,
+ tableAppearances = countTableAppearances(root)
+ }, Inspector_mt)
+
+ inspector:putValue(root)
+
+ return table.concat(inspector.buffer)
+end
+
+setmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) end })
+
+return inspect
+
diff --git a/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-1.2-2.rockspec b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-1.2-2.rockspec
new file mode 100644
index 0000000..b683143
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-1.2-2.rockspec
@@ -0,0 +1,23 @@
+package = "inspect"
+version = "1.2-2"
+source = {
+ url = "https://github.com/kikito/inspect.lua/archive/v1.2.0.tar.gz",
+ dir = "inspect.lua-1.2.0"
+}
+description = {
+ summary = "Lua table visualizer, ideal for debugging",
+ detailed = [[
+ inspect will print out your lua tables nicely so you can debug your programs quickly. It sorts keys by type and name, handles data recursion
+ ]],
+ homepage = "https://github.com/kikito/inspect.lua",
+ license = "MIT <http://opensource.org/licenses/MIT>"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ inspect = "inspect.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-2.0-1.rockspec b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-2.0-1.rockspec
new file mode 100644
index 0000000..286bbd5
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-2.0-1.rockspec
@@ -0,0 +1,23 @@
+package = "inspect"
+version = "2.0-1"
+source = {
+ url = "https://github.com/kikito/inspect.lua/archive/v2.0.0.tar.gz",
+ dir = "inspect.lua-2.0.0"
+}
+description = {
+ summary = "Lua table visualizer, ideal for debugging",
+ detailed = [[
+ inspect will print out your lua tables nicely so you can debug your programs quickly. It sorts keys by type and name, handles data recursion
+ ]],
+ homepage = "https://github.com/kikito/inspect.lua",
+ license = "MIT <http://opensource.org/licenses/MIT>"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ inspect = "inspect.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-1.rockspec b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-1.rockspec
new file mode 100644
index 0000000..387d450
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-1.rockspec
@@ -0,0 +1,23 @@
+package = "inspect"
+version = "3.0-1"
+source = {
+ url = "https://github.com/kikito/inspect.lua/archive/v3.0.0.tar.gz",
+ dir = "inspect.lua-3.0.0"
+}
+description = {
+ summary = "Lua table visualizer, ideal for debugging",
+ detailed = [[
+ inspect will print out your lua tables nicely so you can debug your programs quickly. It sorts keys by type and name and handles recursive tables properly.
+ ]],
+ homepage = "https://github.com/kikito/inspect.lua",
+ license = "MIT <http://opensource.org/licenses/MIT>"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ inspect = "inspect.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-2.rockspec b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-2.rockspec
new file mode 100644
index 0000000..b22ec9c
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-2.rockspec
@@ -0,0 +1,23 @@
+package = "inspect"
+version = "3.0-2"
+source = {
+ url = "https://github.com/kikito/inspect.lua/archive/v3.0.1.tar.gz",
+ dir = "inspect.lua-3.0.1"
+}
+description = {
+ summary = "Lua table visualizer, ideal for debugging",
+ detailed = [[
+ inspect will print out your lua tables nicely so you can debug your programs quickly. It sorts keys by type and name and handles recursive tables properly.
+ ]],
+ homepage = "https://github.com/kikito/inspect.lua",
+ license = "MIT <http://opensource.org/licenses/MIT>"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ inspect = "inspect.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-3.rockspec b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-3.rockspec
new file mode 100644
index 0000000..9e07b01
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-3.rockspec
@@ -0,0 +1,23 @@
+package = "inspect"
+version = "3.0-3"
+source = {
+ url = "https://github.com/kikito/inspect.lua/archive/v3.0.2.tar.gz",
+ dir = "inspect.lua-3.0.2"
+}
+description = {
+ summary = "Lua table visualizer, ideal for debugging",
+ detailed = [[
+ inspect will print out your lua tables nicely so you can debug your programs quickly. It sorts keys by type and name and handles recursive tables properly.
+ ]],
+ homepage = "https://github.com/kikito/inspect.lua",
+ license = "MIT <http://opensource.org/licenses/MIT>"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ inspect = "inspect.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-4.rockspec b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-4.rockspec
new file mode 100644
index 0000000..56f3d48
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.0-4.rockspec
@@ -0,0 +1,23 @@
+package = "inspect"
+version = "3.0-4"
+source = {
+ url = "https://github.com/kikito/inspect.lua/archive/v3.0.3.tar.gz",
+ dir = "inspect.lua-3.0.3"
+}
+description = {
+ summary = "Lua table visualizer, ideal for debugging",
+ detailed = [[
+ inspect will print out your lua tables nicely so you can debug your programs quickly. It sorts keys by type and name and handles recursive tables properly.
+ ]],
+ homepage = "https://github.com/kikito/inspect.lua",
+ license = "MIT <http://opensource.org/licenses/MIT>"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ inspect = "inspect.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.1.1-0.rockspec b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.1.1-0.rockspec
new file mode 100644
index 0000000..740b644
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/rockspecs/inspect-3.1.1-0.rockspec
@@ -0,0 +1,23 @@
+package = "inspect"
+version = "3.1.1-0"
+source = {
+ url = "https://github.com/kikito/inspect.lua/archive/v3.1.1.tar.gz",
+ dir = "inspect.lua-3.1.1"
+}
+description = {
+ summary = "Lua table visualizer, ideal for debugging",
+ detailed = [[
+ inspect will print out your lua tables nicely so you can debug your programs quickly. It sorts keys by type and name and handles recursive tables properly.
+ ]],
+ homepage = "https://github.com/kikito/inspect.lua",
+ license = "MIT <http://opensource.org/licenses/MIT>"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ inspect = "inspect.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/inspect/spec/inspect_spec.lua b/Data/DefaultContent/Libraries/inspect/spec/inspect_spec.lua
new file mode 100644
index 0000000..edea720
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/spec/inspect_spec.lua
@@ -0,0 +1,460 @@
+local inspect = require 'inspect'
+local unindent = require 'spec.unindent'
+local is_luajit, ffi = pcall(require, 'ffi')
+local has_rawlen = type(_G.rawlen) == 'function'
+
+describe( 'inspect', function()
+
+ describe('numbers', function()
+ it('works', function()
+ assert.equals("1", inspect(1))
+ assert.equals("1.5", inspect(1.5))
+ assert.equals("-3.14", inspect(-3.14))
+ end)
+ end)
+
+ describe('strings', function()
+ it('puts quotes around regular strings', function()
+ assert.equals('"hello"', inspect("hello"))
+ end)
+
+ it('puts apostrophes around strings with quotes', function()
+ assert.equals("'I have \"quotes\"'", inspect('I have "quotes"'))
+ end)
+
+ it('uses regular quotes if the string has both quotes and apostrophes', function()
+ assert.equals('"I have \\"quotes\\" and \'apostrophes\'"', inspect("I have \"quotes\" and 'apostrophes'"))
+ end)
+
+ it('escapes newlines properly', function()
+ assert.equals('"I have \\n new \\n lines"', inspect('I have \n new \n lines'))
+ end)
+
+ it('escapes tabs properly', function()
+ assert.equals('"I have \\t a tab character"', inspect('I have \t a tab character'))
+ end)
+
+ it('escapes backspaces properly', function()
+ assert.equals('"I have \\b a back space"', inspect('I have \b a back space'))
+ end)
+
+ it('escapes unnamed control characters with 1 or 2 digits', function()
+ assert.equals('"Here are some control characters: \\0 \\1 \\6 \\17 \\27 \\31"',
+ inspect('Here are some control characters: \0 \1 \6 \17 \27 \31'))
+ end)
+
+ it('escapes unnamed control characters with 3 digits when they are followed by numbers', function()
+ assert.equals('"Control chars followed by digits \\0001 \\0011 \\0061 \\0171 \\0271 \\0311"',
+ inspect('Control chars followed by digits \0001 \0011 \0061 \0171 \0271 \0311'))
+ end)
+
+ it('backslashes its backslashes', function()
+ assert.equals('"I have \\\\ a backslash"', inspect('I have \\ a backslash'))
+ assert.equals('"I have \\\\\\\\ two backslashes"', inspect('I have \\\\ two backslashes'))
+ assert.equals('"I have \\\\\\n a backslash followed by a newline"',
+ inspect('I have \\\n a backslash followed by a newline'))
+ end)
+
+ end)
+
+ it('works with nil', function()
+ assert.equals('nil', inspect(nil))
+ end)
+
+ it('works with functions', function()
+ assert.equals('{ <function 1>, <function 2>, <function 1> }', inspect({ print, type, print }))
+ end)
+
+ it('works with booleans', function()
+ assert.equals('true', inspect(true))
+ assert.equals('false', inspect(false))
+ end)
+
+ if is_luajit then
+ it('works with luajit cdata', function()
+ assert.equals('{ cdata<int>: PTR, ctype<int>, cdata<int>: PTR }',
+ inspect({ ffi.new("int", 1), ffi.typeof("int"), ffi.typeof("int")(1) }):gsub('(0x%x+)','PTR'))
+ end)
+ end
+
+ describe('tables', function()
+
+ it('works with simple array-like tables', function()
+ assert.equals("{ 1, 2, 3 }", inspect({1,2,3}))
+ end)
+
+ it('works with nested arrays', function()
+ assert.equals('{ "a", "b", "c", { "d", "e" }, "f" }', inspect({'a','b','c', {'d','e'}, 'f'}))
+ end)
+
+ if has_rawlen then
+ it('handles arrays with a __len metatable correctly (ignoring the __len metatable and using rawlen)', function()
+ local arr = setmetatable({1,2,3}, {__len = function() return nil end})
+ assert.equals("{ 1, 2, 3,\n <metatable> = {\n __len = <function 1>\n }\n}", inspect(arr))
+ end)
+
+ it('handles tables with a __pairs metamethod (ignoring the __pairs metamethod and using next)', function()
+ local t = setmetatable({ {}, name = "yeah" }, { __pairs = function() end })
+ assert.equals(
+ unindent([[{ {},
+ name = "yeah",
+ <metatable> = {
+ __pairs = <function 1>
+ }
+ }]]),
+ inspect(t))
+ end)
+ end
+
+ it('works with simple dictionary tables', function()
+ assert.equals("{\n a = 1,\n b = 2\n}", inspect({a = 1, b = 2}))
+ end)
+
+ it('identifies tables with no number 1 as struct-like', function()
+ assert.equals(unindent([[{
+ [2] = 1,
+ [25] = 1,
+ id = 1
+ }
+ ]]), inspect({[2]=1,[25]=1,id=1}))
+ end)
+
+ it('identifies numeric non-array keys as dictionary keys', function()
+ assert.equals("{ 1, 2,\n [-1] = true\n}", inspect({1, 2, [-1] = true}))
+ assert.equals("{ 1, 2,\n [1.5] = true\n}", inspect({1, 2, [1.5] = true}))
+ end)
+
+ it('sorts keys in dictionary tables', function()
+ local t = { 1,2,3,
+ [print] = 1, ["buy more"] = 1, a = 1,
+ [coroutine.create(function() end)] = 1,
+ [14] = 1, [{c=2}] = 1, [true]= 1
+ }
+ assert.equals(unindent([[
+ { 1, 2, 3,
+ [14] = 1,
+ [true] = 1,
+ a = 1,
+ ["buy more"] = 1,
+ [{
+ c = 2
+ }] = 1,
+ [<function 1>] = 1,
+ [<thread 1>] = 1
+ }
+ ]]), inspect(t))
+ end)
+
+ it('works with nested dictionary tables', function()
+ assert.equals(unindent([[{
+ a = 1,
+ b = {
+ c = 2
+ },
+ d = 3
+ }]]), inspect( {d=3, b={c=2}, a=1} ))
+ end)
+
+ it('works with hybrid tables', function()
+ assert.equals(unindent([[
+ { "a", {
+ b = 1
+ }, 2,
+ ["ahoy you"] = 4,
+ c = 3
+ }
+ ]]), inspect({ 'a', {b = 1}, 2, c = 3, ['ahoy you'] = 4 }))
+
+
+ end)
+
+ it('displays <table x> instead of repeating an already existing table', function()
+ local a = { 1, 2, 3 }
+ local b = { 'a', 'b', 'c', a }
+ a[4] = b
+ a[5] = a
+ a[6] = b
+ assert.equals('<1>{ 1, 2, 3, <2>{ "a", "b", "c", <table 1> }, <table 1>, <table 2> }', inspect(a))
+ end)
+
+ describe('The depth parameter', function()
+ local level5 = { 1,2,3, a = { b = { c = { d = { e = 5 } } } } }
+ local keys = { [level5] = true }
+
+ it('has infinite depth by default', function()
+ assert.equals(unindent([[
+ { 1, 2, 3,
+ a = {
+ b = {
+ c = {
+ d = {
+ e = 5
+ }
+ }
+ }
+ }
+ }
+ ]]), inspect(level5))
+ end)
+ it('is modifiable by the user', function()
+ assert.equals(unindent([[
+ { 1, 2, 3,
+ a = {
+ b = {...}
+ }
+ }
+ ]]), inspect(level5, {depth = 2}))
+
+ assert.equals(unindent([[
+ { 1, 2, 3,
+ a = {...}
+ }
+ ]]), inspect(level5, {depth = 1}))
+
+ assert.equals(unindent([[
+ { 1, 2, 3,
+ a = {
+ b = {
+ c = {
+ d = {...}
+ }
+ }
+ }
+ }
+ ]]), inspect(level5, {depth = 4}))
+
+ assert.equals("{...}", inspect(level5, {depth = 0}))
+ end)
+
+ it('respects depth on keys', function()
+ assert.equals(unindent([[
+ {
+ [{ 1, 2, 3,
+ a = {
+ b = {
+ c = {...}
+ }
+ }
+ }] = true
+ }
+ ]]), inspect(keys, {depth = 4}))
+ end)
+ end)
+
+ describe('the newline option', function()
+ it('changes the substring used for newlines', function()
+ local t = {a={b=1}}
+
+ assert.equal("{@ a = {@ b = 1@ }@}", inspect(t, {newline='@'}))
+ end)
+ end)
+
+ describe('the indent option', function()
+ it('changes the substring used for indenting', function()
+ local t = {a={b=1}}
+
+ assert.equal("{\n>>>a = {\n>>>>>>b = 1\n>>>}\n}", inspect(t, {indent='>>>'}))
+ end)
+ end)
+
+ describe('the process option', function()
+
+ it('removes one element', function()
+ local names = {'Andrew', 'Peter', 'Ann' }
+ local removeAnn = function(item) if item ~= 'Ann' then return item end end
+ assert.equals('{ "Andrew", "Peter" }', inspect(names, {process = removeAnn}))
+ end)
+
+ it('uses the path', function()
+ local names = {'Andrew', 'Peter', 'Ann' }
+ local removeThird = function(item, path) if path[1] ~= 3 then return item end end
+ assert.equals('{ "Andrew", "Peter" }', inspect(names, {process = removeThird}))
+ end)
+
+ it('replaces items', function()
+ local names = {'Andrew', 'Peter', 'Ann' }
+ local filterAnn = function(item) return item == 'Ann' and '<filtered>' or item end
+ assert.equals('{ "Andrew", "Peter", "<filtered>" }', inspect(names, {process = filterAnn}))
+ end)
+
+ it('nullifies metatables', function()
+ local mt = {'world'}
+ local t = setmetatable({'hello'}, mt)
+ local removeMt = function(item) if item ~= mt then return item end end
+ assert.equals('{ "hello" }', inspect(t, {process = removeMt}))
+ end)
+
+ it('nullifies metatables using their paths', function()
+ local mt = {'world'}
+ local t = setmetatable({'hello'}, mt)
+ local removeMt = function(item, path) if path[#path] ~= inspect.METATABLE then return item end end
+ assert.equals('{ "hello" }', inspect(t, {process = removeMt}))
+ end)
+
+ it('nullifies the root object', function()
+ local names = {'Andrew', 'Peter', 'Ann' }
+ local removeNames = function(item) if item ~= names then return item end end
+ assert.equals('nil', inspect(names, {process = removeNames}))
+ end)
+
+ it('changes keys', function()
+ local dict = {a = 1}
+ local changeKey = function(item) return item == 'a' and 'x' or item end
+ assert.equals('{\n x = 1\n}', inspect(dict, {process = changeKey}))
+ end)
+
+ it('nullifies keys', function()
+ local dict = {a = 1, b = 2}
+ local removeA = function(item) return item ~= 'a' and item or nil end
+ assert.equals('{\n b = 2\n}', inspect(dict, {process = removeA}))
+ end)
+
+ it('prints inspect.KEY & inspect.METATABLE', function()
+ local t = {inspect.KEY, inspect.METATABLE}
+ assert.equals("{ inspect.KEY, inspect.METATABLE }", inspect(t))
+ end)
+
+ it('marks key paths with inspect.KEY and metatables with inspect.METATABLE', function()
+ local t = { [{a=1}] = setmetatable({b=2}, {c=3}) }
+
+ local items = {}
+ local addItem = function(item, path)
+ items[#items + 1] = {item = item, path = path}
+ return item
+ end
+
+ inspect(t, {process = addItem})
+
+ assert.same({
+ {item = t, path = {}},
+ {item = {a=1}, path = {{a=1}, inspect.KEY}},
+ {item = 'a', path = {{a=1}, inspect.KEY, 'a', inspect.KEY}},
+ {item = 1, path = {{a=1}, inspect.KEY, 'a'}},
+ {item = setmetatable({b=2}, {c=3}), path = {{a=1}}},
+ {item = 'b', path = {{a=1}, 'b', inspect.KEY}},
+ {item = 2, path = {{a=1}, 'b'}},
+ {item = {c=3}, path = {{a=1}, inspect.METATABLE}},
+ {item = 'c', path = {{a=1}, inspect.METATABLE, 'c', inspect.KEY}},
+ {item = 3, path = {{a=1}, inspect.METATABLE, 'c'}}
+ }, items)
+
+ end)
+
+ it('handles recursive tables correctly', function()
+ local tbl = { 1,2,3}
+ tbl.loop = tbl
+ inspect(tbl, { process=function(x) return x end})
+ end)
+ end)
+
+ describe('metatables', function()
+
+ it('includes the metatable as an extra hash attribute', function()
+ local foo = { foo = 1, __mode = 'v' }
+ local bar = setmetatable({a = 1}, foo)
+ assert.equals(unindent([[
+ {
+ a = 1,
+ <metatable> = {
+ __mode = "v",
+ foo = 1
+ }
+ }
+ ]]), inspect(bar))
+ end)
+
+ it('can be used on the __tostring metamethod of a table without errors', function()
+ local f = function(x) return inspect(x) end
+ local tbl = setmetatable({ x = 1 }, { __tostring = f })
+ assert.equals(unindent([[
+ {
+ x = 1,
+ <metatable> = {
+ __tostring = <function 1>
+ }
+ }
+ ]]), tostring(tbl))
+ end)
+
+ it('does not allow collecting weak tables while they are being inspected', function()
+ collectgarbage('stop')
+ finally(function() collectgarbage('restart') end)
+ local shimMetatable = {
+ __mode = 'v',
+ __index = function() return {} end,
+ }
+ local function shim() return setmetatable({}, shimMetatable) end
+ local t = shim()
+ t.key = shim()
+ assert.equals(unindent([[
+ {
+ key = {
+ <metatable> = <1>{
+ __index = <function 1>,
+ __mode = "v"
+ }
+ },
+ <metatable> = <table 1>
+ }
+ ]]), inspect(t))
+ end)
+
+ it('ignores metatables with __metatable field set to non-nil and non-table type', function()
+ local function process(item) return item end
+ local function inspector(data) return inspect(data, {process=process}) end
+
+ local foo = setmetatable({}, {__metatable=false})
+ local bar = setmetatable({}, {__metatable=true})
+ local baz = setmetatable({}, {__metatable=10})
+ local spam = setmetatable({}, {__metatable=nil})
+ local eggs = setmetatable({}, {__metatable={}})
+ assert.equals(unindent('{}'), inspector(foo))
+ assert.equals(unindent('{}'), inspector(bar))
+ assert.equals(unindent('{}'), inspector(baz))
+ assert.equals(unindent([[
+ {
+ <metatable> = {}
+ }
+ ]]), inspector(spam))
+ assert.equals(unindent([[
+ {
+ <metatable> = {}
+ }
+ ]]), inspector(eggs))
+ end)
+
+ describe('When a table is its own metatable', function()
+ it('accepts a table that is its own metatable without stack overflowing', function()
+ local x = {}
+ setmetatable(x,x)
+ assert.equals(unindent([[
+ <1>{
+ <metatable> = <table 1>
+ }
+ ]]), inspect(x))
+ end)
+
+ it('can invoke the __tostring method without stack overflowing', function()
+ local t = {}
+ t.__index = t
+ setmetatable(t,t)
+ assert.equals(unindent([[
+ <1>{
+ __index = <table 1>,
+ <metatable> = <table 1>
+ }
+ ]]), inspect(t))
+ end)
+ end)
+ end)
+ end)
+
+ it('allows changing the global tostring', function()
+ local save = _G.tostring
+ _G.tostring = inspect
+ local s = tostring({1, 2, 3})
+ _G.tostring = save
+ assert.equals("{ 1, 2, 3 }", s)
+ end)
+
+end)
diff --git a/Data/DefaultContent/Libraries/inspect/spec/unindent.lua b/Data/DefaultContent/Libraries/inspect/spec/unindent.lua
new file mode 100644
index 0000000..02324a1
--- /dev/null
+++ b/Data/DefaultContent/Libraries/inspect/spec/unindent.lua
@@ -0,0 +1,39 @@
+-- Unindenting transforms a string like this:
+-- [[
+-- {
+-- foo = 1,
+-- bar = 2
+-- }
+-- ]]
+--
+-- Into the same one without indentation, nor start/end newlines
+--
+-- [[{
+-- foo = 1,
+-- bar = 2
+-- }]]
+--
+-- This makes the strings look and read better in the tests
+--
+
+local getIndentPreffix = function(str)
+ local level = math.huge
+ local minPreffix = ""
+ local len
+ for preffix in str:gmatch("\n( +)") do
+ len = #preffix
+ if len < level then
+ level = len
+ minPreffix = preffix
+ end
+ end
+ return minPreffix
+end
+
+local unindent = function(str)
+ str = str:gsub(" +$", ""):gsub("^ +", "") -- remove spaces at start and end
+ local preffix = getIndentPreffix(str)
+ return (str:gsub("\n" .. preffix, "\n"):gsub("\n$", ""))
+end
+
+return unindent
diff --git a/Data/DefaultContent/Libraries/json4lua/README.md b/Data/DefaultContent/Libraries/json4lua/README.md
new file mode 100644
index 0000000..b4f8015
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/README.md
@@ -0,0 +1,52 @@
+# json4lua
+JSON and JSONRPC for Lua
+
+# Installation #
+```
+luarocks install --server=http://rocks.moonscript.org/manifests/amrhassan --local json4Lua
+```
+
+# JSON Usage #
+
+## Encoding ##
+
+```lua
+json = require('json')
+print(json.encode({ 1, 2, 'fred', {first='mars',second='venus',third='earth'} }))
+```
+```json
+[1,2,"fred", {"first":"mars","second":"venus","third":"earth"}]
+```
+
+## Decoding ##
+
+```lua
+json = require("json")
+testString = [[ { "one":1 , "two":2, "primes":[2,3,5,7] } ]]
+decoded = json.decode(testString)
+table.foreach(decoded, print)
+print ("Primes are:")
+table.foreach(decoded.primes,print)
+```
+```
+one 1
+two 2
+primes table: 0032B928
+Primes are:
+1 2
+2 3
+3 5
+4 7
+```
+
+# JSONRPC Usage #
+```lua
+json = require('json')
+require("json.rpc")
+server = json.rpc.proxy("http://jsolait.net/testj.py")
+result, error = server.echo('Test echo!')
+print(result)
+```
+```
+Test echo!
+```
diff --git a/Data/DefaultContent/Libraries/json4lua/doc/INSTALL.txt b/Data/DefaultContent/Libraries/json4lua/doc/INSTALL.txt
new file mode 100644
index 0000000..3e7cad3
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/doc/INSTALL.txt
@@ -0,0 +1,4 @@
+INSTALLATION
+============
+
+See INSTALLATION section in doc/index.html \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/json4lua/doc/LICENCE.txt b/Data/DefaultContent/Libraries/json4lua/doc/LICENCE.txt
new file mode 100644
index 0000000..48f61e7
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/doc/LICENCE.txt
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2009 Craig Mason-Jones
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE. \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/json4lua/doc/README.txt b/Data/DefaultContent/Libraries/json4lua/doc/README.txt
new file mode 100644
index 0000000..59e5b7b
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/doc/README.txt
@@ -0,0 +1,5 @@
+===================================================================================================================
+== README.txt
+===================================================================================================================
+
+Please see doc/index.html
diff --git a/Data/DefaultContent/Libraries/json4lua/doc/VERSION.txt b/Data/DefaultContent/Libraries/json4lua/doc/VERSION.txt
new file mode 100644
index 0000000..deae881
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/doc/VERSION.txt
@@ -0,0 +1,4 @@
+JSON4Lua and JSONRPC4Lua
+Version 1.0.0
+4 March 2015
+http://github.com/craigmj/json4lua/ \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/json4lua/doc/cgilua_patch.html b/Data/DefaultContent/Libraries/json4lua/doc/cgilua_patch.html
new file mode 100644
index 0000000..1b4d6b3
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/doc/cgilua_patch.html
@@ -0,0 +1,187 @@
+<html>
+<head>
+<title>JSON4Lua and JSONRPC4Lua</title>
+<style type="text/css">
+body {
+ font-family: Arial, Helvetica, Geneva;
+ font-size: 10pt;
+}
+
+.copyright {
+ color: #999999;
+ font-size: 8pt;
+ text-align:center;
+}
+
+.navBar {
+ border-left: 1px solid lightgray;
+ border-right: 1px solid lightgray;
+ border-bottom: 1px solid lightgray;
+ margin-top:5px;
+ margin-bottom: 5px;
+}
+.navBar h1 {
+ background-image: url('pics/lunartone.gif');
+ background-color: #e0c088;
+ color: white;
+ font-size: 9pt;
+ margin: 0px;
+ padding: 4px;
+}
+
+.navBar .navItem a {
+ color: #999999;
+ font-size: 8pt;
+ padding: 2px 2px 2px 10px;
+ text-decoration:none;
+}
+
+.navBar .navItem a:hover {
+ color: #ff9900;
+ text-decoration: underline;
+}
+
+.titleBar {
+ border-bottom: 2px dotted gray;
+ font-size: 20pt;
+ font-weight: bold;
+ margin-bottom: 15px;
+ width: 100%;
+}
+
+.workArea {
+ border: 1px none lightgray;
+ font-family: Times New Roman;
+ padding: 8px;
+ padding-left: 15px;
+}
+
+.workArea a {
+ font-weight: bold;
+ text-decoration: none;
+}
+
+.workArea a:hover {
+ color: #ff9900;
+ text-decoration: underline;
+}
+
+.workArea .downloadTable {
+ border: 1px solid lightgray;
+ padding: 0px;
+ margin: 0px;
+}
+
+.workArea .downloadTable * th {
+ background-color: #e0c088;
+ background-image: url('pics/lunartone.gif');
+ color: white;
+}
+
+.workArea .downloadTable * tr {
+ border: 1px solid lightgray;
+}
+
+.workArea .downloadTable * td {
+ vertical-align: top;
+}
+
+.workArea * dt {
+ font-size: 12pt;
+ margin-top: 10px;
+}
+
+.workArea * .example {
+ background-color: #ffffcc;
+ border: 1px dashed lightgray;
+ padding: 10px;
+}
+
+.workArea h1 {
+ font-size: 16pt;
+ font-weight: bold;
+}
+
+.workArea h2 {
+ font-size: 14pt;
+ font-weight: normal;
+ color: gray;
+}
+
+</style>
+<body>
+<table border="0">
+ <tr>
+ <td valign="top">
+ <img src="pics/json4lua.gif"><p/>
+ <!-- NAVIGATION BARS -->
+
+ <div class="navBar">
+ <h1>Home Page</h1>
+ <div class="navItem"><a href="index.html#news">Latest News</a></div>
+ <div class="navItem"><a href="index.html#introduction">Introduction</a></div>
+ <div class="navItem"><a href="index.html#licence">Licence</a></div>
+ <div class="navItem"><a href="index.html#requirements">Requirements</a></div>
+ <div class="navItem"><a href="index.html#download">Download</a></div>
+ <div class="navItem"><a href="index.html#installation">Installation</a></div>
+ <div class="navItem"><a href="index.html#usage">Usage &amp; Reference</a></div>
+ <div class="navItem"><a href="index.html#roadmap">History &amp; Roadmap</a></div>
+ </div> <!-- end of navigation bar: This Site -->
+
+ <div class="navBar">
+ <h1>json.luaforge</h1>
+ <div class="navItem"><a href="http://luaforge.net/projects/json/">Summary</a></div>
+ <div class="navItem"><a href="http://luaforge.net/forum/?group_id=143">Forums</a></div>
+ <div class="navItem"><a href="http://luaforge.net/tracker/?group_id=143">Tracker</a></div>
+ <div class="navItem"><a href="http://luaforge.net/news/?group_id=143">News</a></div>
+ <!--<div class="navItem"><a href="http://luaforge.net/scm/?group_id=143">CVS</a></div>-->
+ <div class="navItem"><a href="http://luaforge.net/frs/?group_id=143">Files</a></div>
+ </div> <!-- end of navigation bar: json.luaforge -->
+
+ <div class="navBar">
+ <h1>Lua</h1>
+ <div class="navItem"><a href="http://www.lua.org/">Lua</a></div>
+ <div class="navItem"><a href="http://www.luaforge.net/">Lua Forge</a></div>
+ <div class="navItem"><a href="http://www.keplerproject.org/cgilua/">CGI Lua</a></div>
+ <div class="navItem"><a href="http://www.keplerproject.org/compat/">Lua compat-5.1</a></div>
+ <div class="navItem"><a href="http://www.cs.princeton.edu/~diego/professional/luasocket/">Lua Socket 2.0</a></div>
+ <div class="navItem"><a href="http://www.keplerproject.org/xavante/">Xavante</a></div>
+ </div> <!-- end of navigation bar: Lua Resources -->
+
+ <div class="navBar">
+ <h1>JSON</h1>
+ <div class="navItem"><a href="http://www.json.org/">json.org</a></div>
+ <div class="navItem"><a href="http://www.json-rpc.org/">json-rpc.org</a></div>
+ </div> <!-- end of navigation bar: Lua Resources -->
+
+ </td>
+ <!-- MAIN WORK AREA -->
+ <td valign="top" class="workArea">
+ <div class="titleBar">Patching CGILua to handle <code>text/plain</code></div>
+
+ <!-- cgilua_patch.html -->
+JSON RPC (both the JSONRPC4Lua implementation and the <a href="http://www.jsolait.net/">jsolait Javascript</a> implementation) send the http request with a Content-Type of <code>text/plain</code>.<p/>
+
+CGILua 5.0 does not accept <code>text/plain</code> content, and will generate an error of 'Unsupported Media Type: text/plain'.<p/>
+
+This is easily patched in CGILua 5.0 by making the following change to <code>cgilua/post.lua</code>, line 286:<p/>
+Change:<pre>
+ elseif strfind (contenttype, "text/xml") then
+</pre>
+to
+<pre>
+ elseif strfind (contenttype, "text/xml") or strfind (contenttype, "text/plain") then
+</pre>
+This makes CGILua handle <code>text/plain</code> as it does <code>text/xml</code>, without parsing the incoming POST data.<p/>
+
+<b>Please note:</b> I have requested the maintainers of CGILua to make this change to CGILua, whereafter this patch will no longer be required.
+
+
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="copyright">&copy; 2005 Craig Mason-Jones</td>
+ </tr>
+</table>
+</body>
+</html> \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/json4lua/doc/index.html b/Data/DefaultContent/Libraries/json4lua/doc/index.html
new file mode 100644
index 0000000..12ec6c7
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/doc/index.html
@@ -0,0 +1,394 @@
+<html>
+<head>
+<title>JSON4Lua and JSONRPC4Lua</title>
+<style type="text/css">
+body {
+ font-family: Arial, Helvetica, Geneva;
+ font-size: 10pt;
+}
+
+.copyright {
+ color: #999999;
+ font-size: 8pt;
+ text-align:center;
+}
+
+.navBar {
+ border-left: 1px solid lightgray;
+ border-right: 1px solid lightgray;
+ border-bottom: 1px solid lightgray;
+ margin-top:5px;
+ margin-bottom: 5px;
+}
+.navBar h1 {
+ background-image: url('pics/lunartone.gif');
+ background-color: #e0c088;
+ color: white;
+ font-size: 9pt;
+ margin: 0px;
+ padding: 4px;
+}
+
+.navBar .navItem a {
+ color: #999999;
+ font-size: 8pt;
+ padding: 2px 2px 2px 10px;
+ text-decoration:none;
+}
+
+.navBar .navItem a:hover {
+ color: #ff9900;
+ text-decoration: underline;
+}
+
+.titleBar {
+ border-bottom: 2px dotted gray;
+ font-size: 20pt;
+ font-weight: bold;
+ margin-bottom: 15px;
+ width: 100%;
+}
+
+.workArea {
+ border: 1px none lightgray;
+ font-family: Times New Roman;
+ padding: 8px;
+ padding-left: 15px;
+}
+
+.workArea a {
+ font-weight: bold;
+ text-decoration: none;
+}
+
+.workArea a:hover {
+ color: #ff9900;
+ text-decoration: underline;
+}
+
+.workArea .downloadTable {
+ border: 1px solid lightgray;
+ padding: 0px;
+ margin: 0px;
+}
+
+.workArea .downloadTable * th {
+ background-color: #e0c088;
+ background-image: url('pics/lunartone.gif');
+ color: white;
+}
+
+.workArea .downloadTable * tr {
+ border: 1px solid lightgray;
+}
+
+.workArea .downloadTable * td {
+ vertical-align: top;
+}
+
+.workArea * dt {
+ font-size: 12pt;
+ margin-top: 10px;
+}
+
+.workArea * .example {
+ background-color: #ffffcc;
+ border: 1px dashed lightgray;
+ padding: 10px;
+}
+
+.workArea h1 {
+ font-size: 16pt;
+ font-weight: bold;
+}
+
+.workArea h2 {
+ font-size: 14pt;
+ font-weight: normal;
+ color: gray;
+}
+
+</style>
+<body>
+<table border="0">
+ <tr>
+ <td valign="top">
+ <img src="pics/json4lua.gif"><p/>
+ <!-- NAVIGATION BARS -->
+
+ <div class="navBar">
+ <h1>This Page</h1>
+ <div class="navItem"><a href="#news">Latest News</a></div>
+ <div class="navItem"><a href="#introduction">Introduction</a></div>
+ <div class="navItem"><a href="#licence">Licence</a></div>
+ <div class="navItem"><a href="#requirements">Requirements</a></div>
+ <div class="navItem"><a href="#download">Download</a></div>
+ <div class="navItem"><a href="#installation">Installation</a></div>
+ <div class="navItem"><a href="#usage">Usage &amp; Reference</a>
+ <div class="navItem" style="margin-left: 4px"><a href="#json_decode">decode</a></div>
+ <div class="navItem" style="margin-left: 4px"><a href="#json_encode">encode</a></div>
+ <div class="navItem" style="margin-left: 4px"><a href="#json_null">null</a></div>
+ <div class="navItem" style="margin-left: 4px"><a href="#json_rpc_call">rpc.call</a></div>
+ <div class="navItem" style="margin-left: 4px"><a href="#json_rpc_proxy">rpc.proxy</a></div>
+ <div class="navItem" style="margin-left: 4px"><a href="#json_rpcserver_serve">rpcserver.serve</a></div>
+
+ </div>
+ <div class="navItem"><a href="#roadmap">History &amp; Roadmap</a></div>
+ </div> <!-- end of navigation bar: This Site -->
+
+ <div class="navBar">
+ <h1>json.luaforge</h1>
+ <div class="navItem"><a href="http://luaforge.net/projects/json/">Summary</a></div>
+ <div class="navItem"><a href="http://luaforge.net/forum/?group_id=143">Forums</a></div>
+ <div class="navItem"><a href="http://luaforge.net/tracker/?group_id=143">Tracker</a></div>
+ <div class="navItem"><a href="http://luaforge.net/news/?group_id=143">News</a></div>
+ <!--<div class="navItem"><a href="http://luaforge.net/scm/?group_id=143">CVS</a></div>-->
+ <div class="navItem"><a href="http://luaforge.net/frs/?group_id=143">Files</a></div>
+ </div> <!-- end of navigation bar: json.luaforge -->
+
+ <div class="navBar">
+ <h1>Lua</h1>
+ <div class="navItem"><a href="http://www.lua.org/">Lua</a></div>
+ <div class="navItem"><a href="http://www.luaforge.net/">Lua Forge</a></div>
+ <div class="navItem"><a href="http://www.keplerproject.org/cgilua/">CGI Lua</a></div>
+ <div class="navItem"><a href="http://www.keplerproject.org/compat/">Lua compat-5.1</a></div>
+ <div class="navItem"><a href="http://www.cs.princeton.edu/~diego/professional/luasocket/">Lua Socket 2.0</a></div>
+ <div class="navItem"><a href="http://www.keplerproject.org/xavante/">Xavante</a></div>
+ </div> <!-- end of navigation bar: Lua Resources -->
+
+ <div class="navBar">
+ <h1>JSON</h1>
+ <div class="navItem"><a href="http://www.json.org/">json.org</a></div>
+ <div class="navItem"><a href="http://www.json-rpc.org/">json-rpc.org</a></div>
+ </div> <!-- end of navigation bar: Lua Resources -->
+
+ </td>
+ <!-- MAIN WORK AREA -->
+ <td valign="top" class="workArea">
+ <div class="titleBar">JSON4Lua and JSONRPC4Lua</div>
+ <!-- ***************** LATEST NEWS ***************** -->
+ <h1><a name="news"></a>Latest News</h1>
+ <p><small>(2009-08-06)</small> We've changed the JSON4Lua and JSONRPC4Lua licence from the GPL to the MIT licence, like Lua itself.</p>
+ <p>
+ The 0.9.20 release fixes a bug in Lua 5.1 operation, introduces a <a href="#json_null"><code>json.null</code></a> value to force null values in JSON encodings, improves performance (over 50% faster on some tests), and permits <code>/* comments */</code> in the JSON string being decoded.
+ </p>
+
+ <!-- ***************** INTRODUCTION ***************** -->
+ <h1><a name="introduction"></a>Introduction</h1>
+ JSON4Lua and JSONRPC4Lua implement <a href="http://www.json.org">JSON (JavaScript Object Notation)</a> encoding and decoding and a <a href="http://www.json-rpc.org/">JSON-RPC-over-http</a> client for <a href="http://www.lua.org/">Lua</a>.<p/>
+
+JSON is JavaScript Object Notation, a simple encoding of Javascript-like objects that is ideal for lightweight transmission of relatively weakly-typed data.
+A sub-package of JSON4Lua is JSONRPC4Lua, which provides a simple JSON-RPC-over-http client and server (in a CGILua environment) for Lua. Please seen the documentation below for JSONRPC4Lua.
+
+ <!-- ***************** LICENCE ***************** -->
+ <h1><a name="licence"></a>Licence</h1>
+ JSON4Lua is licensed under the MIT Consortium licence like Lua itself. Please see <a href="LICENCE.txt">LICENCE.txt</a> for details.<p/>
+
+ <!-- ***************** REQUIREMENTS ***************** -->
+ <a name="requirements"></a><h1>Requirements</h1>
+ JSON4Lua is a pure-Lua module that is Lua 5.0 compatible (if you have <a href="http://www.keplerproject.org/compat/">compat-5.1</a> for Lua 5.0). JSON4Lua also works (perfectly, I hope) under Lua 5.1, which is where I largely use it nowadays. Since Lua is platform independent, so is JSON4Lua.<p/>
+
+ The JSON4RPC sub-module requires <a href="http://www.cs.princeton.edu/~diego/professional/luasocket/">Lua Socket 2.0</a>. It uses <code>socket.http</code> for for the RPC over http connection. Socket 2.0 includes <code>ltn12</code>, which is also used by JSON4RPC.<p />
+
+ To use <code>json.rpcserver</code> you need a <a href="http://www.keplerproject.org/cgilua/">CGILua</a> enabled webserver. However, a quick <a href="cgilua_patch.html">patch</a> is required in CGILua 5.0 to support JSON-RPC.
+
+ <!-- ***************** START OF DOWNLOAD SECTION ***************** -->
+ <h1><a name="download"></a>Download</h1>
+ JSON4Lua is hosted on <a href="http://www.luaforge.net">LuaForge</a>.
+ <table cols="2" class="downloadTable">
+ <tr><th>Version</th><th>Date</th><th>Notes</th></tr>
+ <tr><td><a href="http://luaforge.net/frs/?group_id=143">0.9.30</a></td><td>6 August 2009</td><td>
+ Changed to MIT Licence.
+ </td></tr>
+ <tr><td><a href="http://luaforge.net/frs/?group_id=143">0.9.20</a></td><td>4 January 2006</td><td>
+ Introduction of local Lua functions for private functions (removed _ function prefix). <br />
+ Fixed Lua 5.1 compatibility issues.<br />
+ Introduced <code>json.null</code> to have null values in associative arrays.<br />
+ Performance improvement (more than 50% on some tests) through <code>table.concat</code> rather than <code>..</code> operator.<br/>
+ <code>json.decode</code> now ignores <code>/* */</code> comments in the JSON string.<br />
+ </td></tr>
+ <tr><td><a href="http://luaforge.net/frs/?group_id=143">0.9.10</a></td><td>20 December 2005</td><td>
+ Fixes bug with array representation when nil / null values occur in the array.<br />
+ Adds content-type header of <code>text/plain</code> to JSON RPC http requests.<br />
+ Introduces <code>json.rpcserver</code> module with simple JSON RPC enablement for Lua objects.<br />
+ Moved the <code>json.lua</code> file into the <code>json</code> directory. Ensure, therefore, that your <code>LUA_PATH</code> contains a module-finding form like <code>LUA_PATH = c:\proj\lua\?\?.lua;?.lua</code>.<br/>
+ </td></tr>
+ <tr>
+ <td><a href="http://luaforge.net/frs/?group_id=143">0.9.01</a></td>
+ <td>19 December 2005</td>
+ <td>Minor corrections to documentation.</td>
+ </tr>
+ <tr>
+ <td><a href="http://luaforge.net/frs/?group_id=143">0.9.00</a></td>
+ <td>19 December 2005</td>
+ <td>First release</td>
+ </tr>
+ </table>
+ <!-- END OF DOWNLOAD SECTION -->
+
+ <!-- ***************** START OF INSTALLATION SECTION ***************** -->
+ <h1><a name="installation"></a>Installation</h1>
+ As of version 0.9.10, all the JSON4Lua files are contained in the <code>json</code> subdirectory in the distribution zip.<p />
+ Simply copy the <code>json</code> subdirectory so that it is in your Lua path.<p />
+ Ensure that your <code>LUA_PATH</code> variable permits module resolution of the form <code>?/?.lua</code>.<p />
+ <b>Example</b>
+ <div class="example">
+ </div>
+ <h2>Using Windows</h2>
+ Under Windows, set your Lua path as (my Lua installation is in <code>c:\proj\lua\</code>): <p/>
+ <code>
+ set LUA_PATH=c:\proj\lua\?.lua;c:\proj\lua\?\?.lua;?.lua
+ </code><p/>
+ For compat-5.1.lua to start when Lua starts (if you're using Lua 5.0), you also need:<p/>
+ <code>
+ set LUA_INIT=@c:\proj\lua\compat-5.1.lua
+ </code><p />
+ You probably also want to set your library path:<p/>
+ <code>set LUA_CPATH=c:\proj\lua\lib\?.dll;?.dll</code>
+
+ <!------------------------ USAGE AND REFERENCE -------------------->
+ <h1><a name="usage"></a>Usage &amp; Reference</h1>
+ The following functions in <b>JSON4Lua</b> and <b>JSONRPC4Lua</b> are of interest:<p />
+ <dl>
+ <dt><a name="json_encode"></a><code>string <b>json.encode</b>( lua_object )</code></dt>
+ <dd>Returns the Lua object JSON encoded into a string.<p/>
+ <b>Example</b>
+ <div class="example">
+ <code>
+ json = require("json")<br/>
+ print (json.encode( { 1, 2, 'fred', {first='mars',second='venus',third='earth'} } ))
+ </code><p/>
+ prints<p/><code> [1,2,"fred", {"first":"mars","second":"venus","third","earth"}]</code>
+ </div>
+
+ </dd>
+ <dt><a name="json_decode"></a><code>lua_object <b>json.decode</b>( json_string )</code></dt>
+ <dd>Decodes the JSON encoded data structure, and returns a Lua object with the appropriate data.<p/>
+ <b>Example</b>
+
+ <div class="example">
+ <code>
+ json = require("json")<br/>
+
+ testString = [[ { "one":1 , "two":2, "primes":[2,3,5,7] } ]]<br/>
+ o = json.decode(testString)<br/>
+ table.foreach(o,print)<br />
+ print ("Primes are:")<br />
+ table.foreach(o.primes,print)
+ </code><p/>
+ prints:<p/>
+ <pre>
+one 1
+two 2
+primes table: 0032B928
+Primes are:
+1 2
+2 3
+3 5
+4 7</pre>
+ </div></dd>
+
+ <dt><a name="json_null"></a><code><b>json.null</b></code></dt>
+ <dd>Returns a unique value that will be encoded as a <code>null</code> in a JSON encoding.
+ <p>This is necessary in one situation. In Lua, if a key in a table has a <code>nil</code> value, the key is simply discarded (since any non-existent key has a nil value). The encoding of arrays has been built to manage this nil-values in arrays, but associative arrays provide a problem. Consider:
+ <div class="example"><pre>t = { user="test", password=nil }</pre></div>
+ Since Lua simply discards the <code>password</code> key, JSON4Lua encodes this as the JSON string
+ <div class="example"><pre>{"user":"test"}</pre></div>
+ If, for some reason, your JSON RPC Server requires a defined <code>null</code> value, use the following code:
+ <div class="example"><pre>t = { user="test", password=json.null }</pre></div>
+ This will now correctly encode to:
+ <div class="example"><pre>{"user":"test","password":null}</pre></div>
+ Incidentally, <code>json.null</code> is simply a function that returns itself, so that you can use either <code>json.null</code> or <code>json.null()</code> as you fancy.
+ </dd>
+
+
+ <dt><a name="json_rpc_call"></a><code>result, error <b>json.rpc.call</b> ( url, method, ...)</code></dt>
+ <dd>Calls the named method on the given url with the arg parameters. Returns the result and the error. If <code>error</code> is <code>nil</code>, no error occurred.<p/>
+ <b>Example</b>
+ <div class="example">
+ <pre>require ("json.rpc")
+result, error = json.rpc.call("http://jsolait.net/testj.py","echo","Test echo!")
+print(result)</pre>
+ <p />prints<p />
+ <pre>Test echo!</pre>
+ </div>
+ </dd>
+ <dt><a name="json_rpc_proxy"></a><code>proxyServer = <b>json.rpc.proxy</b> (url)</code></dt>
+ <dd>Creates a proxy server object on which JSON-RPC calls can be made. Each call will return the <code>result, error</code>. If <code>error</code> is <code>nil</code>, no error occurred.<p/>
+ <b>Example</b>
+ <div class="example">
+ <pre>
+require ("json.rpc")
+server = json.rpc.proxy("http://jsolait.net/testj.py")
+result, error = server.echo('Test echo!')
+print(result)</pre>
+ <p />prints<p />
+ <pre>Test echo!</pre>
+ </div>
+ </dd>
+
+ <dt><a name="json_rpcserver_serve"></a><code><b>json.rpcserver.serve</b>(object[, packReturn])</code></dt>
+ <dd>
+ Handles an incoming CGILua request as a JSON RPC request and serves the request from
+ the given object.
+ <p />The optional <code>packReturn</code> parameter, if set <code>true</code>, will, if the requested
+ method returns more than one value, pack these returned values into an array. If only a single value
+ is returned, it is not packed into an array. If <code>packReturn</code> is <code>false</code> (or not set), only the first
+ return value from the requested method will be returned. This is necessitated since the JSON protocol does not permit a method call to return more than a single value.
+ <p/>
+
+ <code>serve</code> returns nothing.<p/>
+
+ <b>Example</b>
+ <div class="example">
+ <pre>
+--
+-- jsonrpc.lua
+-- Installed in a CGILua webserver environment (with necessary CGI Lua 5.0 patch)
+--
+require ('json.rpcserver')
+
+-- The Lua class that is to serve JSON RPC requests
+local myServer = {
+ echo = function (msg) return msg end,
+ average = function(...)
+ local total=0
+ local count=0
+ for i=1, table.getn(arg) do
+ total = total + arg[i]
+ count = count + 1
+ end
+ return { average= total/count, sum = total, n=count }
+ end
+}
+
+json.rpcserver.serve(myServer)
+</pre>
+An example of using this JSON RPC server from a Lua file:
+<pre>
+require ('json.rpc')
+local server = json.rpc.proxy('http://www.myserver.com/jsonrpc.lua')
+table.foreach(server.average(10,15,23), print)
+</pre>
+Prints:
+<pre>
+average 16
+sum 48
+n 3
+</pre>
+ </div>
+
+ </dd>
+ </dl>
+
+ <!-- ***************** HISTORY AND ROADMAP ***************** -->
+ <h1><a name="roadmap"></a>History &amp; Roadmap</h1>
+ The downloads sections details the versions and their related histories. I will wait for Lua 5.1 to be final (expected late January) before making the JSON4Lua module beta. If no serious bugs or objections are encountered, I will make the module 1.0 on 1 April 2006 (to coincide with April Fool's day!)
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="copyright">&copy; 2005, 2006 Craig Mason-Jones</td>
+ </tr>
+</table>
+</body>
+</html> \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/json4lua/doc/pics/json4lua.gif b/Data/DefaultContent/Libraries/json4lua/doc/pics/json4lua.gif
new file mode 100644
index 0000000..938bcb9
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/doc/pics/json4lua.gif
Binary files differ
diff --git a/Data/DefaultContent/Libraries/json4lua/doc/pics/lunartone.gif b/Data/DefaultContent/Libraries/json4lua/doc/pics/lunartone.gif
new file mode 100644
index 0000000..e914a8f
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/doc/pics/lunartone.gif
Binary files differ
diff --git a/Data/DefaultContent/Libraries/json4lua/examples/example.lua b/Data/DefaultContent/Libraries/json4lua/examples/example.lua
new file mode 100644
index 0000000..36497da
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/examples/example.lua
@@ -0,0 +1,23 @@
+--[[
+JSON4Lua example script.
+Demonstrates the simple functionality of the json module.
+]]--
+json = require('json')
+
+
+-- Object to JSON encode
+test = {
+ one='first',two='second',three={2,3,5}
+}
+
+jsonTest = json.encode(test)
+
+print('JSON encoded test is: ' .. jsonTest)
+
+-- Now JSON decode the json string
+result = json.decode(jsonTest)
+
+print ("The decoded table result:")
+table.foreach(result,print)
+print ("The decoded table result.three")
+table.foreach(result.three, print)
diff --git a/Data/DefaultContent/Libraries/json4lua/examples/jsonrpc.lua b/Data/DefaultContent/Libraries/json4lua/examples/jsonrpc.lua
new file mode 100644
index 0000000..f265b8a
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/examples/jsonrpc.lua
@@ -0,0 +1,21 @@
+--
+-- jsonrpc.lua
+-- Installed in a CGILua webserver environment (with necessary CGI Lua 5.0 patch)
+--
+require ('json.rpcserver')
+
+-- The Lua class that is to serve JSON RPC requests
+local myServer = {
+ echo = function (msg) return msg end,
+ average = function(...)
+ local total=0
+ local count=0
+ for i=1, table.getn(arg) do
+ total = total + arg[i]
+ count = count + 1
+ end
+ return { average= total/count, sum = total, n=count }
+ end
+}
+
+json.rpcserver.serve(myServer) \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/json4lua/examples/tests.lua b/Data/DefaultContent/Libraries/json4lua/examples/tests.lua
new file mode 100644
index 0000000..2e58b6e
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/examples/tests.lua
@@ -0,0 +1,223 @@
+--[[
+Some basic tests for JSON4Lua.
+]]--
+
+--- Compares two tables for being data-identical.
+function compareData(a,b)
+ if (type(a)=='string' or type(a)=='number' or type(a)=='boolean' or type(a)=='nil') then return a==b end
+ -- After basic data types, we're only interested in tables
+ if (type(a)~='table') then return true end
+ -- Check that a has everything b has
+ for k,v in pairs(b) do
+ if (not compareData( a[k], v ) ) then return false end
+ end
+ for k,v in pairs(a) do
+ if (not compareData( v, b[k] ) ) then return false end
+ end
+ return true
+end
+
+---
+-- Checks that our compareData function works properly
+function testCompareData()
+ s = "name"
+ r = "name"
+ assert(compareData(s,r))
+ assert(not compareData('fred',s))
+ assert(not compareData(nil, s))
+ assert(not compareData("123",123))
+ assert(not compareData(false, nil))
+ assert(compareData(true, true))
+ assert(compareData({1,2,3},{1,2,3}))
+ assert(compareData({'one',2,'three'},{'one',2,'three'}))
+ assert(not compareData({'one',2,4},{4,2,'one'}))
+ assert(compareData({one='ichi',two='nichi',three='san'}, {three='san',two='nichi',one='ichi'}))
+ s = { one={1,2,3}, two={one='hitotsu',two='futatsu',three='mitsu'} }
+ assert(compareData(s,s))
+ t = { one={1,2,3}, two={one='een',two='twee',three='drie'} }
+ assert(not compareData(s,t))
+end
+
+testCompareData()
+
+--
+--
+-- Performs some perfunctory tests on JSON module
+function testJSON4Lua()
+ json = require('json')
+
+ if nil then
+ -- Test encodeString
+ s = [["\"
+]]
+ r = json._encodeString(s)
+ assert(r=='\\"\\\\\\"\\n')
+ s = [["""\\\"]]
+ r = json._encodeString(s)
+ assert(r==[[\"\"\"\\\\\\\"]])
+
+ end
+
+ -- Test encode for basic strings (complicated strings)
+ s = [[Hello, Lua!]]
+ r = json.encode(s)
+ assert(r=='"Hello, Lua!"')
+ s = [["\"
+]]
+ r = json.encode(s)
+ assert(r=='\"\\"\\\\\\"\\n\"')
+ s = [["""\\\"]]
+ r = json.encode(s)
+ assert(r==[["\"\"\"\\\\\\\""]])
+
+ -- Test encode for numeric values
+ s = 23
+ r = json.encode(s)
+ assert(r=='23')
+ s=48.123
+ r = json.encode(s)
+ assert(r=='48.123')
+
+ -- Test encode for boolean values
+ assert(json.encode(true)=='true')
+ assert(json.encode(false)=='false')
+ assert(json.encode(nil)=='null')
+
+ -- Test encode for arrays
+ s = {1,2,3}
+ r = json.encode(s)
+ assert(r=="[1,2,3]")
+ s = {9,9,9}
+ r = json.encode(s)
+ assert(r=="[9,9,9]")
+
+ -- Complex array test
+ s = { 2, 'joe', false, nil, 'hi' }
+ r = json.encode(s)
+ assert(r=='[2,"joe",false,null,"hi"]')
+
+ -- Test encode for tables
+ s = {Name='Craig',email='craig@lateral.co.za',age=35}
+ r = json.encode(s)
+ -- NB: This test can fail because of order: need to test further once
+ -- decoding is supported.
+ -- assert(r==[[{"age":35,"Name":"Craig","email":"craig@lateral.co.za"}]])
+
+ -- Test encoding tables with numeric (string) indexes
+ s = {}
+ s['1']='One'
+ r = json.encode(s)
+ -- print("r = ", r)
+ assert(r=='{"1":"One"}')
+
+ s['2']= {One='Uno'}
+ r = json.encode(s)
+ assert(compareData(json.decode(r), s))
+
+ -- Test decode_scanWhitespace
+ if nil then
+ s = " \n \r \t "
+ e = json._decode_scanWhitespace(s,1)
+ assert(e==string.len(s)+1)
+ s = " \n\r\t4"
+ assert(json._decode_scanWhitespace(s,1)==5)
+
+ -- Test decode_scanString
+ s = [["Test"]]
+ r,e = json._decode_scanString(s,1)
+ assert(r=='Test' and e==7)
+ s = [["This\nis a \"test"]]
+ r = json._decode_scanString(s,1)
+ assert(r=="This\nis a \"test")
+
+ s = [["Test\u00A7\\"]]
+ r,e = json._decode_scanString(s,1)
+ assert(r=="Test\xC2\xA7\\" and e==9)
+
+ -- Test decode_scanNumber
+ s = [[354]]
+ r,e = json._decode_scanNumber(s,1)
+ assert(r==354 and e==4)
+ s = [[ 4565.23 AND OTHER THINGS ]]
+ r,e = json._decode_scanNumber(s,2)
+ assert(r==4565.23 and e==9)
+ s = [[ -23.22 and ]]
+ r,e = json._decode_scanNumber(s,2)
+ assert(r==-23.22 and e==8)
+
+ -- Test decode_scanConstant
+ s = "true"
+ r,e = json._decode_scanConstant(s,1)
+ assert(r==true and e==5)
+ s = " false "
+ r,e = json._decode_scanConstant(s,3)
+ assert(r==false and e==8)
+ s = "1null6"
+ r,e = json._decode_scanConstant(s,2)
+ assert(r==nil and e==6)
+
+ -- Test decode_scanArray
+ s = "[1,2,3]"
+ r,e = json._decode_scanArray(s,1)
+ assert(compareData(r,{1,2,3}))
+ s = [[[ 1 , 3 ,5 , "Fred" , true, false, null, -23 ] ]]
+ r,e = json._decode_scanArray(s,1)
+ assert(compareData(r, {1,3,5,'Fred',true,false,nil,-23} ) )
+ s = "[3,5,null,7,9]"
+ r,e = json._decode_scanArray(s,1)
+ assert(compareData(r, {3,5,nil,7,9}))
+ s = "[3,5,null,7,9,null,null]"
+ r,e = json._decode_scanArray(s,1)
+ assert(compareData(r, {3,5,nil,7,9,nil,nil}))
+
+ end
+
+ s = [["Test\u00A7\\\""]]
+ r,e = json.decode(s)
+ assert(r=="Test\xC2\xA7\\\"", r)
+
+ -- Test decode_scanObject
+ s = [[ {"one":1, "two":2, "three":"three", "four":true} ]]
+ r,e = json.decode(s)
+ -- for x,y in pairs(r) do
+ -- print(x,y)
+ -- end
+ assert(compareData(r,{one=1,two=2,three='three',four=true}))
+ s = [[ { "one" : { "first":1,"second":2,"third":3}, "two":2, "three":false } ]]
+ r,e = json.decode(s)
+ assert(compareData(r, {one={first=1,second=2,third=3},two=2,three=false}))
+ s = [[ { "primes" : [2,3,5,7,9], "user":{"name":"craig","age":35,"programs_lua":true},
+ "lua_is_great":true } ]]
+ r,e = json.decode(s)
+ assert(compareData(r, {primes={2,3,5,7,9},user={name='craig',age=35,programs_lua=true},lua_is_great=true}))
+
+ -- Test json.null management
+ t = { 1,2,json.null,4 }
+ assert( json.encode(t)=="[1,2,null,4]" )
+ t = {x=json.null }
+ r = json.encode(t)
+ assert( json.encode(t) == '{"x":null}' )
+
+ -- Test comment decoding
+ s = [[ /* A comment
+ that spans
+ a few lines
+ */
+ "test"
+ ]]
+ r,e = json.decode(s)
+ assert(r=='test',"Comment decoding failed")
+
+ -- Per error reported by M.Hund, with incorrect decoding of string-numbered tables
+ s = {}
+ subt = {a="a",b="b",c="c"}
+ s['1'] = subt
+ s['2'] = subt
+ s['3'] = subt
+ r = json.decode('{"1":{"a":"a","b":"b","c":"c"},"2":{"a":"a","b":"b","c":"c"},"3":{"a":"a","b":"b","c":"c"}}')
+ assert(compareData(s, r))
+end
+
+testJSON4Lua()
+
+print("JSON4Lua tests completed successfully")
diff --git a/Data/DefaultContent/Libraries/json4lua/examples/timetrials.lua b/Data/DefaultContent/Libraries/json4lua/examples/timetrials.lua
new file mode 100644
index 0000000..cbda514
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/examples/timetrials.lua
@@ -0,0 +1,46 @@
+--[[
+ Some Time Trails for the JSON4Lua package
+]]--
+
+
+require('json')
+require('os')
+require('table')
+
+local t1 = os.clock()
+local jstr
+local v
+for i=1,100 do
+ local t = {}
+ for j=1,500 do
+ table.insert(t,j)
+ end
+ for j=1,500 do
+ table.insert(t,"VALUE")
+ end
+ jstr = json.encode(t)
+ v = json.decode(jstr)
+ --print(json.encode(t))
+end
+
+for i = 1,100 do
+ local t = {}
+ for j=1,500 do
+ local m= math.mod(j,3)
+ if (m==0) then
+ t['a'..j] = true
+ elseif m==1 then
+ t['a'..j] = json.null
+ else
+ t['a'..j] = j
+ end
+ end
+ jstr = json.encode(t)
+ v = json.decode(jstr)
+end
+
+print (jstr)
+--print(type(t1))
+local t2 = os.clock()
+
+print ("Elapsed time=" .. os.difftime(t2,t1) .. "s") \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/json4lua/json/json.lua b/Data/DefaultContent/Libraries/json4lua/json/json.lua
new file mode 100644
index 0000000..79761b6
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/json/json.lua
@@ -0,0 +1,427 @@
+-----------------------------------------------------------------------------
+-- JSON4Lua: JSON encoding / decoding support for the Lua language.
+-- json Module.
+-- Author: Craig Mason-Jones
+-- Homepage: http://github.com/craigmj/json4lua/
+-- Version: 1.0.0
+-- This module is released under the MIT License (MIT).
+-- Please see LICENCE.txt for details.
+--
+-- USAGE:
+-- This module exposes two functions:
+-- json.encode(o)
+-- Returns the table / string / boolean / number / nil / json.null value as a JSON-encoded string.
+-- json.decode(json_string)
+-- Returns a Lua object populated with the data encoded in the JSON string json_string.
+--
+-- REQUIREMENTS:
+-- compat-5.1 if using Lua 5.0
+--
+-- CHANGELOG
+-- 0.9.20 Introduction of local Lua functions for private functions (removed _ function prefix).
+-- Fixed Lua 5.1 compatibility issues.
+-- Introduced json.null to have null values in associative arrays.
+-- json.encode() performance improvement (more than 50%) through table.concat rather than ..
+-- Introduced decode ability to ignore /**/ comments in the JSON string.
+-- 0.9.10 Fix to array encoding / decoding to correctly manage nil/null values in arrays.
+-----------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+-- Imports and dependencies
+-----------------------------------------------------------------------------
+local math = require('math')
+local string = require("string")
+local table = require("table")
+
+-----------------------------------------------------------------------------
+-- Module declaration
+-----------------------------------------------------------------------------
+local json = {} -- Public namespace
+local json_private = {} -- Private namespace
+
+-- Public constants
+json.EMPTY_ARRAY={}
+json.EMPTY_OBJECT={}
+
+-- Public functions
+
+-- Private functions
+local decode_scanArray
+local decode_scanComment
+local decode_scanConstant
+local decode_scanNumber
+local decode_scanObject
+local decode_scanString
+local decode_scanWhitespace
+local encodeString
+local isArray
+local isEncodable
+
+-----------------------------------------------------------------------------
+-- PUBLIC FUNCTIONS
+-----------------------------------------------------------------------------
+--- Encodes an arbitrary Lua object / variable.
+-- @param v The Lua object / variable to be JSON encoded.
+-- @return String containing the JSON encoding in internal Lua string format (i.e. not unicode)
+function json.encode (v)
+ -- Handle nil values
+ if v==nil then
+ return "null"
+ end
+
+ local vtype = type(v)
+
+ -- Handle strings
+ if vtype=='string' then
+ return '"' .. json_private.encodeString(v) .. '"' -- Need to handle encoding in string
+ end
+
+ -- Handle booleans
+ if vtype=='number' or vtype=='boolean' then
+ return tostring(v)
+ end
+
+ -- Handle tables
+ if vtype=='table' then
+ local rval = {}
+ -- Consider arrays separately
+ local bArray, maxCount = isArray(v)
+ if bArray then
+ for i = 1,maxCount do
+ table.insert(rval, json.encode(v[i]))
+ end
+ else -- An object, not an array
+ for i,j in pairs(v) do
+ if isEncodable(i) and isEncodable(j) then
+ table.insert(rval, '"' .. json_private.encodeString(i) .. '":' .. json.encode(j))
+ end
+ end
+ end
+ if bArray then
+ return '[' .. table.concat(rval,',') ..']'
+ else
+ return '{' .. table.concat(rval,',') .. '}'
+ end
+ end
+
+ -- Handle null values
+ if vtype=='function' and v==json.null then
+ return 'null'
+ end
+
+ assert(false,'encode attempt to encode unsupported type ' .. vtype .. ':' .. tostring(v))
+end
+
+
+--- Decodes a JSON string and returns the decoded value as a Lua data structure / value.
+-- @param s The string to scan.
+-- @param [startPos] Optional starting position where the JSON string is located. Defaults to 1.
+-- @param Lua object, number The object that was scanned, as a Lua table / string / number / boolean or nil,
+-- and the position of the first character after
+-- the scanned JSON object.
+function json.decode(s, startPos)
+ startPos = startPos and startPos or 1
+ startPos = decode_scanWhitespace(s,startPos)
+ assert(startPos<=string.len(s), 'Unterminated JSON encoded object found at position in [' .. s .. ']')
+ local curChar = string.sub(s,startPos,startPos)
+ -- Object
+ if curChar=='{' then
+ return decode_scanObject(s,startPos)
+ end
+ -- Array
+ if curChar=='[' then
+ return decode_scanArray(s,startPos)
+ end
+ -- Number
+ if string.find("+-0123456789.e", curChar, 1, true) then
+ return decode_scanNumber(s,startPos)
+ end
+ -- String
+ if curChar==[["]] or curChar==[[']] then
+ return decode_scanString(s,startPos)
+ end
+ if string.sub(s,startPos,startPos+1)=='/*' then
+ return json.decode(s, decode_scanComment(s,startPos))
+ end
+ -- Otherwise, it must be a constant
+ return decode_scanConstant(s,startPos)
+end
+
+--- The null function allows one to specify a null value in an associative array (which is otherwise
+-- discarded if you set the value with 'nil' in Lua. Simply set t = { first=json.null }
+function json.null()
+ return json.null -- so json.null() will also return null ;-)
+end
+-----------------------------------------------------------------------------
+-- Internal, PRIVATE functions.
+-- Following a Python-like convention, I have prefixed all these 'PRIVATE'
+-- functions with an underscore.
+-----------------------------------------------------------------------------
+
+--- Scans an array from JSON into a Lua object
+-- startPos begins at the start of the array.
+-- Returns the array and the next starting position
+-- @param s The string being scanned.
+-- @param startPos The starting position for the scan.
+-- @return table, int The scanned array as a table, and the position of the next character to scan.
+function decode_scanArray(s,startPos)
+ local array = {} -- The return value
+ local stringLen = string.len(s)
+ assert(string.sub(s,startPos,startPos)=='[','decode_scanArray called but array does not start at position ' .. startPos .. ' in string:\n'..s )
+ startPos = startPos + 1
+ -- Infinite loop for array elements
+ local index = 1
+ repeat
+ startPos = decode_scanWhitespace(s,startPos)
+ assert(startPos<=stringLen,'JSON String ended unexpectedly scanning array.')
+ local curChar = string.sub(s,startPos,startPos)
+ if (curChar==']') then
+ return array, startPos+1
+ end
+ if (curChar==',') then
+ startPos = decode_scanWhitespace(s,startPos+1)
+ end
+ assert(startPos<=stringLen, 'JSON String ended unexpectedly scanning array.')
+ object, startPos = json.decode(s,startPos)
+ array[index] = object
+ index = index + 1
+ until false
+end
+
+--- Scans a comment and discards the comment.
+-- Returns the position of the next character following the comment.
+-- @param string s The JSON string to scan.
+-- @param int startPos The starting position of the comment
+function decode_scanComment(s, startPos)
+ assert( string.sub(s,startPos,startPos+1)=='/*', "decode_scanComment called but comment does not start at position " .. startPos)
+ local endPos = string.find(s,'*/',startPos+2)
+ assert(endPos~=nil, "Unterminated comment in string at " .. startPos)
+ return endPos+2
+end
+
+--- Scans for given constants: true, false or null
+-- Returns the appropriate Lua type, and the position of the next character to read.
+-- @param s The string being scanned.
+-- @param startPos The position in the string at which to start scanning.
+-- @return object, int The object (true, false or nil) and the position at which the next character should be
+-- scanned.
+function decode_scanConstant(s, startPos)
+ local consts = { ["true"] = true, ["false"] = false, ["null"] = nil }
+ local constNames = {"true","false","null"}
+
+ for i,k in pairs(constNames) do
+ if string.sub(s,startPos, startPos + string.len(k) -1 )==k then
+ return consts[k], startPos + string.len(k)
+ end
+ end
+ assert(nil, 'Failed to scan constant from string ' .. s .. ' at starting position ' .. startPos)
+end
+
+--- Scans a number from the JSON encoded string.
+-- (in fact, also is able to scan numeric +- eqns, which is not
+-- in the JSON spec.)
+-- Returns the number, and the position of the next character
+-- after the number.
+-- @param s The string being scanned.
+-- @param startPos The position at which to start scanning.
+-- @return number, int The extracted number and the position of the next character to scan.
+function decode_scanNumber(s,startPos)
+ local endPos = startPos+1
+ local stringLen = string.len(s)
+ local acceptableChars = "+-0123456789.e"
+ while (string.find(acceptableChars, string.sub(s,endPos,endPos), 1, true)
+ and endPos<=stringLen
+ ) do
+ endPos = endPos + 1
+ end
+ local stringValue = 'return ' .. string.sub(s,startPos, endPos-1)
+ local stringEval = load(stringValue)
+ assert(stringEval, 'Failed to scan number [ ' .. stringValue .. '] in JSON string at position ' .. startPos .. ' : ' .. endPos)
+ return stringEval(), endPos
+end
+
+--- Scans a JSON object into a Lua object.
+-- startPos begins at the start of the object.
+-- Returns the object and the next starting position.
+-- @param s The string being scanned.
+-- @param startPos The starting position of the scan.
+-- @return table, int The scanned object as a table and the position of the next character to scan.
+function decode_scanObject(s,startPos)
+ local object = {}
+ local stringLen = string.len(s)
+ local key, value
+ assert(string.sub(s,startPos,startPos)=='{','decode_scanObject called but object does not start at position ' .. startPos .. ' in string:\n' .. s)
+ startPos = startPos + 1
+ repeat
+ startPos = decode_scanWhitespace(s,startPos)
+ assert(startPos<=stringLen, 'JSON string ended unexpectedly while scanning object.')
+ local curChar = string.sub(s,startPos,startPos)
+ if (curChar=='}') then
+ return object,startPos+1
+ end
+ if (curChar==',') then
+ startPos = decode_scanWhitespace(s,startPos+1)
+ end
+ assert(startPos<=stringLen, 'JSON string ended unexpectedly scanning object.')
+ -- Scan the key
+ key, startPos = json.decode(s,startPos)
+ assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
+ startPos = decode_scanWhitespace(s,startPos)
+ assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
+ assert(string.sub(s,startPos,startPos)==':','JSON object key-value assignment mal-formed at ' .. startPos)
+ startPos = decode_scanWhitespace(s,startPos+1)
+ assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
+ value, startPos = json.decode(s,startPos)
+ object[key]=value
+ until false -- infinite loop while key-value pairs are found
+end
+
+-- START SoniEx2
+-- Initialize some things used by decode_scanString
+-- You know, for efficiency
+local escapeSequences = {
+ ["\\t"] = "\t",
+ ["\\f"] = "\f",
+ ["\\r"] = "\r",
+ ["\\n"] = "\n",
+ ["\\b"] = "\b"
+}
+setmetatable(escapeSequences, {__index = function(t,k)
+ -- skip "\" aka strip escape
+ return string.sub(k,2)
+end})
+-- END SoniEx2
+
+--- Scans a JSON string from the opening inverted comma or single quote to the
+-- end of the string.
+-- Returns the string extracted as a Lua string,
+-- and the position of the next non-string character
+-- (after the closing inverted comma or single quote).
+-- @param s The string being scanned.
+-- @param startPos The starting position of the scan.
+-- @return string, int The extracted string as a Lua string, and the next character to parse.
+function decode_scanString(s,startPos)
+ assert(startPos, 'decode_scanString(..) called without start position')
+ local startChar = string.sub(s,startPos,startPos)
+ -- START SoniEx2
+ -- PS: I don't think single quotes are valid JSON
+ assert(startChar == [["]] or startChar == [[']],'decode_scanString called for a non-string')
+ --assert(startPos, "String decoding failed: missing closing " .. startChar .. " for string at position " .. oldStart)
+ local t = {}
+ local i,j = startPos,startPos
+ while string.find(s, startChar, j+1) ~= j+1 do
+ local oldj = j
+ i,j = string.find(s, "\\.", j+1)
+ local x,y = string.find(s, startChar, oldj+1)
+ if not i or x < i then
+ i,j = x,y-1
+ end
+ table.insert(t, string.sub(s, oldj+1, i-1))
+ if string.sub(s, i, j) == "\\u" then
+ local a = string.sub(s,j+1,j+4)
+ j = j + 4
+ local n = tonumber(a, 16)
+ assert(n, "String decoding failed: bad Unicode escape " .. a .. " at position " .. i .. " : " .. j)
+ -- math.floor(x/2^y) == lazy right shift
+ -- a % 2^b == bitwise_and(a, (2^b)-1)
+ -- 64 = 2^6
+ -- 4096 = 2^12 (or 2^6 * 2^6)
+ local x
+ if n < 0x80 then
+ x = string.char(n % 0x80)
+ elseif n < 0x800 then
+ -- [110x xxxx] [10xx xxxx]
+ x = string.char(0xC0 + (math.floor(n/64) % 0x20), 0x80 + (n % 0x40))
+ else
+ -- [1110 xxxx] [10xx xxxx] [10xx xxxx]
+ x = string.char(0xE0 + (math.floor(n/4096) % 0x10), 0x80 + (math.floor(n/64) % 0x40), 0x80 + (n % 0x40))
+ end
+ table.insert(t, x)
+ else
+ table.insert(t, escapeSequences[string.sub(s, i, j)])
+ end
+ end
+ table.insert(t,string.sub(j, j+1))
+ assert(string.find(s, startChar, j+1), "String decoding failed: missing closing " .. startChar .. " at position " .. j .. "(for string at position " .. startPos .. ")")
+ return table.concat(t,""), j+2
+ -- END SoniEx2
+end
+
+--- Scans a JSON string skipping all whitespace from the current start position.
+-- Returns the position of the first non-whitespace character, or nil if the whole end of string is reached.
+-- @param s The string being scanned
+-- @param startPos The starting position where we should begin removing whitespace.
+-- @return int The first position where non-whitespace was encountered, or string.len(s)+1 if the end of string
+-- was reached.
+function decode_scanWhitespace(s,startPos)
+ local whitespace=" \n\r\t"
+ local stringLen = string.len(s)
+ while ( string.find(whitespace, string.sub(s,startPos,startPos), 1, true) and startPos <= stringLen) do
+ startPos = startPos + 1
+ end
+ return startPos
+end
+
+--- Encodes a string to be JSON-compatible.
+-- This just involves back-quoting inverted commas, back-quotes and newlines, I think ;-)
+-- @param s The string to return as a JSON encoded (i.e. backquoted string)
+-- @return The string appropriately escaped.
+
+local escapeList = {
+ ['"'] = '\\"',
+ ['\\'] = '\\\\',
+ ['/'] = '\\/',
+ ['\b'] = '\\b',
+ ['\f'] = '\\f',
+ ['\n'] = '\\n',
+ ['\r'] = '\\r',
+ ['\t'] = '\\t'
+}
+
+function json_private.encodeString(s)
+ local s = tostring(s)
+ return s:gsub(".", function(c) return escapeList[c] end) -- SoniEx2: 5.0 compat
+end
+
+-- Determines whether the given Lua type is an array or a table / dictionary.
+-- We consider any table an array if it has indexes 1..n for its n items, and no
+-- other data in the table.
+-- I think this method is currently a little 'flaky', but can't think of a good way around it yet...
+-- @param t The table to evaluate as an array
+-- @return boolean, number True if the table can be represented as an array, false otherwise. If true,
+-- the second returned value is the maximum
+-- number of indexed elements in the array.
+function isArray(t)
+ -- Next we count all the elements, ensuring that any non-indexed elements are not-encodable
+ -- (with the possible exception of 'n')
+ if (t == json.EMPTY_ARRAY) then return true, 0 end
+ if (t == json.EMPTY_OBJECT) then return false end
+
+ local maxIndex = 0
+ for k,v in pairs(t) do
+ if (type(k)=='number' and math.floor(k)==k and 1<=k) then -- k,v is an indexed pair
+ if (not isEncodable(v)) then return false end -- All array elements must be encodable
+ maxIndex = math.max(maxIndex,k)
+ else
+ if (k=='n') then
+ if v ~= (t.n or #t) then return false end -- False if n does not hold the number of elements
+ else -- Else of (k=='n')
+ if isEncodable(v) then return false end
+ end -- End of (k~='n')
+ end -- End of k,v not an indexed pair
+ end -- End of loop across all pairs
+ return true, maxIndex
+end
+
+--- Determines whether the given Lua object / table / variable can be JSON encoded. The only
+-- types that are JSON encodable are: string, boolean, number, nil, table and json.null.
+-- In this implementation, all other types are ignored.
+-- @param o The object to examine.
+-- @return boolean True if the object should be JSON encoded, false if it should be ignored.
+function isEncodable(o)
+ local t = type(o)
+ return (t=='string' or t=='boolean' or t=='number' or t=='nil' or t=='table') or
+ (t=='function' and o==json.null)
+end
+
+return json
diff --git a/Data/DefaultContent/Libraries/json4lua/json/rpc.lua b/Data/DefaultContent/Libraries/json4lua/json/rpc.lua
new file mode 100644
index 0000000..952c5b5
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/json/rpc.lua
@@ -0,0 +1,107 @@
+-----------------------------------------------------------------------------
+-- JSONRPC4Lua: JSON RPC client calls over http for the Lua language.
+-- json.rpc Module.
+-- Author: Craig Mason-Jones
+-- Homepage: http://github.com/craigmj/json4lua/
+-- Version: 1.0.0
+-- This module is released under the MIT License (MIT).
+-- Please see LICENCE.txt for details.
+--
+-- USAGE:
+-- This module exposes two functions:
+-- proxy( 'url')
+-- Returns a proxy object for calling the JSON RPC Service at the given url.
+-- call ( 'url', 'method', ...)
+-- Calls the JSON RPC server at the given url, invokes the appropriate method, and
+-- passes the remaining parameters. Returns the result and the error. If the result is nil, an error
+-- should be there (or the system returned a null). If an error is there, the result should be nil.
+--
+-- REQUIREMENTS:
+-- Lua socket 2.0 (http://www.cs.princeton.edu/~diego/professional/luasocket/)
+-- json (The JSON4Lua package with which it is bundled)
+-- compat-5.1 if using Lua 5.0.
+-----------------------------------------------------------------------------
+
+local json = require('json')
+json.rpc = {} -- Module public namespace
+
+-----------------------------------------------------------------------------
+-- Imports and dependencies
+-----------------------------------------------------------------------------
+local json = require('json')
+local http = require("socket.http")
+
+-----------------------------------------------------------------------------
+-- PUBLIC functions
+-----------------------------------------------------------------------------
+
+--- Creates an RPC Proxy object for the given Url of a JSON-RPC server.
+-- @param url The URL for the JSON RPC Server.
+-- @return Object on which JSON-RPC remote methods can be called.
+-- EXAMPLE Usage:
+-- local jsolait = json.rpc.proxy('http://jsolait.net/testj.py')
+-- print(jsolait.echo('This is a test of the echo method!'))
+-- print(jsolait.args2String('first','second','third'))
+-- table.foreachi( jsolait.args2Array(5,4,3,2,1), print)
+function json.rpc.proxy(url)
+ local serverProxy = {}
+ local proxyMeta = {
+ __index = function(self, key)
+ return function(...)
+ return json.rpc.call(url, key, ...)
+ end
+ end
+ }
+ setmetatable(serverProxy, proxyMeta)
+ return serverProxy
+end
+
+--- Calls a JSON RPC method on a remote server.
+-- Returns a boolean true if the call succeeded, false otherwise.
+-- On success, the second returned parameter is the decoded
+-- JSON object from the server.
+-- On http failure, returns nil and an error message.
+-- On success, returns the result and nil.
+-- @param url The url of the JSON RPC server.
+-- @param method The method being called.
+-- @param ... Parameters to pass to the method.
+-- @return result, error The JSON RPC result and error. One or the other should be nil. If both
+-- are nil, this means that the result of the RPC call was nil.
+-- EXAMPLE Usage:
+-- print(json.rpc.call('http://jsolait.net/testj.py','echo','This string will be returned'))
+function json.rpc.call(url, method, ...)
+ local JSONRequestArray = {
+ id=tostring(math.random()),
+ ["method"]=method,
+ ["jsonrpc"]="2.0",
+ params = ...
+ }
+ local httpResponse, result , code
+ local jsonRequest = json.encode(JSONRequestArray)
+ -- We use the sophisticated http.request form (with ltn12 sources and sinks) so that
+ -- we can set the content-type to text/plain. While this shouldn't strictly-speaking be true,
+ -- it seems a good idea (Xavante won't work w/out a content-type header, although a patch
+ -- is needed to Xavante to make it work with text/plain)
+ local ltn12 = require('ltn12')
+ local resultChunks = {}
+ httpResponse, code = http.request(
+ { ['url'] = url,
+ sink = ltn12.sink.table(resultChunks),
+ method = 'POST',
+ headers = { ['content-type']='application/json-rpc', ['content-length']=string.len(jsonRequest) },
+ source = ltn12.source.string(jsonRequest)
+ }
+ )
+ httpResponse = table.concat(resultChunks)
+ -- Check the http response code
+ if (code~=200) then
+ return nil, "HTTP ERROR: " .. code
+ end
+ -- And decode the httpResponse and check the JSON RPC result code
+ result = json.decode( httpResponse )
+ if result.result then
+ return result.result, nil
+ else
+ return nil, result.error
+ end
+end
diff --git a/Data/DefaultContent/Libraries/json4lua/json/rpcserver.lua b/Data/DefaultContent/Libraries/json4lua/json/rpcserver.lua
new file mode 100644
index 0000000..e01f1f8
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/json/rpcserver.lua
@@ -0,0 +1,78 @@
+-----------------------------------------------------------------------------
+-- JSONRPC4Lua: JSON RPC server for exposing Lua objects as JSON RPC callable
+-- objects via http.
+-- json.rpcserver Module.
+-- Author: Craig Mason-Jones
+-- Homepage: http://github.com/craigmj/json4lua/
+-- Version: 1.0.0
+-- This module is released under the MIT License (MIT).
+-- Please see LICENCE.txt for details.
+--
+-- USAGE:
+-- This module exposes one function:
+-- server(luaClass, packReturn)
+-- Manages incoming JSON RPC request forwarding the method call to the given
+-- object. If packReturn is true, multiple return values are packed into an
+-- array on return.
+--
+-- IMPORTANT NOTES:
+-- 1. This version ought really not be 0.9.10, since this particular part of the
+-- JSONRPC4Lua package is very first-draft. However, the JSON4Lua package with which
+-- it comes is quite solid, so there you have it :-)
+-- 2. This has only been tested with Xavante webserver, with which it works
+-- if you patch CGILua to accept 'text/plain' content type. See doc\cgilua_patch.html
+-- for details.
+----------------------------------------------------------------------------
+
+module ('json.rpcserver')
+
+---
+-- Implements a JSON RPC Server wrapping for luaClass, exposing each of luaClass's
+-- methods as JSON RPC callable methods.
+-- @param luaClass The JSON RPC class to expose.
+-- @param packReturn If true, the server will automatically wrap any
+-- multiple-value returns into an array. Single returns remain single returns. If
+-- false, when a function returns multiple values, only the first of these values will
+-- be returned.
+--
+function serve(luaClass, packReturn)
+ cgilua.contentheader('text','plain')
+ require('cgilua')
+ require ('json')
+ local postData = ""
+
+ if not cgilua.servervariable('CONTENT_LENGTH') then
+ cgilua.put("Please access JSON Request using HTTP POST Request")
+ return 0
+ else
+ postData = cgi[1] -- SAPI.Request.getpostdata() --[[{ "id":1, "method":"echo","params":["Hi there"]}]] --
+ end
+ -- @TODO Catch an error condition on decoding the data
+ local jsonRequest = json.decode(postData)
+ local jsonResponse = {}
+ jsonResponse.id = jsonRequest.id
+ local method = luaClass[ jsonRequest.method ]
+
+ if not method then
+ jsonResponse.error = 'Method ' .. jsonRequest.method .. ' does not exist at this server.'
+ else
+ local callResult = { pcall( method, unpack( jsonRequest.params ) ) }
+ if callResult[1] then -- Function call successfull
+ table.remove(callResult,1)
+ if packReturn and table.getn(callResult)>1 then
+ jsonResponse.result = callResult
+ else
+ jsonResponse.result = unpack(callResult) -- NB: Does not support multiple argument returns
+ end
+ else
+ jsonResponse.error = callResult[2]
+ end
+ end
+
+ -- Output the result
+ -- TODO: How to be sure that the result and error tags are there even when they are nil in Lua?
+ -- Can force them by hand... ?
+ cgilua.contentheader('text','plain')
+ cgilua.put( json.encode( jsonResponse ) )
+end
+
diff --git a/Data/DefaultContent/Libraries/json4lua/json4lua-1.0.0-1.rockspec b/Data/DefaultContent/Libraries/json4lua/json4lua-1.0.0-1.rockspec
new file mode 100644
index 0000000..b3b737a
--- /dev/null
+++ b/Data/DefaultContent/Libraries/json4lua/json4lua-1.0.0-1.rockspec
@@ -0,0 +1,32 @@
+package="JSON4Lua"
+version="1.0.0"
+source = {
+ url = "git://github.com/craigmj/json4lua.git",
+ tag = "1.0.0"
+}
+description = {
+ summary = "JSON4Lua and JSONRPC4Lua implement JSON (JavaScript Object Notation) encoding and decoding and a JSON-RPC-over-http client for Lua.",
+ detailed = [[
+ JSON4Lua and JSONRPC4Lua implement JSON (JavaScript Object Notation)
+ encoding and decoding and a JSON-RPC-over-http client for Lua.
+ JSON is JavaScript Object Notation, a simple encoding of
+ Javascript-like objects that is ideal for lightweight transmission
+ of relatively weakly-typed data. A sub-package of JSON4Lua is
+ JSONRPC4Lua, which provides a simple JSON-RPC-over-http client and server
+ (in a CGILua environment) for Lua.
+ ]],
+ homepage = "http://github.com/craigmj/json4lua/",
+ license = "GPL"
+}
+dependencies = {
+ "lua >= 5.2",
+ "luasocket",
+}
+
+build = {
+ type = "builtin",
+ modules = {
+ ["json"] = "json/json.lua",
+ ["json.rpc"] = "json/rpc.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/lbase64/.gitignore b/Data/DefaultContent/Libraries/lbase64/.gitignore
new file mode 100644
index 0000000..a70719a
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lbase64/.gitignore
@@ -0,0 +1,3 @@
+*.out
+*.swp
+*.swo
diff --git a/Data/DefaultContent/Libraries/lbase64/.travis.yml b/Data/DefaultContent/Libraries/lbase64/.travis.yml
new file mode 100644
index 0000000..7bca356
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lbase64/.travis.yml
@@ -0,0 +1,25 @@
+language: python
+sudo: false
+
+env:
+ - LUA="lua 5.1"
+ - LUA="lua 5.2"
+ - LUA="lua 5.3"
+ - LUA="lua 5.4"
+ - LUA="luajit 2.0"
+ - LUA="luajit 2.1"
+
+before_install:
+ - pip install hererocks
+ - hererocks env --$LUA -rlatest # Use latest LuaRocks, install into 'env' directory.
+ - source env/bin/activate # Add directory with all installed binaries to PATH.notifications:
+
+notifications:
+ email: false
+
+install:
+ - luarocks install luacheck
+
+script:
+ - luacheck --no-unused-args *.lua
+ - lua test.lua
diff --git a/Data/DefaultContent/Libraries/lbase64/README.md b/Data/DefaultContent/Libraries/lbase64/README.md
new file mode 100644
index 0000000..1b5b0ee
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lbase64/README.md
@@ -0,0 +1,48 @@
+[![Build Status](https://travis-ci.org/iskolbin/lbase64.svg?branch=master)](https://travis-ci.org/iskolbin/lbase64)
+[![license](https://img.shields.io/badge/license-public%20domain-blue.svg)]()
+[![MIT Licence](https://badges.frapsoft.com/os/mit/mit.svg?v=103)](https://opensource.org/licenses/mit-license.php)
+
+Lua base64 encoder/decoder
+==========================
+
+Pure Lua [base64](https://en.wikipedia.org/wiki/Base64) encoder/decoder. Works with
+Lua 5.1+ and LuaJIT. Fallbacks to pure Lua bit operations if bit/bit32/native bit
+operators are not available.
+
+```lua
+local base64 = require'base64'
+local str = 'Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.'
+local b64str = 'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4='
+local encoded = base64.encode( str )
+local decoded = base64.decode( b64str )
+assert( str == decoded )
+assert( b64str == encoded )
+```
+
+base64.encode( str, encoder = DEFAULT, usecache = false )
+---------------------------------------------------------
+Encodes `str` string using `encoder` table. By default uses table with `+` as
+char for 62, `/` as char for 63 and `=` as padding char. You can specify custom
+encoder. For this you could use `base64.makeencoder`. If you are encoding large
+chunks of text (or another highly redundant data) it's possible to highly
+increase performace (for text approx. x2 gain) by using `usecache = true`. For
+binary data like images using cache decreasing performance.
+
+base64.decode( str, decoder = DEFAULT, usecache = false )
+---------------------------------------------------------
+Decodes `str` string using `decoder` table. Default decoder uses same chars as
+default encoder.
+
+base64.makeencoder( s62 = '+', s63 = '/', spad = '=' )
+------------------------------------------------------
+Make custom encoding table
+
+base64.makedecoder( s62 = '+', s63 = '/', spad = '=' )
+------------------------------------------------------
+Make custom decoding table
+
+Install
+-------
+```bash
+luarocks install base64
+```
diff --git a/Data/DefaultContent/Libraries/lbase64/base64.lua b/Data/DefaultContent/Libraries/lbase64/base64.lua
new file mode 100644
index 0000000..32de332
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lbase64/base64.lua
@@ -0,0 +1,201 @@
+--[[
+
+ base64 -- v1.5.3 public domain Lua base64 encoder/decoder
+ no warranty implied; use at your own risk
+
+ Needs bit32.extract function. If not present it's implemented using BitOp
+ or Lua 5.3 native bit operators. For Lua 5.1 fallbacks to pure Lua
+ implementation inspired by Rici Lake's post:
+ http://ricilake.blogspot.co.uk/2007/10/iterating-bits-in-lua.html
+
+ author: Ilya Kolbin (iskolbin@gmail.com)
+ url: github.com/iskolbin/lbase64
+
+ COMPATIBILITY
+
+ Lua 5.1+, LuaJIT
+
+ LICENSE
+
+ See end of file for license information.
+
+--]]
+
+
+local base64 = {}
+
+local extract = _G.bit32 and _G.bit32.extract -- Lua 5.2/Lua 5.3 in compatibility mode
+if not extract then
+ if _G.bit then -- LuaJIT
+ local shl, shr, band = _G.bit.lshift, _G.bit.rshift, _G.bit.band
+ extract = function( v, from, width )
+ return band( shr( v, from ), shl( 1, width ) - 1 )
+ end
+ elseif _G._VERSION == "Lua 5.1" then
+ extract = function( v, from, width )
+ local w = 0
+ local flag = 2^from
+ for i = 0, width-1 do
+ local flag2 = flag + flag
+ if v % flag2 >= flag then
+ w = w + 2^i
+ end
+ flag = flag2
+ end
+ return w
+ end
+ else -- Lua 5.3+
+ extract = load[[return function( v, from, width )
+ return ( v >> from ) & ((1 << width) - 1)
+ end]]()
+ end
+end
+
+
+function base64.makeencoder( s62, s63, spad )
+ local encoder = {}
+ for b64code, char in pairs{[0]='A','B','C','D','E','F','G','H','I','J',
+ 'K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y',
+ 'Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n',
+ 'o','p','q','r','s','t','u','v','w','x','y','z','0','1','2',
+ '3','4','5','6','7','8','9',s62 or '+',s63 or'/',spad or'='} do
+ encoder[b64code] = char:byte()
+ end
+ return encoder
+end
+
+function base64.makedecoder( s62, s63, spad )
+ local decoder = {}
+ for b64code, charcode in pairs( base64.makeencoder( s62, s63, spad )) do
+ decoder[charcode] = b64code
+ end
+ return decoder
+end
+
+local DEFAULT_ENCODER = base64.makeencoder()
+local DEFAULT_DECODER = base64.makedecoder()
+
+local char, concat = string.char, table.concat
+
+function base64.encode( str, encoder, usecaching )
+ encoder = encoder or DEFAULT_ENCODER
+ local t, k, n = {}, 1, #str
+ local lastn = n % 3
+ local cache = {}
+ for i = 1, n-lastn, 3 do
+ local a, b, c = str:byte( i, i+2 )
+ local v = a*0x10000 + b*0x100 + c
+ local s
+ if usecaching then
+ s = cache[v]
+ if not s then
+ s = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[extract(v,0,6)])
+ cache[v] = s
+ end
+ else
+ s = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[extract(v,0,6)])
+ end
+ t[k] = s
+ k = k + 1
+ end
+ if lastn == 2 then
+ local a, b = str:byte( n-1, n )
+ local v = a*0x10000 + b*0x100
+ t[k] = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[extract(v,6,6)], encoder[64])
+ elseif lastn == 1 then
+ local v = str:byte( n )*0x10000
+ t[k] = char(encoder[extract(v,18,6)], encoder[extract(v,12,6)], encoder[64], encoder[64])
+ end
+ return concat( t )
+end
+
+function base64.decode( b64, decoder, usecaching )
+ decoder = decoder or DEFAULT_DECODER
+ local pattern = '[^%w%+%/%=]'
+ if decoder then
+ local s62, s63
+ for charcode, b64code in pairs( decoder ) do
+ if b64code == 62 then s62 = charcode
+ elseif b64code == 63 then s63 = charcode
+ end
+ end
+ pattern = ('[^%%w%%%s%%%s%%=]'):format( char(s62), char(s63) )
+ end
+ b64 = b64:gsub( pattern, '' )
+ local cache = usecaching and {}
+ local t, k = {}, 1
+ local n = #b64
+ local padding = b64:sub(-2) == '==' and 2 or b64:sub(-1) == '=' and 1 or 0
+ for i = 1, padding > 0 and n-4 or n, 4 do
+ local a, b, c, d = b64:byte( i, i+3 )
+ local s
+ if usecaching then
+ local v0 = a*0x1000000 + b*0x10000 + c*0x100 + d
+ s = cache[v0]
+ if not s then
+ local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40 + decoder[d]
+ s = char( extract(v,16,8), extract(v,8,8), extract(v,0,8))
+ cache[v0] = s
+ end
+ else
+ local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40 + decoder[d]
+ s = char( extract(v,16,8), extract(v,8,8), extract(v,0,8))
+ end
+ t[k] = s
+ k = k + 1
+ end
+ if padding == 1 then
+ local a, b, c = b64:byte( n-3, n-1 )
+ local v = decoder[a]*0x40000 + decoder[b]*0x1000 + decoder[c]*0x40
+ t[k] = char( extract(v,16,8), extract(v,8,8))
+ elseif padding == 2 then
+ local a, b = b64:byte( n-3, n-2 )
+ local v = decoder[a]*0x40000 + decoder[b]*0x1000
+ t[k] = char( extract(v,16,8))
+ end
+ return concat( t )
+end
+
+return base64
+
+--[[
+------------------------------------------------------------------------------
+This software is available under 2 licenses -- choose whichever you prefer.
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+Copyright (c) 2018 Ilya Kolbin
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+------------------------------------------------------------------------------
+ALTERNATIVE B - Public Domain (www.unlicense.org)
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+software, either in source code form or as a compiled binary, for any purpose,
+commercial or non-commercial, and by any means.
+In jurisdictions that recognize copyright laws, the author or authors of this
+software dedicate any and all copyright interest in the software to the public
+domain. We make this dedication for the benefit of the public at large and to
+the detriment of our heirs and successors. We intend this dedication to be an
+overt act of relinquishment in perpetuity of all present and future rights to
+this software under copyright law.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+------------------------------------------------------------------------------
+--]]
diff --git a/Data/DefaultContent/Libraries/lbase64/bench.lua b/Data/DefaultContent/Libraries/lbase64/bench.lua
new file mode 100644
index 0000000..d24c1bf
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lbase64/bench.lua
@@ -0,0 +1,76 @@
+local base64 = require'base64'
+local N = 10000000
+local st = {}
+local letters = ' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
+ .. 'абвгдеёжзийклмнопрÑтуфхцшщчъыьÑÑŽÑ'
+ .. 'ÐБВГДЕÐЖЗИЙКЛМÐОПРСТУФХЦШЩЧЪЫЬЭЮЯ'
+local nletters = #letters
+for i = 1, N do
+ local j = math.random( nletters )
+ st[i] = letters:sub( j, j )
+end
+local s = table.concat( st )
+local t = os.clock()
+local encoded = base64.encode( s )
+local encodetime = os.clock() - t
+
+t = os.clock()
+local decoded = base64.decode( encoded )
+local decodetime = os.clock() - t
+
+assert( s == decoded )
+print('Common text')
+print(('Encoding: %d bytes/sec'):format( math.floor(N/encodetime)))
+print(('Decoding: %d bytes/sec'):format( math.floor(N/decodetime)))
+collectgarbage()
+
+t = os.clock()
+encoded = base64.encode( s, nil, true )
+encodetime = os.clock() - t
+
+t = os.clock()
+decoded = base64.decode( encoded, nil, true )
+assert( s == decoded )
+decodetime = os.clock() - t
+print('Common text (cache)')
+print(('Encoding: %d bytes/sec'):format( math.floor(N/encodetime)))
+print(('Decoding: %d bytes/sec'):format( math.floor(N/decodetime)))
+collectgarbage()
+
+local lt = {}
+for i = 0, 255 do
+ lt[i] = string.char(i)
+end
+nletters = #lt
+for i = 1, N do
+ local j = math.random( nletters )
+ st[i] = lt[j]
+end
+s = table.concat( st )
+
+t = os.clock()
+encoded = base64.encode( s, nil )
+encodetime = os.clock() - t
+
+t = os.clock()
+decoded = base64.decode( encoded )
+decodetime = os.clock() - t
+
+assert( s == decoded )
+print('Binary')
+print(('Encoding: %d bytes/sec'):format( math.floor(N/encodetime)))
+print(('Decoding: %d bytes/sec'):format( math.floor(N/decodetime)))
+collectgarbage()
+
+t = os.clock()
+encoded = base64.encode( s, nil, true )
+encodetime = os.clock() - t
+
+t = os.clock()
+decoded = base64.decode( encoded, nil, true )
+assert( s == decoded )
+decodetime = os.clock() - t
+print('Binary (cache)')
+print(('Encoding: %d bytes/sec'):format( math.floor(N/encodetime)))
+print(('Decoding: %d bytes/sec'):format( math.floor(N/decodetime)))
+collectgarbage()
diff --git a/Data/DefaultContent/Libraries/lbase64/rockspec/base64-1.5-1.rockspec b/Data/DefaultContent/Libraries/lbase64/rockspec/base64-1.5-1.rockspec
new file mode 100644
index 0000000..f25c7b4
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lbase64/rockspec/base64-1.5-1.rockspec
@@ -0,0 +1,20 @@
+package = "base64"
+version = "1.5-1"
+source = {
+ url = "git+https://github.com/iskolbin/lbase64",
+ tag = "v1.5.1",
+}
+description = {
+ summary = "Pure Lua base64 encoder/decoder",
+ detailed = [[
+Pure Lua [base64](https://en.wikipedia.org/wiki/Base64) encoder/decoder. Works with Lua 5.1+ and LuaJIT. Fallbacks to pure Lua bit operations if bit/bit32/native bit operators are not available.]],
+ homepage = "https://github.com/iskolbin/lbase64",
+ license = "MIT/Public Domain"
+}
+dependencies = {}
+build = {
+ type = "builtin",
+ modules = {
+ base64 = "base64.lua",
+ }
+}
diff --git a/Data/DefaultContent/Libraries/lbase64/rockspec/base64-1.5-2.rockspec b/Data/DefaultContent/Libraries/lbase64/rockspec/base64-1.5-2.rockspec
new file mode 100644
index 0000000..7d0addd
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lbase64/rockspec/base64-1.5-2.rockspec
@@ -0,0 +1,20 @@
+package = "base64"
+version = "1.5-2"
+source = {
+ url = "git://github.com/iskolbin/lbase64",
+ tag = "v1.5.2",
+}
+description = {
+ summary = "Pure Lua base64 encoder/decoder",
+ detailed = [[
+Pure Lua [base64](https://en.wikipedia.org/wiki/Base64) encoder/decoder. Works with Lua 5.1+ and LuaJIT. Fallbacks to pure Lua bit operations if bit/bit32/native bit operators are not available.]],
+ homepage = "https://github.com/iskolbin/lbase64",
+ license = "MIT/Public Domain"
+}
+dependencies = {}
+build = {
+ type = "builtin",
+ modules = {
+ base64 = "base64.lua",
+ }
+}
diff --git a/Data/DefaultContent/Libraries/lbase64/rockspec/base64-1.5-3.rockspec b/Data/DefaultContent/Libraries/lbase64/rockspec/base64-1.5-3.rockspec
new file mode 100644
index 0000000..60706d3
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lbase64/rockspec/base64-1.5-3.rockspec
@@ -0,0 +1,20 @@
+package = "base64"
+version = "1.5-3"
+source = {
+ url = "git://github.com/iskolbin/lbase64",
+ tag = "v1.5.3",
+}
+description = {
+ summary = "Pure Lua base64 encoder/decoder",
+ detailed = [[
+Pure Lua base64 encoder/decoder. Works with Lua 5.1+ and LuaJIT. Fallbacks to pure Lua bit operations if bit/bit32/native bit operators are not available.]],
+ homepage = "https://github.com/iskolbin/lbase64",
+ license = "MIT/Public Domain"
+}
+dependencies = {}
+build = {
+ type = "builtin",
+ modules = {
+ base64 = "base64.lua",
+ }
+}
diff --git a/Data/DefaultContent/Libraries/lbase64/test.lua b/Data/DefaultContent/Libraries/lbase64/test.lua
new file mode 100644
index 0000000..d8efebf
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lbase64/test.lua
@@ -0,0 +1,47 @@
+local base64 = require('base64')
+
+local function test( s, b64 )
+ assert( base64.encode( s ) == b64 )
+ assert( base64.decode( b64 ) == s )
+ assert( base64.decode( base64.encode( s )) == s )
+ assert( base64.encode( s, nil, true ) == b64 )
+ assert( base64.decode( b64, nil, true ) == s )
+ assert( base64.decode( base64.encode( s, nil, true ), nil, true ) == s )
+end
+
+test( 'any carnal pleasure.', 'YW55IGNhcm5hbCBwbGVhc3VyZS4=' )
+test( 'any carnal pleasure', 'YW55IGNhcm5hbCBwbGVhc3VyZQ==' )
+test( 'any carnal pleasur', 'YW55IGNhcm5hbCBwbGVhc3Vy' )
+test( 'Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a ' ..
+ 'lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, ' ..
+ 'exceeds the short vehemence of any carnal pleasure.', 'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb' ..
+ '24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoY' ..
+ 'XQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd' ..
+ '2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=' )
+test( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et ' ..
+ 'dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea ' ..
+ 'commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat ' ..
+ 'nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit ' ..
+ 'anim id est laborum.', 'TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwgc2VkIGRvIGVp' ..
+ 'dXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVuaWFtLCBx' ..
+ 'dWlzIG5vc3RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBuaXNpIHV0IGFsaXF1aXAgZXggZWEgY29tbW9kbyBjb25zZXF1YXQuIER1' ..
+ 'aXMgYXV0ZSBpcnVyZSBkb2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2ZWxpdCBlc3NlIGNpbGx1bSBkb2xvcmUgZXUgZnVnaWF0' ..
+ 'IG51bGxhIHBhcmlhdHVyLiBFeGNlcHRldXIgc2ludCBvY2NhZWNhdCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBzdW50IGluIGN1bHBhIHF1aSBv' ..
+ 'ZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlkIGVzdCBsYWJvcnVtLg==')
+test( '«В чащах юга жил бы цитруÑ? Да, но фальшивый ÑкземплÑÑ€!»',
+ 'wqvQkiDRh9Cw0YnQsNGFINGO0LPQsCDQttC40Lsg0LHRiyDR' ..
+ 'htC40YLRgNGD0YE/INCU0LAsINC90L4g0YTQsNC70YzRiNC40LLRi9C5INGN0LrQt9C10LzQv9C70Y/RgCHCuw==')
+test( '«В чащах юга жил бы цитруÑ? Да, фальшивый ÑкземплÑÑ€!»',
+ 'wqvQkiDRh9Cw0YnQsNGFINGO0LPQsCDQttC40Lsg0LHRiyDRhtC' ..
+ '40YLRgNGD0YE/INCU0LAsINGE0LDQu9GM0YjQuNCy0YvQuSDRjdC60LfQtdC80L/Qu9GP0YAhwrs=')
+test( '\137\080\078\071\013\010\026\010\000\000\000\013\073\072\068\082\000\000\000\032\000\000\000\032\001\003\000' ..
+ '\000\000\073\180\232\183\000\000\000\006\080\076\084\069\255\255\255\000\000\000\085\194\211\126\000\000\000\018' ..
+ '\073\068\065\084\008\215\099\248\015\004\196\016\084\006\196\218\011\000\237\189\063\193\243\000\141\059\000\000' ..
+ '\000\000\073\069\078\068\174\066\096\130', 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgAQMAAABJtOi3AAAABlBMVEX///8AAABVwtN+' ..
+ 'AAAAEklEQVQI12P4DwTEEFQGxNoLAO29P8HzAI07AAAAAElFTkSuQmCC' )
+
+assert( base64.decode('YW55IGNhcm5hbCBwbGVhc3VyZS4=\n\r\\' ) == 'any carnal pleasure.' )
+
+assert( base64.decode('wйqеvнQÑуkкiеDнRгhш9щCзwÑ…0ÑŠÑ„YÑ‹nвQаsпNÑ€GоFллIдNжGÑOÑ‘0ÑLчPQsCDQttC40Lsg0LHRiyDRhtC' ..
+ '40YLRgNGD0YE/INÑCмUи0Ñ‚LÑŒAбsÑŽIЙКNЕG\n\n\n\n\r\rE0LDQu9GM0YjQuNCy0YvQuSDRjdC60LfQtdC80L/Qu9GP0YAhwrs=') ==
+ '«В чащах юга жил бы цитруÑ? Да, фальшивый ÑкземплÑÑ€!»' )
diff --git a/Data/DefaultContent/Libraries/lua-csv/.gitignore b/Data/DefaultContent/Libraries/lua-csv/.gitignore
new file mode 100644
index 0000000..131f9b6
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/.gitignore
@@ -0,0 +1,2 @@
+.DS_Store
+lua/docs \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/lua-csv/AUTHORS b/Data/DefaultContent/Libraries/lua-csv/AUTHORS
new file mode 100644
index 0000000..84961bd
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/AUTHORS
@@ -0,0 +1,2 @@
+Leyland, Geoff
+Martin, Kevin
diff --git a/Data/DefaultContent/Libraries/lua-csv/LICENSE b/Data/DefaultContent/Libraries/lua-csv/LICENSE
new file mode 100644
index 0000000..d8472a0
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2013-2014 Incremental IP Limited
+Copyright (c) 2014 Kevin Martin
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
diff --git a/Data/DefaultContent/Libraries/lua-csv/README.md b/Data/DefaultContent/Libraries/lua-csv/README.md
new file mode 100644
index 0000000..d10314a
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/README.md
@@ -0,0 +1,93 @@
+# Lua-CSV - delimited file reading
+
+## 1. What?
+
+Lua-CSV is a Lua module for reading delimited text files (popularly CSV and
+tab-separated files, but you can specify the separator).
+
+Lua-CSV tries to auto-detect whether a file is delimited with commas or tabs,
+copes with non-native newlines, survives newlines and quotes inside quoted
+fields and offers an iterator interface so it can handle large files.
+
+
+## 2. How?
+
+ local csv = require("csv")
+ local f = csv.open("file.csv")
+ for fields in f:lines() do
+ for i, v in ipairs(fields) do print(i, v) end
+ end
+
+`csv.open` takes a second argument `parameters`, a table of parameters
+controlling how the file is read:
+
++ `separator` sets the separator. It'll probably guess the separator
+ correctly if it's a comma or a tab (unless, say, the first field in a
+ tab-delimited file contains a comma), but if you want something else you'll
+ have to set this. It could be more than one character, but it's used as
+ part of a set: `"["..sep.."\n\r]"`
+
++ Set `header` to true if the file contains a header and each set of fields
+ will be keyed by the names in the header rather than by integer index.
+
++ `columns` provides a mechanism for column remapping.
+ Suppose you have a csv file as follows:
+
+ Word,Number
+ ONE,10
+
+ And columns is:
+
+ + `{ word = true }` then the only field in the file would be
+ `{ word = "ONE" }`
+ + `{ first = { name = "word"} }` then it would be `{ first = "ONE" }`
+ + `{ word = { transform = string.lower }}` would give `{ word = "one" }`
+ + finally,
+
+ { word = true
+ number = { transform = function(x) return tonumber(x) / 10 end }}
+
+ would give `{ word = "ONE", number = 1 }`
+
+ A column can have more than one name:
+ `{ first = { names = {"word", "worm"}}}` to help cope with badly specified
+ file formats and spelling mistakes.
+
++ `buffer_size` controls the size of the blocks the file is read in. The
+ default is 1MB. It used to be 4096 bytes which is what `pagesize` says on
+ my system, but that seems kind of small.
+
+`csv.openstring` works exactly like `csv.open` except the first argument
+is the contents of the csv file. In this case `buffer_size` is set to
+the length of the string.
+
+## 3. Requirements
+
+Lua 5.1, 5.2 or LuaJIT.
+
+
+## 4. Issues
+
++ Some whitespace-delimited files might use more than one space between
+ fields, for example if the columns are "manually" aligned:
+
+ street nr city
+ "Oneway Street" 1 Toontown
+
+ It won't cope with this - you'll get lots of extra empty fields.
+
+## 5. Wishlist
+
++ Tests would be nice.
++ So would better LDoc documentation.
+
+
+## 6. Alternatives
+
++ [Penlight](http://github.com/stevedonovan/penlight) contains delimited
+ file reading. It reads the whole file in one go.
++ The Lua Wiki contains two pages on CSV
+ [here](http://lua-users.org/wiki/LuaCsv) and
+ [here](http://lua-users.org/wiki/CsvUtils).
++ There's an example using [LPeg](http://www.inf.puc-rio.br/~roberto/lpeg/)
+ to parse CSV [here](http://www.inf.puc-rio.br/~roberto/lpeg/#CSV)
diff --git a/Data/DefaultContent/Libraries/lua-csv/lua/config.ld b/Data/DefaultContent/Libraries/lua-csv/lua/config.ld
new file mode 100644
index 0000000..af51949
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/lua/config.ld
@@ -0,0 +1,4 @@
+project = "Lua-CSV"
+title = "Lua-CSV Source Documentation"
+description = "Lua-CSV reads delimited text files"
+format = "markdown"
diff --git a/Data/DefaultContent/Libraries/lua-csv/lua/csv.lua b/Data/DefaultContent/Libraries/lua-csv/lua/csv.lua
new file mode 100644
index 0000000..64196c0
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/lua/csv.lua
@@ -0,0 +1,557 @@
+--- Read a comma or tab (or other delimiter) separated file.
+-- This version of a CSV reader differs from others I've seen in that it
+--
+-- + handles embedded newlines in fields (if they're delimited with double
+-- quotes)
+-- + is line-ending agnostic
+-- + reads the file line-by-line, so it can potientially handle large
+-- files.
+--
+-- Of course, for such a simple format, CSV is horribly complicated, so it
+-- likely gets something wrong.
+
+-- (c) Copyright 2013-2014 Incremental IP Limited.
+-- (c) Copyright 2014 Kevin Martin
+-- Available under the MIT licence. See LICENSE for more information.
+
+local DEFAULT_BUFFER_BLOCK_SIZE = 1024 * 1024
+
+
+------------------------------------------------------------------------------
+
+local function trim_space(s)
+ return s:match("^%s*(.-)%s*$")
+end
+
+
+local function fix_quotes(s)
+ -- the sub(..., -2) is to strip the trailing quote
+ return string.sub(s:gsub('""', '"'), 1, -2)
+end
+
+
+------------------------------------------------------------------------------
+
+local column_map = {}
+column_map.__index = column_map
+
+
+local function normalise_string(s)
+ return (s:lower():gsub("[^%w%d]+", " "):gsub("^ *(.-) *$", "%1"))
+end
+
+
+--- Parse a list of columns.
+-- The main job here is normalising column names and dealing with columns
+-- for which we have more than one possible name in the header.
+function column_map:new(columns)
+ local name_map = {}
+ for n, v in pairs(columns) do
+ local names
+ local t
+ if type(v) == "table" then
+ t = { transform = v.transform, default = v.default }
+ if v.name then
+ names = { normalise_string(v.name) }
+ elseif v.names then
+ names = v.names
+ for i, n in ipairs(names) do names[i] = normalise_string(n) end
+ end
+ else
+ if type(v) == "function" then
+ t = { transform = v }
+ else
+ t = {}
+ if type(v) == "string" then
+ names = { normalise_string(v) }
+ end
+ end
+ end
+
+ if not names then
+ names = { (n:lower():gsub("[^%w%d]+", " ")) }
+ end
+
+ t.name = n
+ for _, n in ipairs(names) do
+ name_map[n:lower()] = t
+ end
+ end
+
+ return setmetatable({ name_map = name_map }, column_map)
+end
+
+
+--- Map "virtual" columns to file columns.
+-- Once we've read the header, work out which columns we're interested in and
+-- what to do with them. Mostly this is about checking we've got the columns
+-- we need and writing a nice complaint if we haven't.
+function column_map:read_header(header)
+ local index_map = {}
+
+ -- Match the columns in the file to the columns in the name map
+ local found = {}
+ local found_any
+ for i, word in ipairs(header) do
+ word = normalise_string(word)
+ local r = self.name_map[word]
+ if r then
+ index_map[i] = r
+ found[r.name] = true
+ found_any = true
+ end
+ end
+
+ if not found_any then return end
+
+ -- check we found all the columns we need
+ local not_found = {}
+ for name, r in pairs(self.name_map) do
+ if not found[r.name] then
+ local nf = not_found[r.name]
+ if nf then
+ nf[#nf+1] = name
+ else
+ not_found[r.name] = { name }
+ end
+ end
+ end
+ -- If any columns are missing, assemble an error message
+ if next(not_found) then
+ local problems = {}
+ for k, v in pairs(not_found) do
+ local missing
+ if #v == 1 then
+ missing = "'"..v[1].."'"
+ else
+ missing = v[1]
+ for i = 2, #v - 1 do
+ missing = missing..", '"..v[i].."'"
+ end
+ missing = missing.." or '"..v[#v].."'"
+ end
+ problems[#problems+1] = "Couldn't find a column named "..missing
+ end
+ error(table.concat(problems, "\n"), 0)
+ end
+
+ self.index_map = index_map
+ return true
+end
+
+
+function column_map:transform(value, index)
+ local field = self.index_map[index]
+ if field then
+ if field.transform then
+ local ok
+ ok, value = pcall(field.transform, value)
+ if not ok then
+ error(("Error reading field '%s': %s"):format(field.name, value), 0)
+ end
+ end
+ return value or field.default, field.name
+ end
+end
+
+
+------------------------------------------------------------------------------
+
+local file_buffer = {}
+file_buffer.__index = file_buffer
+
+function file_buffer:new(file, buffer_block_size)
+ return setmetatable({
+ file = file,
+ buffer_block_size = buffer_block_size or DEFAULT_BUFFER_BLOCK_SIZE,
+ buffer_start = 0,
+ buffer = "",
+ }, file_buffer)
+end
+
+
+--- Cut the front off the buffer if we've already read it
+function file_buffer:truncate(p)
+ p = p - self.buffer_start
+ if p > self.buffer_block_size then
+ local remove = self.buffer_block_size *
+ math.floor((p-1) / self.buffer_block_size)
+ self.buffer = self.buffer:sub(remove + 1)
+ self.buffer_start = self.buffer_start + remove
+ end
+end
+
+
+--- Find something in the buffer, extending it if necessary
+function file_buffer:find(pattern, init)
+ while true do
+ local first, last, capture =
+ self.buffer:find(pattern, init - self.buffer_start)
+ -- if we found nothing, or the last character is at the end of the
+ -- buffer (and the match could potentially be longer) then read some
+ -- more.
+ if not first or last == #self.buffer then
+ local s = self.file:read(self.buffer_block_size)
+ if not s then
+ if not first then
+ return
+ else
+ return first + self.buffer_start, last + self.buffer_start, capture
+ end
+ end
+ self.buffer = self.buffer..s
+ else
+ return first + self.buffer_start, last + self.buffer_start, capture
+ end
+ end
+end
+
+
+--- Extend the buffer so we can see more
+function file_buffer:extend(offset)
+ local extra = offset - #self.buffer - self.buffer_start
+ if extra > 0 then
+ local size = self.buffer_block_size *
+ math.ceil(extra / self.buffer_block_size)
+ local s = self.file:read(size)
+ if not s then return end
+ self.buffer = self.buffer..s
+ end
+end
+
+
+--- Get a substring from the buffer, extending it if necessary
+function file_buffer:sub(a, b)
+ self:extend(b)
+ b = b == -1 and b or b - self.buffer_start
+ return self.buffer:sub(a - self.buffer_start, b)
+end
+
+
+--- Close a file buffer
+function file_buffer:close()
+ self.file:close()
+ self.file = nil
+end
+
+
+------------------------------------------------------------------------------
+
+local separator_candidates = { ",", "\t", "|" }
+local guess_separator_params = { record_limit = 8; }
+
+
+local function try_separator(buffer, sep, f)
+ guess_separator_params.separator = sep
+ local min, max = math.huge, 0
+ local lines, split_lines = 0, 0
+ local iterator = coroutine.wrap(function() f(buffer, guess_separator_params) end)
+ for t in iterator do
+ min = math.min(min, #t)
+ max = math.max(max, #t)
+ split_lines = split_lines + (t[2] and 1 or 0)
+ lines = lines + 1
+ end
+ if split_lines / lines > 0.75 then
+ return max - min
+ else
+ return math.huge
+ end
+end
+
+
+--- If the user hasn't specified a separator, try to work out what it is.
+function guess_separator(buffer, f)
+ local best_separator, lowest_diff = "", math.huge
+ for _, s in ipairs(separator_candidates) do
+ local ok, diff = pcall(function() return try_separator(buffer, s, f) end)
+ if ok and diff < lowest_diff then
+ best_separator = s
+ lowest_diff = diff
+ end
+ end
+
+ return best_separator
+end
+
+
+local unicode_BOMS =
+{
+ {
+ length = 2,
+ BOMS =
+ {
+ ["\254\255"] = true, -- UTF-16 big-endian
+ ["\255\254"] = true, -- UTF-16 little-endian
+ }
+ },
+ {
+ length = 3,
+ BOMS =
+ {
+ ["\239\187\191"] = true, -- UTF-8
+ }
+ }
+}
+
+
+local function find_unicode_BOM(sub)
+ for _, x in ipairs(unicode_BOMS) do
+ local code = sub(1, x.length)
+ if x.BOMS[code] then
+ return x.length
+ end
+ end
+ return 0
+end
+
+
+--- Iterate through the records in a file
+-- Since records might be more than one line (if there's a newline in quotes)
+-- and line-endings might not be native, we read the file in chunks of
+-- we read the file in chunks using a file_buffer, rather than line-by-line
+-- using io.lines.
+local function separated_values_iterator(buffer, parameters)
+ local field_start = 1
+
+ local advance
+ if buffer.truncate then
+ advance = function(n)
+ field_start = field_start + n
+ buffer:truncate(field_start)
+ end
+ else
+ advance = function(n)
+ field_start = field_start + n
+ end
+ end
+
+
+ local function field_sub(a, b)
+ b = b == -1 and b or b + field_start - 1
+ return buffer:sub(a + field_start - 1, b)
+ end
+
+
+ local function field_find(pattern, init)
+ init = init or 1
+ local f, l, c = buffer:find(pattern, init + field_start - 1)
+ if not f then return end
+ return f - field_start + 1, l - field_start + 1, c
+ end
+
+
+ -- Is there some kind of Unicode BOM here?
+ advance(find_unicode_BOM(field_sub))
+
+
+ -- Start reading the file
+ local sep = "(["..(parameters.separator or
+ guess_separator(buffer, separated_values_iterator)).."\n\r])"
+ local line_start = 1
+ local line = 1
+ local field_count, fields, starts, nonblanks = 0, {}, {}
+ local header, header_read
+ local field_start_line, field_start_column
+ local record_count = 0
+
+
+ local function problem(message)
+ error(("%s:%d:%d: %s"):
+ format(parameters.filename, field_start_line, field_start_column,
+ message), 0)
+ end
+
+
+ while true do
+ local field_end, sep_end, this_sep
+ local tidy
+ field_start_line = line
+ field_start_column = field_start - line_start + 1
+
+ -- If the field is quoted, go find the other quote
+ if field_sub(1, 1) == '"' then
+ advance(1)
+ local current_pos = 0
+ repeat
+ local a, b, c = field_find('"("?)', current_pos + 1)
+ current_pos = b
+ until c ~= '"'
+ if not current_pos then problem("unmatched quote") end
+ tidy = fix_quotes
+ field_end, sep_end, this_sep = field_find(" *([^ ])", current_pos+1)
+ if this_sep and not this_sep:match(sep) then problem("unmatched quote") end
+ else
+ field_end, sep_end, this_sep = field_find(sep, 1)
+ tidy = trim_space
+ end
+
+ -- Look for the separator or a newline or the end of the file
+ field_end = (field_end or 0) - 1
+
+ -- Read the field, then convert all the line endings to \n, and
+ -- count any embedded line endings
+ local value = field_sub(1, field_end)
+ value = value:gsub("\r\n", "\n"):gsub("\r", "\n")
+ for nl in value:gmatch("\n()") do
+ line = line + 1
+ line_start = nl + field_start
+ end
+
+ value = tidy(value)
+ if #value > 0 then nonblanks = true end
+ field_count = field_count + 1
+
+ -- Insert the value into the table for this "line"
+ local key
+ if parameters.column_map and header_read then
+ local ok
+ ok, value, key = pcall(parameters.column_map.transform,
+ parameters.column_map, value, field_count)
+ if not ok then problem(value) end
+ elseif header then
+ key = header[field_count]
+ else
+ key = field_count
+ end
+ if key then
+ fields[key] = value
+ starts[key] = { line=field_start_line, column=field_start_column }
+ end
+
+ -- if we ended on a newline then yield the fields on this line.
+ if not this_sep or this_sep == "\r" or this_sep == "\n" then
+ if parameters.column_map and not header_read then
+ header_read = parameters.column_map:read_header(fields)
+ elseif parameters.header and not header_read then
+ if nonblanks or field_count > 1 then -- ignore blank lines
+ header = fields
+ header_read = true
+ end
+ else
+ if nonblanks or field_count > 1 then -- ignore blank lines
+ coroutine.yield(fields, starts)
+ record_count = record_count + 1
+ if parameters.record_limit and
+ record_count >= parameters.record_limit then
+ break
+ end
+ end
+ end
+ field_count, fields, starts, nonblanks = 0, {}, {}
+ end
+
+ -- If we *really* didn't find a separator then we're done.
+ if not sep_end then break end
+
+ -- If we ended on a newline then count it.
+ if this_sep == "\r" or this_sep == "\n" then
+ if this_sep == "\r" and field_sub(sep_end+1, sep_end+1) == "\n" then
+ sep_end = sep_end + 1
+ end
+ line = line + 1
+ line_start = field_start + sep_end
+ end
+
+ advance(sep_end)
+ end
+end
+
+
+------------------------------------------------------------------------------
+
+local buffer_mt =
+{
+ lines = function(t)
+ return coroutine.wrap(function()
+ separated_values_iterator(t.buffer, t.parameters)
+ end)
+ end,
+ close = function(t)
+ if t.buffer.close then t.buffer:close() end
+ end,
+ name = function(t)
+ return t.parameters.filename
+ end,
+}
+buffer_mt.__index = buffer_mt
+
+
+--- Use an existing file or buffer as a stream to read csv from.
+-- (A buffer is just something that looks like a string in that we can do
+-- `buffer:sub()` and `buffer:find()`)
+-- @return a file object
+local function use(
+ buffer, -- ?string|file|buffer: the buffer to read from. If it's:
+ -- - a string, read from that;
+ -- - a file, turn it into a file_buffer;
+ -- - nil, read from stdin
+ -- otherwise assume it's already a a buffer.
+ parameters) -- ?table: parameters controlling reading the file.
+ -- See README.md
+ parameters = parameters or {}
+ parameters.filename = parameters.filename or "<unknown>"
+ parameters.column_map = parameters.columns and
+ column_map:new(parameters.columns)
+
+ if not buffer then
+ buffer = file_buffer:new(io.stdin)
+ elseif io.type(buffer) == "file" then
+ buffer = file_buffer:new(buffer)
+ end
+
+ local f = { buffer = buffer, parameters = parameters }
+ return setmetatable(f, buffer_mt)
+end
+
+
+------------------------------------------------------------------------------
+
+--- Open a file for reading as a delimited file
+-- @return a file object
+local function open(
+ filename, -- string: name of the file to open
+ parameters) -- ?table: parameters controlling reading the file.
+ -- See README.md
+ local file, message = io.open(filename, "r")
+ if not file then return nil, message end
+
+ parameters = parameters or {}
+ parameters.filename = filename
+ return use(file_buffer:new(file), parameters)
+end
+
+
+------------------------------------------------------------------------------
+
+local function makename(s)
+ local t = {}
+ t[#t+1] = "<(String) "
+ t[#t+1] = (s:gmatch("[^\n]+")() or ""):sub(1,15)
+ if #t[#t] > 14 then t[#t+1] = "..." end
+ t[#t+1] = " >"
+ return table.concat(t)
+end
+
+
+--- Open a string for reading as a delimited file
+-- @return a file object
+local function openstring(
+ filecontents, -- string: The contents of the delimited file
+ parameters) -- ?table: parameters controlling reading the file.
+ -- See README.md
+
+ parameters = parameters or {}
+
+
+ parameters.filename = parameters.filename or makename(filecontents)
+ parameters.buffer_size = parameters.buffer_size or #filecontents
+ return use(filecontents, parameters)
+end
+
+
+------------------------------------------------------------------------------
+
+return { open = open, openstring = openstring, use = use }
+
+------------------------------------------------------------------------------
diff --git a/Data/DefaultContent/Libraries/lua-csv/lua/test.lua b/Data/DefaultContent/Libraries/lua-csv/lua/test.lua
new file mode 100644
index 0000000..f418cf6
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/lua/test.lua
@@ -0,0 +1,102 @@
+pcall(require, "strict")
+local csv = require"csv"
+
+local errors = 0
+
+local function testhandle(handle, correct_result)
+ local result = {}
+ for r in handle:lines() do
+ if not r[1] then
+ local r2 = {}
+ for k, v in pairs(r) do r2[#r2+1] = k..":"..tostring(v) end
+ table.sort(r2)
+ r = r2
+ end
+ result[#result+1] = table.concat(r, ",")
+ end
+
+ handle:close()
+
+ result = table.concat(result, "!\n").."!"
+ if result ~= correct_result then
+ io.stderr:write(
+ ("Error reading '%s':\nExpected output:\n%s\n\nActual output:\n%s\n\n"):
+ format(handle:name(), correct_result, result))
+ errors = errors + 1
+ return false
+ end
+ return true
+end
+
+local function test(filename, correct_result, parameters)
+ parameters = parameters or {}
+ for i = 1, 16 do
+ parameters.buffer_size = i
+ local f = csv.open(filename, parameters)
+ local fileok = testhandle(f, correct_result)
+
+ if fileok then
+ f = io.open(filename, "r")
+ local data = f:read("*a")
+ f:close()
+
+ f = csv.openstring(data, parameters)
+ testhandle(f, correct_result)
+ end
+ end
+end
+
+test("../test-data/embedded-newlines.csv", [[
+embedded
+newline,embedded
+newline,embedded
+newline!
+embedded
+newline,embedded
+newline,embedded
+newline!]])
+
+test("../test-data/embedded-quotes.csv", [[
+embedded "quotes",embedded "quotes",embedded "quotes"!
+embedded "quotes",embedded "quotes",embedded "quotes"!]])
+
+test("../test-data/header.csv", [[
+alpha:ONE,bravo:two,charlie:3!
+alpha:four,bravo:five,charlie:6!]], {header=true})
+
+test("../test-data/header.csv", [[
+apple:one,charlie:30!
+apple:four,charlie:60!]],
+{ columns = {
+ apple = { name = "ALPHA", transform = string.lower },
+ charlie = { transform = function(x) return tonumber(x) * 10 end }}})
+
+test("../test-data/blank-line.csv", [[
+this,file,ends,with,a,blank,line!]])
+
+test("../test-data/BOM.csv", [[
+apple:one,charlie:30!
+apple:four,charlie:60!]],
+{ columns = {
+ apple = { name = "ALPHA", transform = string.lower },
+ charlie = { transform = function(x) return tonumber(x) * 10 end }}})
+
+test("../test-data/bars.txt", [[
+there's a comma in this field, but no newline,embedded
+newline,embedded
+newline!
+embedded
+newline,embedded
+newline,embedded
+newline!]])
+
+
+if errors == 0 then
+ io.stdout:write("Passed\n")
+elseif errors == 1 then
+ io.stdout:write("1 error\n")
+else
+ io.stdout:write(("%d errors\n"):format(errors))
+end
+
+os.exit(errors)
diff --git a/Data/DefaultContent/Libraries/lua-csv/makefile b/Data/DefaultContent/Libraries/lua-csv/makefile
new file mode 100644
index 0000000..dfa7596
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/makefile
@@ -0,0 +1,14 @@
+LUA= $(shell echo `which lua`)
+LUA_BINDIR= $(shell echo `dirname $(LUA)`)
+LUA_PREFIX= $(shell echo `dirname $(LUA_BINDIR)`)
+LUA_VERSION = $(shell echo `lua -v 2>&1 | cut -d " " -f 2 | cut -b 1-3`)
+LUA_SHAREDIR=$(LUA_PREFIX)/share/lua/$(LUA_VERSION)
+
+default:
+ @echo "Nothing to build. Try 'make install' or 'make test'."
+
+install:
+ cp lua/csv.lua $(LUA_SHAREDIR)
+
+test:
+ cd lua && $(LUA) test.lua
diff --git a/Data/DefaultContent/Libraries/lua-csv/rockspecs/csv-1-1.rockspec b/Data/DefaultContent/Libraries/lua-csv/rockspecs/csv-1-1.rockspec
new file mode 100644
index 0000000..6f280aa
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/rockspecs/csv-1-1.rockspec
@@ -0,0 +1,24 @@
+package = "csv"
+version = "1-1"
+source =
+{
+ url = "git://github.com/geoffleyland/lua-csv.git",
+ branch = "master",
+ tag = "v1",
+}
+description =
+{
+ summary = "CSV and other delimited file reading",
+ homepage = "http://github.com/geoffleyland/lua-csv",
+ license = "MIT/X11",
+ maintainer = "Geoff Leyland <geoff.leyland@incremental.co.nz>"
+}
+dependencies = { "lua >= 5.1" }
+build =
+{
+ type = "builtin",
+ modules =
+ {
+ csv = "lua/csv.lua",
+ },
+}
diff --git a/Data/DefaultContent/Libraries/lua-csv/rockspecs/csv-scm-1.rockspec b/Data/DefaultContent/Libraries/lua-csv/rockspecs/csv-scm-1.rockspec
new file mode 100644
index 0000000..29629da
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/rockspecs/csv-scm-1.rockspec
@@ -0,0 +1,23 @@
+package = "csv"
+version = "scm-1"
+source =
+{
+ url = "git://github.com/geoffleyland/lua-csv.git",
+ branch = "master",
+}
+description =
+{
+ summary = "CSV and other delimited file reading",
+ homepage = "http://github.com/geoffleyland/lua-csv",
+ license = "MIT/X11",
+ maintainer = "Geoff Leyland <geoff.leyland@incremental.co.nz>"
+}
+dependencies = { "lua >= 5.1" }
+build =
+{
+ type = "builtin",
+ modules =
+ {
+ csv = "lua/csv.lua",
+ },
+}
diff --git a/Data/DefaultContent/Libraries/lua-csv/test-data/BOM.csv b/Data/DefaultContent/Libraries/lua-csv/test-data/BOM.csv
new file mode 100644
index 0000000..9787c0d
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/test-data/BOM.csv
@@ -0,0 +1,3 @@
+alpha,bravo,charlie
+ONE,two,3
+four,five,6 \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/lua-csv/test-data/bars.txt b/Data/DefaultContent/Libraries/lua-csv/test-data/bars.txt
new file mode 100644
index 0000000..9decabc
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/test-data/bars.txt
@@ -0,0 +1,7 @@
+there's a comma in this field, but no newline|"embedded
+newline"|"embedded
+newline"
+"embedded
+newline"|"embedded
+newline"|"embedded
+newline" \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/lua-csv/test-data/blank-line.csv b/Data/DefaultContent/Libraries/lua-csv/test-data/blank-line.csv
new file mode 100644
index 0000000..63fc515
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/test-data/blank-line.csv
@@ -0,0 +1,2 @@
+this,file,ends,with,a,blank,line
+
diff --git a/Data/DefaultContent/Libraries/lua-csv/test-data/embedded-newlines.csv b/Data/DefaultContent/Libraries/lua-csv/test-data/embedded-newlines.csv
new file mode 100644
index 0000000..67987d1
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/test-data/embedded-newlines.csv
@@ -0,0 +1,8 @@
+"embedded
+newline","embedded
+newline","embedded
+newline"
+"embedded
+newline","embedded
+newline","embedded
+newline" \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/lua-csv/test-data/embedded-quotes.csv b/Data/DefaultContent/Libraries/lua-csv/test-data/embedded-quotes.csv
new file mode 100644
index 0000000..e0c5c73
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/test-data/embedded-quotes.csv
@@ -0,0 +1,2 @@
+"embedded ""quotes""","embedded ""quotes""","embedded ""quotes"""
+"embedded ""quotes""","embedded ""quotes""","embedded ""quotes""" \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/lua-csv/test-data/header.csv b/Data/DefaultContent/Libraries/lua-csv/test-data/header.csv
new file mode 100644
index 0000000..89f702e
--- /dev/null
+++ b/Data/DefaultContent/Libraries/lua-csv/test-data/header.csv
@@ -0,0 +1,3 @@
+alpha,bravo,charlie
+ONE,two,3
+four,five,6 \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/luafun/.gitignore b/Data/DefaultContent/Libraries/luafun/.gitignore
new file mode 100644
index 0000000..0ebe4e1
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/.gitignore
@@ -0,0 +1,4 @@
+*~
+temp/
+fun.lua.c
+5.?-fun/
diff --git a/Data/DefaultContent/Libraries/luafun/.travis.yml b/Data/DefaultContent/Libraries/luafun/.travis.yml
new file mode 100644
index 0000000..2c3f4d8
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/.travis.yml
@@ -0,0 +1,74 @@
+sudo: false
+language: C
+services:
+ - docker
+
+env:
+ global:
+ - PRODUCT=lua-fun
+ matrix:
+ - OS=el DIST=7
+ - OS=fedora DIST=24
+ - OS=fedora DIST=25
+ - OS=ubuntu DIST=xenial
+ - OS=ubuntu DIST=yakkety
+ - OS=debian DIST=stretch
+
+before_deploy:
+ - git clone https://github.com/packpack/packpack.git packpack
+ - ./packpack/packpack
+
+deploy:
+ provider: packagecloud
+ username: ${PACKAGECLOUD_USER}
+ repository: ${PACKAGECLOUD_REPO}
+ token: ${PACKAGECLOUD_TOKEN}
+ dist: ${OS}/${DIST}
+ package_glob: build/*.{deb,rpm}
+ skip_cleanup: true
+ on:
+ branch: master
+ condition: -n "${OS}" && -n "${DIST}" && -n "${PACKAGECLOUD_TOKEN}"
+
+after_deploy:
+ # Prune old packages from PackageCloud, keep only the last two
+ - pip install -r ./packpack/tools/requirements.txt
+ - python ./packpack/tools/packagecloud prune ${PACKAGECLOUD_USER}/${PACKAGECLOUD_REPO} deb ${OS} ${DIST} --keep 2
+ - python ./packpack/tools/packagecloud prune ${PACKAGECLOUD_USER}/${PACKAGECLOUD_REPO} rpm ${OS} ${DIST} --keep 2
+
+cache:
+ directories:
+ - $HOME/lua-5.3.2
+
+addons:
+ apt:
+ packages:
+ - lua5.1
+ - lua5.2
+ - luajit
+
+# Ubuntu Precise on Travis doesn't have lua5.3 package
+install:
+ - |
+ [ -e ${HOME}/lua-5.3.2/src/lua ] || (\
+ wget http://www.lua.org/ftp/lua-5.3.2.tar.gz -c && \
+ tar xzf lua-5.3.2.tar.gz -C ${HOME} && \
+ make -j -C ${HOME}/lua-5.3.2 linux \
+ )
+
+script:
+ - cd tests
+ - LUAJIT=`echo /usr/bin/luajit* | cut -f 1 -d ' '`
+ - ${LUAJIT} -v
+ - ${LUAJIT} runtest *.lua
+ - lua5.1 -v
+ - lua5.1 runtest *.lua
+ - lua5.2 -v
+ - lua5.2 runtest *.lua
+ - LUA53=${HOME}/lua-5.3.2/src/lua
+ - ${LUA53} -v
+ - ${LUA53} runtest *.lua
+ - cd ..
+
+notifications:
+ email: true
diff --git a/Data/DefaultContent/Libraries/luafun/CONTRIBUTING.md b/Data/DefaultContent/Libraries/luafun/CONTRIBUTING.md
new file mode 100644
index 0000000..660ec53
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/CONTRIBUTING.md
@@ -0,0 +1,20 @@
+Contributing
+============
+
+We'd love for you to contribute to the project and make **Lua Fun** even better
+than it is today!
+
+Filling Issues
+---------------
+
+Please file bugs reports and feature requests using [GitHub Issues].
+
+[GitHub Issues]: https://github.com/luafun/luafun/issues
+
+Making Changes
+--------------
+
+If you want to contribute code, please fork the project on [GitHub], make
+changes in branch and send a pull request.
+
+[GitHub]: https://github.com/luafun/luafun
diff --git a/Data/DefaultContent/Libraries/luafun/COPYING.md b/Data/DefaultContent/Libraries/luafun/COPYING.md
new file mode 100644
index 0000000..c945d62
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/COPYING.md
@@ -0,0 +1,27 @@
+Copying
+=======
+
+**Lua Fun** source codes, logo and documentation are distributed under the
+**[MIT/X11 License]** - same as Lua and LuaJIT.
+
+Copyright (c) 2013-2017 Roman Tsisyk <roman@tsisyk.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+[MIT/X11 License]: http://www.opensource.org/licenses/mit-license.php
diff --git a/Data/DefaultContent/Libraries/luafun/README.md b/Data/DefaultContent/Libraries/luafun/README.md
new file mode 100644
index 0000000..c7a2d61
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/README.md
@@ -0,0 +1,107 @@
+Lua Functional
+==============
+
+<img src="/doc/logo.png" align="right" width="174px" height="144px" />
+
+**Lua Fun** is a high-performance functional programming library for [Lua]
+designed with [LuaJIT's trace compiler][LuaJIT] in mind.
+
+Lua Fun provides a set of more than 50 programming primitives typically
+found in languages like Standard ML, Haskell, Erlang, JavaScript, Python and
+even Lisp. High-order functions such as ``map``, ``filter``, ``reduce``,
+``zip``, etc., make it easy to **write simple and efficient functional code**.
+
+Let's see an example:
+
+ > -- Functional style
+ > require "fun" ()
+ > -- calculate sum(x for x^2 in 1..n)
+ > n = 100
+ > print(reduce(operator.add, 0, map(function(x) return x^2 end, range(n))))
+ 328350
+
+ > -- Object-oriented style
+ > local fun = require "fun"
+ > -- calculate sum(x for x^2 in 1..n)
+ > print(fun.range(n):map(function(x) return x^2 end):reduce(operator.add, 0))
+ 328350
+
+**Lua Fun** takes full advantage of the innovative **tracing JIT compiler**
+to achieve transcendental performance on nested functional expressions.
+Functional compositions and high-order functions can be translated into
+**efficient machine code**. Can you believe it? Just try to run the example
+above with ``luajit -jdump`` and see what happens:
+
+ -- skip some initilization code --
+ ->LOOP:
+ 0bcaffd0 movaps xmm5, xmm7
+ 0bcaffd3 movaps xmm7, xmm1
+ 0bcaffd6 addsd xmm7, xmm5
+ 0bcaffda ucomisd xmm7, xmm0
+ 0bcaffde jnb 0x0bca0024 ->5
+ 0bcaffe4 movaps xmm5, xmm7
+ 0bcaffe7 mulsd xmm5, xmm5
+ 0bcaffeb addsd xmm6, xmm5
+ 0bcaffef jmp 0x0bcaffd0 ->LOOP
+ ---- TRACE 1 stop -> loop
+
+The functional chain above was translated by LuaJIT to (!) **one machine loop**
+containing just 10 CPU assembly instructions without CALL. Unbelievable!
+
+Readable? Efficient? Can your Python/Ruby/V8 do better?
+
+Status
+------
+
+**Lua Fun** is in an early alpha stage. The library fully [documented]
+[Documentation] and covered with unit tests.
+
+[![Build Status](https://travis-ci.org/luafun/luafun.png)]
+(https://travis-ci.org/luafun/luafun)
+
+LuaJIT 2.1 alpha is recommended. The library designed in mind of fact that
+[LuaJIT traces tail-, up- and down-recursion][LuaJIT-Recursion] and has a lot of
+[byte code optimizations][LuaJIT-Optimizations]. Lua 5.1-5.3 are also
+supported.
+
+This is **master** (development) branch. API may be changed without any special
+notice. Please use **stable** branch for your production deployments.
+If you still want to use **master**, please don't forget to grep `git log`
+for *Incompatible API changes* message. Thanks!
+
+Please check out [documentation][Documentation] for more information.
+
+Misc
+----
+
+**Lua Fun** is distributed under the [MIT/X11 License] -
+(same as Lua and LuaJIT).
+
+The library was written to use with [Tarantool] - an efficient in-memory
+store and an asynchronous Lua application server.
+
+See Also
+--------
+
+* [Documentation]
+* [RockSpec]
+* [RPM/DEB packages](https://packagecloud.io/rtsisyk/master)
+* lua-l@lists.lua.org
+* luajit@freelists.org
+* roman@tsisyk.com
+
+ [Lua]: http://www.lua.org/
+ [LuaJIT]: http://luajit.org/luajit.html
+ [LuaJIT-Recursion]: http://lambda-the-ultimate.org/node/3851#comment-57679
+ [LuaJIT-Optimizations]: http://wiki.luajit.org/Optimizations
+ [MIT/X11 License]: http://opensource.org/licenses/MIT
+ [Tarantool]: http://github.com/tarantool/tarantool
+ [Getting Started]: https://luafun.github.io/getting_started.html
+ [Documentation]: http://luafun.github.io/
+ [RockSpec]: https://raw.github.com/luafun/luafun/master/fun-scm-1.rockspec
+
+Please **"Star"** the project on GitHub to help it to survive! Thanks!
+
+*****
+
+**Lua Fun**. Simple, Efficient and Functional. In Lua. With JIT.
diff --git a/Data/DefaultContent/Libraries/luafun/debian/.gitignore b/Data/DefaultContent/Libraries/luafun/debian/.gitignore
new file mode 100644
index 0000000..aa3e6bf
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/debian/.gitignore
@@ -0,0 +1,8 @@
+lua-fun/
+tmp/
+trash
+files
+lua_versions
+*.install
+*.substvars
+*.log
diff --git a/Data/DefaultContent/Libraries/luafun/debian/changelog b/Data/DefaultContent/Libraries/luafun/debian/changelog
new file mode 100644
index 0000000..262c02d
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/debian/changelog
@@ -0,0 +1,5 @@
+lua-fun (0.1.3-1) unstable; urgency=medium
+
+ * Initial release. (Closes: #811482)
+
+ -- Roman Tsisyk <roman@tarantool.org> Mon, 18 Jan 2016 10:00:00 +0300
diff --git a/Data/DefaultContent/Libraries/luafun/debian/compat b/Data/DefaultContent/Libraries/luafun/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/Data/DefaultContent/Libraries/luafun/debian/control b/Data/DefaultContent/Libraries/luafun/debian/control
new file mode 100644
index 0000000..f93b318
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/debian/control
@@ -0,0 +1,20 @@
+Source: lua-fun
+Section: interpreters
+Priority: optional
+Maintainer: Roman Tsisyk <roman@tarantool.org>
+Build-Depends: debhelper (>= 9), dh-lua (>= 19)
+Standards-Version: 3.9.6
+Homepage: https://github.com/luafun/luafun
+Vcs-Git: git://github.com/luafun/luafun.git
+Vcs-Browser: https://github.com/luafun/luafun
+
+Package: lua-fun
+Architecture: all
+Depends: ${misc:Depends}
+Provides: ${lua:Provides}
+XB-Lua-Versions: ${lua:Versions}
+Description: High-performance functional programming library for Lua
+ Lua Fun provides a set of more than 50 programming primitives typically
+ found in languages like Standard ML, Haskell, Erlang, JavaScript, Python and
+ even Lisp. High-order functions such as map, filter, reduce, zip, etc.,
+ make it easy to write simple and efficient functional code.
diff --git a/Data/DefaultContent/Libraries/luafun/debian/copyright b/Data/DefaultContent/Libraries/luafun/debian/copyright
new file mode 100644
index 0000000..34f24ad
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/debian/copyright
@@ -0,0 +1,31 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: luafun
+Upstream-Contact: Roman Tsisyk <roman@tsisyk.com>
+Source: https://github.com/luafun/luafun
+
+Files: *
+Copyright: 2013-2017 Roman Tsisyk <roman@tsisyk.com>
+Comment: In the Lua community this license is better known as "MIT".
+ Unfortunately other variants of this license are also known as "MIT".
+ To obtain a machine intepretable copyright file Debian prefers to name this
+ version of the MIT license using the non ambiguous term "Expat".
+License: Expat
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ “Softwareâ€), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ .
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ .
+ THE SOFTWARE IS PROVIDED “AS ISâ€, WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
diff --git a/Data/DefaultContent/Libraries/luafun/debian/lua-fun.docs b/Data/DefaultContent/Libraries/luafun/debian/lua-fun.docs
new file mode 100644
index 0000000..b43bf86
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/debian/lua-fun.docs
@@ -0,0 +1 @@
+README.md
diff --git a/Data/DefaultContent/Libraries/luafun/debian/lua5.1.dh-lua.conf b/Data/DefaultContent/Libraries/luafun/debian/lua5.1.dh-lua.conf
new file mode 100644
index 0000000..fa57bb6
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/debian/lua5.1.dh-lua.conf
@@ -0,0 +1,4 @@
+PKG_NAME=fun
+LUA_MODNAME=fun
+LUA_SOURCES=fun.lua
+LUA_TEST=tests/runtest tests/*.lua
diff --git a/Data/DefaultContent/Libraries/luafun/debian/lua5.2.dh-lua.conf b/Data/DefaultContent/Libraries/luafun/debian/lua5.2.dh-lua.conf
new file mode 100644
index 0000000..ba875b6
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/debian/lua5.2.dh-lua.conf
@@ -0,0 +1 @@
+lua5.1.dh-lua.conf \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/luafun/debian/lua5.3.dh-lua.conf b/Data/DefaultContent/Libraries/luafun/debian/lua5.3.dh-lua.conf
new file mode 100644
index 0000000..ba875b6
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/debian/lua5.3.dh-lua.conf
@@ -0,0 +1 @@
+lua5.1.dh-lua.conf \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/luafun/debian/patches/series b/Data/DefaultContent/Libraries/luafun/debian/patches/series
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/debian/patches/series
diff --git a/Data/DefaultContent/Libraries/luafun/debian/rules b/Data/DefaultContent/Libraries/luafun/debian/rules
new file mode 100644
index 0000000..9e473ed
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/debian/rules
@@ -0,0 +1,12 @@
+#!/usr/bin/make -f
+
+VERSION := $(shell dpkg-parsechangelog|grep ^Version|awk '{print $$2}')
+UVERSION := $(shell echo $(VERSION)|sed 's/-[[:digit:]]\+$$//')
+
+%:
+ dh $@ --buildsystem=lua --with lua
+
+tarball: clean
+ tar --exclude=.git --exclude=debian --exclude rpm \
+ --transform='s,^\.,luafun-$(UVERSION),S' \
+ -czf ../luafun-$(UVERSION).orig.tar.gz .
diff --git a/Data/DefaultContent/Libraries/luafun/debian/source/format b/Data/DefaultContent/Libraries/luafun/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/Data/DefaultContent/Libraries/luafun/debian/watch b/Data/DefaultContent/Libraries/luafun/debian/watch
new file mode 100644
index 0000000..40bc2ca
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/debian/watch
@@ -0,0 +1,6 @@
+# test this watch file using:
+# uscan --watchfile debian/watch --upstream-version 0.0.1 --package lua-fun
+# https://wiki.debian.org/debian/watch#GitHub
+version=3
+opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/luafun-$1\.tar\.gz/ \
+ https://github.com/luafun/luafun/tags .*/v?(\d\S*)\.tar\.gz
diff --git a/Data/DefaultContent/Libraries/luafun/doc/.gitignore b/Data/DefaultContent/Libraries/luafun/doc/.gitignore
new file mode 100644
index 0000000..e35d885
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/.gitignore
@@ -0,0 +1 @@
+_build
diff --git a/Data/DefaultContent/Libraries/luafun/doc/Makefile b/Data/DefaultContent/Libraries/luafun/doc/Makefile
new file mode 100644
index 0000000..1e1b049
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/Makefile
@@ -0,0 +1,153 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/LuaFunctional.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/LuaFunctional.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/LuaFunctional"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/LuaFunctional"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/Data/DefaultContent/Libraries/luafun/doc/_static/.keep b/Data/DefaultContent/Libraries/luafun/doc/_static/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/_static/.keep
diff --git a/Data/DefaultContent/Libraries/luafun/doc/_templates/layout.html b/Data/DefaultContent/Libraries/luafun/doc/_templates/layout.html
new file mode 100644
index 0000000..ee1fa29
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/_templates/layout.html
@@ -0,0 +1,14 @@
+{% extends "!layout.html" %}
+
+{% block footer %}
+{{ super() }}
+ <script type="text/javascript">
+(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
+
+ga('create', 'UA-45899190-2', 'auto');
+ga('send', 'pageview');
+ </script>
+{% endblock %}
diff --git a/Data/DefaultContent/Libraries/luafun/doc/about.rst b/Data/DefaultContent/Libraries/luafun/doc/about.rst
new file mode 100644
index 0000000..97da8dc
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/about.rst
@@ -0,0 +1,42 @@
+About
+=====
+
+Credits
+-------
+
+An initial prototype was designed and enginered in one evening by Roman Tsisyk.
+After that the library was completely rewritten, tested and documented
+(which took a while).
+
+The project exists only thanks to the excellent tracing just-in-time compiler
+in `LuaJIT <http://luajit.org>`_.
+
+The library works best with `Tarantool <http://tarantool.org>`_ --
+an efficient in-memory database and Lua application server.
+
+Copying
+-------
+
+Lua Fun source codes, logo and documentation are distributed under the
+`MIT License (MIT) <http://www.opensource.org/licenses/mit-license.php>`_ --
+same as LuaJIT.
+
+Copyright (c) 2013-2017 Roman Tsisyk <roman@tsisyk.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/Data/DefaultContent/Libraries/luafun/doc/basic.rst b/Data/DefaultContent/Libraries/luafun/doc/basic.rst
new file mode 100644
index 0000000..346dd78
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/basic.rst
@@ -0,0 +1,141 @@
+Basic Functions
+===============
+
+.. module:: fun
+
+The section contains functions to create iterators from Lua objects.
+
+.. function:: iter(array)
+ iter(map)
+ iter(string)
+ iter(gen, param, state)
+
+ :returns: ``gen, param, state`` -- :ref:`iterator triplet <iterator_triplet>`
+
+ Make ``gen, param, state`` iterator from the iterable object.
+ The function is a generalized version of :func:`pairs` and :func:`ipairs`.
+
+ The function distinguish between arrays and maps using ``#arg == 0``
+ check to detect maps. For arrays ``ipairs`` is used. For maps a modified
+ version of ``pairs`` is used that also returns keys. Userdata objects
+ are handled in the same way as tables.
+
+ If ``LUAJIT_ENABLE_LUA52COMPAT`` [#luajit_lua52compat]_ mode is enabled and
+ argument has metamethods ``__pairs`` (for maps) or ``__ipairs`` for (arrays),
+ call it with the table or userdata as argument and return the first three
+ results from the call [#lua52_ipairs]_.
+
+ All library iterator are suitable to use with Lua's ``for .. in`` loop.
+
+ .. code-block:: lua
+
+ > for _it, a in iter({1, 2, 3}) do print(a) end
+ 1
+ 2
+ 3
+
+ > for _it, k, v in iter({ a = 1, b = 2, c = 3}) do print(k, v) end
+ b 2
+ a 1
+ c 3
+
+ > for _it, a in iter("abcde") do print(a) end
+ a
+ b
+ c
+ d
+ e
+
+ The first cycle variable *_it* is needed to store an internal state of
+ the iterator. The value must be always ignored in loops:
+
+ .. code-block:: lua
+
+ for _it, a, b in iter({ a = 1, b = 2, c = 3}) do print(a, b) end
+ -- _it is some internal iterator state - always ignore it
+ -- a, b are values return from the iterator
+
+ Simple iterators like ``iter({1, 2, 3})`` have simple states, whereas
+ other iterators like :func:`zip` or :func:`chain` have complicated
+ internal states which values senseless for the end user.
+
+ Check out :doc:`under_the_hood` section for more details.
+
+ There is also the possibility to supply custom iterators to the
+ function:
+
+ .. code-block:: lua
+
+ > local function mypairs_gen(max, state)
+ if (state >= max) then
+ return nil
+ end
+ return state + 1, state + 1
+ end
+
+ > local function mypairs(max)
+ return mypairs_gen, max, 0
+ end
+
+ > for _it, a in iter(mypairs(10)) do print(a) end
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+
+ Iterators can return multiple values.
+
+ Check out :doc:`under_the_hood` section for more details.
+
+ .. [#luajit_lua52compat] http://luajit.org/extensions.html
+ .. [#lua52_ipairs] http://www.lua.org/manual/5.2/manual.html#pdf-ipairs
+
+.. function:: each(fun, gen, param, state)
+ iterator:each(fun)
+
+ :returns: none
+
+ Execute the *fun* for each iteration value. The function is equivalent to
+ the code below:
+
+ .. code-block:: lua
+
+ for _it, ... in iter(gen, param, state) do
+ fun(...)
+ end
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, { a = 1, b = 2, c = 3})
+ b 2
+ a 1
+ c 3
+
+ > each(print, {1, 2, 3})
+ 1
+ 2
+ 3
+
+ The function is used for its side effects. Implementation directly applies
+ *fun* to all iteration values without returning a new iterator, in contrast
+ to functions like :func:`map`.
+
+ .. seealso:: :func:`map`, :func:`reduce`
+
+.. function:: for_each(fun, gen, param, state)
+ iterator:for_each(fun)
+
+ An alias for :func:`each`.
+
+.. function:: foreach(fun, gen, param, state)
+ iterator:foreach(fun)
+
+ An alias for :func:`each`.
diff --git a/Data/DefaultContent/Libraries/luafun/doc/compositions.rst b/Data/DefaultContent/Libraries/luafun/doc/compositions.rst
new file mode 100644
index 0000000..4c789b3
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/compositions.rst
@@ -0,0 +1,140 @@
+Compositions
+============
+
+.. module:: fun
+
+.. function:: zip(...)
+ iterator1:zip(iterator2, iterator3, ...)
+
+ :param ...: iterators to "zip"
+ :type ...: iterator
+
+ :returns: an iterator
+
+ Return a new iterator where i-th return value contains the i-th element
+ from each of the iterators. The returned iterator is truncated in length
+ to the length of the shortest iterator. For multi-return iterators only the
+ first variable is used.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > dump(zip({"a", "b", "c", "d"}, {"one", "two", "three"}))
+ a one
+ b two
+ c three
+
+ > each(print, zip())
+
+ > each(print, zip(range(5), {'a', 'b', 'c'}, rands()))
+ 1 a 0.57514179487402
+ 2 b 0.79693061238668
+ 3 c 0.45174307459403
+
+ > each(print, zip(partition(function(x) return x > 7 end, range(1, 15, 1))))
+ 8 1
+ 9 2
+ 10 3
+ 11 4
+ 12 5
+ 13 6
+ 14 7
+
+.. function:: cycle(gen, param, state)
+ iterator:cycle()
+
+ :returns: a cycled version of ``{gen, param, state}`` iterator
+
+ Make a new iterator that returns elements from ``{gen, param, state}``
+ iterator until the end and then "restart" iteration using a saved clone of
+ ``{gen, param, state}``. The returned iterator is constant space and no
+ return values are buffered. Instead of that the function make a clone of the
+ source ``{gen, param, state}`` iterator. Therefore, the source iterator
+ must be pure functional to make an indentical clone. Infinity iterators
+ are supported, but are not recommended.
+
+ .. note:: ``{gen, param, state}`` must be pure functional to work properly
+ with the function.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, take(15, cycle(range(5))))
+ 1
+ 2
+ 3
+ 4
+ 5
+ 1
+ 2
+ 3
+ 4
+ 5
+ 1
+ 2
+ 3
+ 4
+ 5
+
+ > each(print, take(15, cycle(zip(range(5), {"a", "b", "c", "d", "e"}))))
+ 1 a
+ 2 b
+ 3 c
+ 4 d
+ 5 e
+ 1 a
+ 2 b
+ 3 c
+ 4 d
+ 5 e
+ 1 a
+ 2 b
+ 3 c
+ 4 d
+ 5 e
+
+.. function:: chain(...)
+ iterator1:chain(iterator2, iterator3, ...)
+
+ :param ...: iterators to chain
+ :type ...: iterator
+ :returns: a consecutive iterator from sources (left from right)
+
+ Make an iterator that returns elements from the first iterator until it is
+ exhausted, then proceeds to the next iterator, until all of the iterators
+ are exhausted. Used for treating consecutive iterators as a single iterator.
+ Infinity iterators are supported, but are not recommended.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, chain(range(2), {"a", "b", "c"}, {"one", "two", "three"}))
+ 1
+ 2
+ a
+ b
+ c
+ one
+ two
+ three
+
+ > each(print, take(15, cycle(chain(enumerate({"a", "b", "c"}),
+ {"one", "two", "three"}))))
+ 1 a
+ 2 b
+ 3 c
+ one
+ two
+ three
+ 1 a
+ 2 b
+ 3 c
+ one
+ two
+ three
+ 1 a
+ 2 b
+ 3 c
diff --git a/Data/DefaultContent/Libraries/luafun/doc/conf.py b/Data/DefaultContent/Libraries/luafun/doc/conf.py
new file mode 100644
index 0000000..ce36bbf
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/conf.py
@@ -0,0 +1,247 @@
+# -*- coding: utf-8 -*-
+#
+# Lua Functional documentation build configuration file, created by
+# sphinx-quickstart on Sat Nov 9 14:21:28 2013.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+#extensions = [ "redjack.sphinx.lua" ]
+
+# The documentation primary domain is lua
+#primary_domain = "lua"
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Lua Functional'
+copyright = u'2013-2017, Roman Tsisyk'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.1'
+# The full version, including alpha/beta/rc tags.
+release = '0.1.3'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'haiku'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {
+ #"full_logo": False,
+#}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+html_logo = "logo.png"
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+#htmlhelp_basename = 'LuaFunctionaldoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+#latex_documents = [
+ #('index', 'LuaFunctional.tex', u'Lua Functional Documentation',
+ #u'Roman Tsisyk', 'manual'),
+#]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'luafun', u'Lua Functional Documentation',
+ [u'Roman Tsisyk'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+#texinfo_documents = [
+ #('index', 'LuaFunctional', u'Lua Functional Documentation',
+ #u'Roman Tsisyk', 'LuaFunctional', 'One line description of project.',
+ #'Miscellaneous'),
+#]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
diff --git a/Data/DefaultContent/Libraries/luafun/doc/filtering.rst b/Data/DefaultContent/Libraries/luafun/doc/filtering.rst
new file mode 100644
index 0000000..2852f6c
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/filtering.rst
@@ -0,0 +1,121 @@
+Filtering
+=========
+
+.. module:: fun
+
+This section contains functions to filter values during iteration.
+
+.. function:: filter(predicate, gen, param, state)
+ iterator:filter(predicate)
+
+ :param param: an predicate to filter the iterator
+ :type param: (function(...) -> bool)
+
+ Return a new iterator of those elements that satisfy the **predicate**.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, filter(function(x) return x % 3 == 0 end, range(10)))
+ 3
+ 6
+ 9
+
+ > each(print, take(5, filter(function(i, x) return i % 3 == 0 end,
+ enumerate(duplicate('x')))))
+ 3 x
+ 6 x
+ 9 x
+ 12 x
+ 15 x
+
+ .. note:: Multireturn iterators are supported but can cause performance
+ regressions.
+
+ .. seealso:: :func:`take_while` and :func:`drop_while`.
+
+.. function:: remove_if(predicate, gen, param, state)
+ iterator:remove_if(predicate)
+
+ An alias for :func:`filter`.
+
+.. function:: grep(regexp_or_predicate, gen, param, state)
+ iterator:grep(regexp_or_predicate)
+
+ If **regexp_or_predicate** is string then the parameter is used as a regular
+ expression to build filtering predicate. Otherwise the function is just an
+ alias for :func:`filter`.
+
+ Equivalent to:
+
+ .. code-block:: lua
+
+ local fun = regexp_or_predicate
+ if type(regexp_or_predicate) == "string" then
+ fun = function(x) return string.find(x, regexp_or_predicate) ~= nil end
+ end
+ return filter(fun, gen, param, state)
+
+ Examples:
+
+ .. code-block:: lua
+
+ lines_to_grep = {
+ [[Emily]],
+ [[Chloe]],
+ [[Megan]],
+ [[Jessica]],
+ [[Emma]],
+ [[Sarah]],
+ [[Elizabeth]],
+ [[Sophie]],
+ [[Olivia]],
+ [[Lauren]]
+ }
+
+ each(print, grep("^Em", lines_to_grep))
+ --[[test
+ Emily
+ Emma
+ --test]]
+
+ each(print, grep("^P", lines_to_grep))
+ --[[test
+ --test]]
+
+ > each(print, grep(function(x) return x % 3 == 0 end, range(10)))
+ 3
+ 6
+ 9
+
+.. function:: partition(predicate, gen, param, state)
+ iterator:partition(predicate)
+
+ :param x: a value to find
+ :returns: {gen1, param1, state1}, {gen2, param2, state2}
+
+ The function returns two iterators where elements do and do not satisfy the
+ prediucate. Equivalent to:
+
+ .. code-block:: lua
+
+ return filter(predicate, gen', param', state'),
+ filter(function(...) return not predicate(...) end, gen, param, state);
+
+ The function make a clone of the source iterator. Iterators especially
+ returned in tables to work with :func:`zip` and other functions.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, zip(partition(function(i, x) return i % 3 == 0 end, range(10))))
+ 3 1
+ 6 2
+ 9 4
+
+ .. note:: ``gen, param, state`` must be pure functional to work properly
+ with the function.
+
+ .. seealso:: :func:`span`
diff --git a/Data/DefaultContent/Libraries/luafun/doc/generators.rst b/Data/DefaultContent/Libraries/luafun/doc/generators.rst
new file mode 100644
index 0000000..7132d47
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/generators.rst
@@ -0,0 +1,233 @@
+Generators
+==========
+
+.. module:: fun
+
+This section contains a number of useful generators modeled after Standard ML,
+Haskell, Python, Ruby, JavaScript and other languages.
+
+Finite Generators
+-----------------
+
+.. function:: range([start,] stop[, step])
+
+ :param start: an endpoint of the interval (see below)
+ :type start: number
+ :param stop: an endpoint of the interval (see below)
+ :type stop: number
+ :param step: a step
+ :type step: number
+
+ :returns: an iterator
+
+ The iterator to create arithmetic progressions. Iteration values are generated
+ within closed interval ``[start, stop]`` (i.e. *stop* is included).
+ If the *start* argument is omitted, it defaults to ``1`` (*stop* > 0) or
+ to ``-1`` (*stop* < 0). If the *step* argument is omitted, it defaults to
+ ``1`` (*start* <= *stop*) or to ``-1`` (*start* > *stop*). If *step* is
+ positive, the last element is the largest ``start + i * step`` less than or
+ equal to *stop*; if *step* is negative, the last element is the smallest
+ ``start + i * step`` greater than or equal to *stop*.
+ *step* must not be zero (or else an error is raised).
+ ``range(0)`` returns empty iterator.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > for _it, v in range(5) do print(v) end
+ 1
+ 2
+ 3
+ 4
+ 5
+ > for _it, v in range(-5) do print(v) end
+ -1
+ -2
+ -3
+ -4
+ -5
+ > for _it, v in range(1, 6) do print(v) end
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ > for _it, v in range(0, 20, 5) do print(v) end
+ 0
+ 5
+ 10
+ 15
+ 20
+ > for _it, v in range(0, 10, 3) do print(v) end
+ 0
+ 3
+ 6
+ 9
+ > for _it, v in range(0, 1.5, 0.2) do print(v) end
+ 0
+ 0.2
+ 0.4
+ 0.6
+ 0.8
+ 1
+ 1.2
+ 1.4
+ > for _it, v in range(0) do print(v) end
+ > for _it, v in range(1) do print(v) end
+ 1
+ > for _it, v in range(1, 0) do print(v) end
+ 1
+ 0
+ > for _it, v in range(0, 10, 0) do print(v) end
+ error: step must not be zero
+
+Infinity Generators
+-------------------
+
+.. function:: duplicate(...)
+
+ :param ...: objects to duplicate
+ :type ...: non nil
+ :returns: an iterator
+
+ The iterator returns values over and over again indefinitely. All values
+ that passed to the iterator are returned as-is during the iteration.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, take(3, duplicate('a', 'b', 'c')))
+ a b c
+ a b c
+ > each(print, take(3, duplicate('x')))
+ x
+ x
+ x
+ > for _it, a, b, c, d, e in take(3, duplicate(1, 2, 'a', 3, 'b')) do
+ print(a, b, c, d, e)
+ >> end
+ 1 2 a 3 b
+ 1 2 a 3 b
+ 1 2 a 3 b
+
+.. function:: xrepeat(...)
+
+ An alias for :func:`duplicate`.
+
+.. function:: replicate(...)
+
+ An alias for :func:`duplicate`.
+
+.. function:: tabulate(fun)
+
+ :param fun: an unary generating function
+ :type fun: function(n: uint) -> ...
+ :returns: an iterator
+
+ The iterator that returns ``fun(0)``, ``fun(1)``, ``fun(2)``, ``...`` values
+ indefinitely.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, take(5, tabulate(function(x) return 'a', 'b', 2*x end)))
+ a b 0
+ a b 2
+ a b 4
+ a b 6
+ a b 8
+ > each(print, take(5, tabulate(function(x) return x^2 end)))
+ 0
+ 1
+ 4
+ 9
+ 16
+
+.. function:: zeros()
+
+ :returns: an iterator
+
+ The iterator returns ``0`` indefinitely.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, take(5, zeros()))
+ 0
+ 0
+ 0
+ 0
+ 0
+
+.. function:: ones()
+
+ :returns: an iterator
+
+ The iterator that returns ``1`` indefinitely.
+
+ Example::
+
+ > each(print, take(5, ones()))
+ 1
+ 1
+ 1
+ 1
+ 1
+
+Random sampling
+---------------
+
+.. function:: rands([n[, m]])
+
+ :param n: an endpoint of the interval (see below)
+ :type n: uint
+ :param m: an endpoint of the interval (see below)
+ :type m: uint
+ :returns: an iterator
+
+ The iterator returns random values using :func:`math.random`.
+ If the **n** and **m** are set then the iterator returns pseudo-random
+ integers in the ``[n, m)`` interval (i.e. **m** is not included).
+ If the **m** is not set then the iterator generates pseudo-random integers
+ in the ``[0, n)`` interval. When called without arguments returns
+ pseudo-random real numbers with uniform distribution in the
+ interval ``[0, 1)``.
+
+ .. warning:: This iterator is not pure-functional and may not work as
+ expected with some library functions.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, take(10, rands(10, 20)))
+ 19
+ 17
+ 11
+ 19
+ 12
+ 13
+ 14
+ 16
+ 10
+ 11
+
+ > each(print, take(5, rands(10)))
+ 7
+ 6
+ 5
+ 9
+ 0
+
+ > each(print, take(5, rands()))
+ 0.79420629243124
+ 0.69885246563716
+ 0.5901037417281
+ 0.7532286166836
+ 0.080971251199854
+
diff --git a/Data/DefaultContent/Libraries/luafun/doc/getting_started.rst b/Data/DefaultContent/Libraries/luafun/doc/getting_started.rst
new file mode 100644
index 0000000..9a9e3de
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/getting_started.rst
@@ -0,0 +1,254 @@
+Getting Started
+===============
+
+Please jump to `Using the Library`_ section if you are familiar with Lua and
+LuaJIT.
+
+.. contents::
+
+Prerequisites
+-------------
+
+The library is designed for LuaJIT_. **LuaJIT 2.1 alpha** is high^W **Highly**
+recommended for performance reasons. Lua 5.1--5.3 are also supported.
+
+The library is platform-independent and expected to work on all platforms that
+supported by Lua(JIT). It can be also used in any Lua(JIT) based applications,
+e.g. Tarantool_ or OpenResty_.
+
+You might need diff_ tool to run test system and sphinx_ to regenerate the
+documentation from source files.
+
+.. _LuaJIT: http://luajit.org/
+.. _Tarantool: http://tarantool.org/
+.. _OpenResty: http://openresty.org/
+.. _diff: http://en.wikipedia.org/wiki/Diff
+.. _sphinx: http://sphinx-doc.org/
+
+Installing LuaJIT
+-----------------
+
+You can build LuaJIT from sources or install it from a binary archive.
+
+From Sources
+````````````
+
+1. Clone LuaJIT git repository. Please note that **v2.1** branch is needed.
+You can always select this branch using ``git checkout v2.1``.
+
+.. code-block:: bash
+
+ $ git clone http://luajit.org/git/luajit-2.0.git -b v2.1 luajit-2.1
+ Cloning into 'luajit-2.1'...
+
+2. Compile LuaJIT
+
+.. code-block:: bash
+
+ $ cd luajit-2.1/
+ luajit-2.1 $ make -j8
+
+3. Install LuaJIT
+
+.. code-block:: bash
+
+ luajit-2.1 $ make install
+ luajit-2.1 $ ln -s /usr/local/bin/luajit-2.1.0-alpha /usr/local/bin/luajit
+
+Install operation might require root permissions. However, you can install
+LuaJIT into your home directory.
+
+From a Binary Archive
+`````````````````````
+
+If operations above look too complicated for you, you always can download a
+binary archive from http://luajit.org/download.html page.
+Your favorite package manager may also have LuaJIT packages.
+
+Running LuaJIT
+``````````````
+
+Ensure that freshly installed LuaJIT works:
+
+.. code-block:: bash
+
+ $ luajit
+ LuaJIT 2.1.0-alpha -- Copyright (C) 2005-2013 Mike Pall. http://luajit.org/
+ JIT: ON SSE2 SSE3 SSE4.1 fold cse dce fwd dse narrow loop abc sink fuse
+ > = 2 + 2
+ 4
+
+It is good idea to use LuaJIT CLI under ``rlwrap`` (on nix platforms):
+
+.. code-block:: bash
+
+ alias luajit="rlwrap luajit"
+ $ luajit
+ LuaJIT 2.1.0-alpha -- Copyright (C) 2005-2013 Mike Pall. http://luajit.org/
+ JIT: ON SSE2 SSE3 SSE4.1 fold cse dce fwd dse narrow loop abc sink fuse
+ > = 2 + 2
+ 4
+ > = 2 + 2 <!-- You can use arrows, completion and so on, like in Bash
+
+Installing the Library
+----------------------
+
+Using LuaRocks
+``````````````
+
+Use the rockspec_ file.
+
+.. _rockspec: https://raw.github.com/luafun/luafun/master/fun-scm-1.rockspec
+
+Using git
+`````````
+1. Clone Lua Fun repository:
+
+.. code-block:: bash
+
+ git clone git://github.com/luafun/luafun.git
+ $ cd luafun
+
+2. Run tests (optional):
+
+.. code-block:: bash
+
+ luafun $ cd tests
+ luafun/tests $ ./runtest *.lua
+ Testing basic.lua
+ Testing compositions.lua
+ Testing filters.lua
+ Testing folds.lua
+ Testing generators.lua
+ Testing slices.lua
+ Testing transformations.lua
+ All tests have passed!
+
+Using wget
+``````````
+
+Just download https://raw.github.com/luafun/luafun/master/fun.lua file:
+
+.. code-block:: bash
+
+ $ wget https://raw.github.com/luafun/luafun/master/fun.lua
+
+Using the Library
+-----------------
+
+Try to run LuaJIT in the same directory where ``fun.lua`` file is located:
+
+.. code-block:: bash
+ :emphasize-lines: 4
+
+ luafun $ luajit
+ LuaJIT 2.1.0-alpha -- Copyright (C) 2005-2013 Mike Pall. http://luajit.org/
+ JIT: ON SSE2 SSE3 fold cse dce fwd dse narrow loop abc sink fuse
+ > fun = require 'fun'
+ >
+ > for _k, a in fun.range(3) do print(a) end
+ 1
+ 2
+ 3
+
+If you see an error message like ``stdin:1: module 'fun' not found:`` then
+you need to configure you Package Path (``package.path``). Please consult
+`Lua Wiki <http://lua-users.org/wiki/PackagePath>`_ for additional information.
+
+
+**Lua Fun** designed to be small ubiquitous library. It is a good idea to import
+all library functions to the global table:
+
+.. code-block:: bash
+ :emphasize-lines: 1
+
+ > for k, v in pairs(require "fun") do _G[k] = v end -- import fun.*
+ > for _k, a in range(3) do print(a) end
+ 0
+ 1
+ 2
+
+**Lua Fun** also provides a special **shortcut** to autoimport all functions:
+
+.. code-block:: bash
+ :emphasize-lines: 1
+
+ > require 'fun'() -- to import all lua.* functions to globals
+ > each(print, range(5))
+ 1
+ 2
+ 3
+ 4
+ 5
+
+Now you can use **Lua Fun**:
+
+.. code-block:: bash
+
+ > print(sum(filter(function(x) return x % 16 == 0 end, range(10000))))
+ 3130000
+
+ > each(print, take(5, tabulate(math.sin)))
+ 0
+ 2
+ 4
+ 6
+ 8
+
+ > each(print, enumerate(zip({"one", "two", "three", "four", "five"},
+ {"a", "b", "c", "d", "e"})))
+ 1 one a
+ 2 two b
+ 3 three c
+ 4 four d
+ 5 five e
+
+ > lines_to_grep = {
+ [[Emily]],
+ [[Chloe]],
+ [[Megan]],
+ [[Jessica]],
+ [[Emma]],
+ [[Sarah]],
+ [[Elizabeth]],
+ [[Sophie]],
+ [[Olivia]],
+ [[Lauren]]
+ }
+
+ > each(print, grep("Em", lines_to_grep))
+ Emily
+ Emma
+
+ > each(print, take(10, cycle(chain(
+ {enumerate({"a", "b", "c"})},
+ {"one", "two", "three"}))
+ ))
+ 0 a
+ 1 b
+ 2 c
+ one
+ two
+ three
+ 0 a
+ 1 b
+ 2 c
+ one
+
+Please note that functions support multireturn.
+
+Further Actions
+---------------
+
+- Take a look on :doc:`reference`.
+- Use :ref:`genindex` to find functions by its names.
+- Checkout **examples** from
+ `tests/ <https://github.com/luafun/luafun/tree/master/tests>`_ directory
+- Read :doc:`under_the_hood` section
+- "Star" us the on GitHub_ to help the project to survive
+- Make Great Software
+- Have fun
+
+**Lua Fun**. Simple, Efficient and Functional. In Lua. With JIT.
+
+.. _GitHub: http://github.com/luafun/luafun
diff --git a/Data/DefaultContent/Libraries/luafun/doc/index.rst b/Data/DefaultContent/Libraries/luafun/doc/index.rst
new file mode 100644
index 0000000..8d1862d
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/index.rst
@@ -0,0 +1,29 @@
+.. _library-index:
+
+###############################
+ Lua Functional Library
+###############################
+
+:Release: |version|
+:Date: |today|
+
+.. highlight:: lua
+
+Contents
+========
+
+.. toctree::
+ :maxdepth: 2
+
+ intro.rst
+ getting_started.rst
+ reference.rst
+ under_the_hood.rst
+ about.rst
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
+
diff --git a/Data/DefaultContent/Libraries/luafun/doc/indexing.rst b/Data/DefaultContent/Libraries/luafun/doc/indexing.rst
new file mode 100644
index 0000000..324cfbf
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/indexing.rst
@@ -0,0 +1,74 @@
+Indexing
+========
+
+.. module:: fun
+
+This section contains functions to find elements by its values.
+
+.. function:: index(x, gen, param, state)
+ iterator:index(x)
+
+ :param x: a value to find
+ :returns: the position of the first element that equals to the **x**
+
+ The function returns the position of the first element in the given iterator
+ which is equal (using ``==``) to the query element, or ``nil`` if there is
+ no such element.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > print(index(2, range(0)))
+ nil
+
+ > print(index("b", {"a", "b", "c", "d", "e"}))
+ 2
+
+.. function:: index_of(x, gen, param, state)
+ iterator:index_of(x)
+
+ An alias for :func:`index`.
+
+.. function:: elem_index(x, gen, param, state)
+ iterator:elem_index(x)
+
+ An alias for :func:`index`.
+
+.. function:: indexes(x, gen, param, state)
+ iterator:indexes(x)
+
+ :param x: a value to find
+ :returns: an iterator which positions of elements that equal to the **x**
+
+ The function returns an iterator to positions of elements which equals to
+ the query element.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, indexes("a", {"a", "b", "c", "d", "e", "a", "b", "a", "a"}))
+ 1
+ 6
+ 9
+ 10
+
+ .. seealso:: :func:`filter`
+
+.. function:: indices(x, gen, param, state)
+ iterator:indices(x)
+
+ An alias for :func:`indexes`.
+
+.. function:: elem_indexes(x, gen, param, state)
+ iterator:elem_indexes(x)
+
+ An alias for :func:`indexes`.
+
+.. function:: elem_indices(x, gen, param, state)
+ iterator:elem_indices(x)
+
+ An alias for :func:`indexes`.
+
+
diff --git a/Data/DefaultContent/Libraries/luafun/doc/intro.rst b/Data/DefaultContent/Libraries/luafun/doc/intro.rst
new file mode 100644
index 0000000..d47c431
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/intro.rst
@@ -0,0 +1,69 @@
+Introduction
+============
+
+.. module:: fun
+
+**Lua Fun** is a high-performance functional programming library
+designed for `LuaJIT tracing just-in-time compiler
+<http://luajit.org/luajit.html>`_.
+
+The library provides a set of more than 50 programming primitives typically
+found in languages like Standard ML, Haskell, Erlang, JavaScript, Python and
+even Lisp. High-order functions such as :func:`map`, :func:`filter`,
+:func:`reduce`, :func:`zip` will help you to **write simple and efficient
+functional code**.
+
+Let's see an example:
+
+.. code-block:: lua
+ :emphasize-lines: 2, 4
+
+ -- Functional style
+ require "fun" ()
+ n = 100
+ x = sum(map(function(x) return x^2 end, take(n, tabulate(math.sin))))
+ -- calculate sum(sin(x)^2 for x in 0..n-1)
+ print(x)
+ 50.011981355266
+
+.. code-block:: lua
+ :emphasize-lines: 2, 4
+
+ -- Object-oriented style
+ local fun = require "fun"
+ n = 100
+ x = fun.tabulate(math.sin):take(n):map(function(x) return x^2 end):sum()
+ -- calculate sum(sin(x)^2 for x in 0..n-1)
+ print(x)
+ 50.011981355266
+
+**Lua Fun** takes full advantage of the innovative **tracing JIT compiler**
+to achieve transcendental performance on nested functional expressions.
+Functional compositions and high-order functions can be translated into
+**efficient machine code**. Can you believe it? Just try to run the example above
+with ``luajit -jdump`` and see what happens:
+
+.. code-block:: none
+ :emphasize-lines: 2,14
+
+ -- skip some initilization code --
+ ->LOOP:
+ 0bcaffd0 movsd [rsp+0x8], xmm7
+ 0bcaffd6 addsd xmm4, xmm5
+ 0bcaffda ucomisd xmm6, xmm1
+ 0bcaffde jnb 0x0bca0028 ->6
+ 0bcaffe4 addsd xmm6, xmm0
+ 0bcaffe8 addsd xmm7, xmm0
+ 0bcaffec fld qword [rsp+0x8]
+ 0bcafff0 fsin
+ 0bcafff2 fstp qword [rsp]
+ 0bcafff5 movsd xmm5, [rsp]
+ 0bcafffa mulsd xmm5, xmm5
+ 0bcafffe jmp 0x0bcaffd0 ->LOOP
+ ---- TRACE 1 stop -> loop
+
+
+The functional chain above was translated by LuaJIT to (!) **one machine loop**
+containing just 10 CPU assembly instructions without CALL. Unbelievable!
+
+Readable? Efficient? Can your Python/Ruby/V8 do better?
diff --git a/Data/DefaultContent/Libraries/luafun/doc/logo.png b/Data/DefaultContent/Libraries/luafun/doc/logo.png
new file mode 100644
index 0000000..9bbeefc
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/logo.png
Binary files differ
diff --git a/Data/DefaultContent/Libraries/luafun/doc/logo.svg b/Data/DefaultContent/Libraries/luafun/doc/logo.svg
new file mode 100644
index 0000000..1a28b03
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/logo.svg
@@ -0,0 +1,758 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="1440"
+ height="1440"
+ viewBox="43 -188 937 937"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="logo.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.0"
+ inkscape:export-filename="/mnt/data/docs/Projects/Personal/lua-functional/doc/logo.png"
+ inkscape:export-xdpi="9"
+ inkscape:export-ydpi="9">
+ <path
+ style="fill:none;stroke:#8c8c8c;stroke-width:16.26736110999999951;stroke-linecap:butt;stroke-miterlimit:5;stroke-opacity:1;stroke-dasharray:65.06944443999999805, 130.13888889000000404;stroke-dashoffset:8.13368056000000017;stroke-linejoin:bevel"
+ d="m 973.58155,283.57775 c 0,254.76511 -206.52793,461.29304 -461.29304,461.29304 -254.76515,0 -461.293094,-206.52793 -461.293094,-461.29304 0,-254.765152 206.527944,-461.2931 461.293094,-461.2931 254.76511,0 461.29304,206.527948 461.29304,461.2931 z"
+ id="path4282"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 250.7423,53.17721 c 29.45588,-29.455878 28.94618,-82.860118 50.21763,-61.5886737 3.83457,3.8345707 18.19138,-8.2050713 20.24148,-3.2632463 93.26191,-67.02258 202.39283,-82.814868 307.85028,-49.879054 36.09059,-29.748071 38.94286,5.985418 65.3616,32.404157 18.29476,18.294756 66.53433,7.175347 57.32218,34.8338661 7.72301,6.5287109 15.21696,13.4128149 22.49443,20.6902869 139.48488,139.484874 138.85087,366.529134 -1.41522,506.795214 -13.20076,13.20077 -27.18352,25.13674 -41.78121,35.86827 0.11753,0.10989 0.24006,0.24005 0.35377,0.35376 7.32801,7.32801 -14.7794,5.93526 -22.8447,14.00055 -8.0653,8.0653 0.95061,22.54956 -6.3774,15.22155 -2.21104,-2.21104 -3.75936,-4.90791 -4.53809,-7.79318 -26.55681,15.31211 -48.92496,23.80758 -77.79886,31.78402 -12.36469,22.32067 -14.45697,24.76671 -25.49856,26.98942 -26.42114,5.29626 -16.92539,-32.7282 -39.30039,7.71415 -5.83218,10.5322 -4.69895,-9.62859 -3.70688,-20.07126 -13.58551,1.25424 -27.23228,1.76113 -40.86415,1.46978 2.43298,8.93808 -12.15669,-6.79506 -18.72531,-0.22644 -10.16421,10.16421 -10.99303,2.98276 -22.14929,-8.17351 -7.9092,-7.90919 -14.49182,12.74826 -11.76706,3.40302 -58.78521,-9.997 -115.48949,-34.70944 -164.14523,-74.19198 -12.56749,4.20346 -30.04677,-15.74065 -46.74503,-47.68522 -18.73981,-35.8665 -62.87191,-48.31168 -53.05075,-58.13285 2.27424,-2.27424 5.68495,-3.18332 9.94126,-2.91647 -59.56609,-111.47978 -59.53281,-236.82202 7.66772,-345.71641 -7.0415,-1.94668 0.60884,-14.312211 -4.54351,-19.46456 -21.27144,-21.271445 14.34543,-2.974381 43.80131,-32.430258 z"
+ id="path2506"
+ inkscape:connector-curvature="0"
+ style="fill:#d7deda;fill-opacity:0.97647005" />
+ <path
+ d="m 287.34799,21.45871 c 6.52025,-6.035087 16.97461,-2.136648 26.09844,-2.252082 21.83494,-19.90438598 48.25766,-35.746981 80.22166,-44.60753 80.62955,-22.34913 163.05343,-11.227174 228.16322,7.000201 9.31493,-10.02247 16.50699,-22.066176 26.36444,-31.266625 13.69185,-7.576755 21.2235,8.492836 23.43568,19.370001 5.21678,14.745728 20.40462,24.978509 36.11753,24.1237648 13.37752,-3.9016398 21.24609,9.4810162 11.70331,19.4281032 -0.66287,1.446206 -1.46443,2.652074 -2.34152,3.680776 19.75182,9.206453 31.14881,15.826263 31.14881,15.826263 0,0 -515.21186,34.570202 -538.20281,241.595288 0,0 3.43188,-81.53836 38.27299,-160.65582 -7.67327,-6.1893 -22.35662,-13.32826 -18.49899,-25.0117 11.3442,-3.965646 19.91446,-12.738063 28.68349,-20.549398 14.31083,-10.138919 17.14992,-28.164671 25.73394,-42.317982 0.89329,-1.838346 1.91466,-3.266548 3.09981,-4.36326 z"
+ id="path2510"
+ inkscape:connector-curvature="0"
+ style="fill:#eef0ec;fill-opacity:0.97646999;fill-rule:evenodd" />
+ <path
+ d="M 349.02532,562.43439 C 563.32391,498.23366 740.70727,495.93921 854.0712,325.4168 c 0,0 -30.7903,145.25887 -134.58891,230.61111 -0.11784,4.53991 0.12283,9.10036 -1.6651,13.26357 -5.01838,6.76194 -14.52863,7.78181 -22.309,8.18363 -1.6497,0.0325 -3.06759,-0.36899 -4.28079,-1.0257 -27.4747,17.34183 -59.17561,30.44476 -95.71065,36.50538 -0.4933,7.87185 -0.46921,16.03492 -6.07808,19.64753 -11.10367,-1.40448 -22.81156,-1.49721 -33.25929,-3.22914 -2.18379,-2.89528 -5.65439,-7.76345 -7.98455,-12.68549 -13.88598,-0.0372 -28.32681,-1.0105 -43.39817,-3.04626 -8.59541,1.89913 -17.51678,2.55753 -26.33409,2.25274 -5.85207,-0.49045 -13.89777,-0.35395 -16.09607,-7.12615 -0.16198,-0.97512 -0.14595,-2.17879 -0.14255,-3.3951 -34.76701,-8.6704 -72.39533,-22.61611 -113.19863,-42.93853 z"
+ id="path2512"
+ inkscape:connector-curvature="0"
+ style="fill:#c4ccbd;fill-opacity:0.97646999;fill-rule:evenodd" />
+ <metadata
+ id="metadata31">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>generated by pstoedit</dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs29">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 512 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1024 : 512 : 1"
+ inkscape:persp3d-origin="512 : 341.33333 : 1"
+ id="perspective33" />
+ <marker
+ id="Arrow1Lstart"
+ style="overflow:visible"
+ orient="auto"
+ refY="0"
+ refX="0">
+ <path
+ id="path3200"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(0.8,0,0,0.8,10,0)"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z " />
+ </marker>
+ <marker
+ id="Arrow1Mend"
+ style="overflow:visible"
+ orient="auto"
+ refY="0"
+ refX="0">
+ <path
+ id="path3209"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z " />
+ </marker>
+ <marker
+ id="Arrow1Mstart"
+ style="overflow:visible"
+ orient="auto"
+ refY="0"
+ refX="0">
+ <path
+ id="path3206"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(0.4,0,0,0.4,4,0)"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z " />
+ </marker>
+ <linearGradient
+ x1="342.86"
+ x2="554.29"
+ y1="549.51"
+ gradientUnits="userSpaceOnUse"
+ y2="549.51"
+ id="linearGradient4218">
+ <stop
+ offset="0"
+ stop-color="#a40000"
+ id="stop4214" />
+ <stop
+ offset="1"
+ stop-color="#ec0000"
+ id="stop4216" />
+ </linearGradient>
+ <marker
+ id="Arrow1Lstart-0"
+ style="overflow:visible"
+ orient="auto"
+ refY="0"
+ refX="0">
+ <path
+ id="path3200-5"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(0.8,0,0,0.8,10,0)"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z " />
+ </marker>
+ <marker
+ id="Arrow1Mend-0"
+ style="overflow:visible"
+ orient="auto"
+ refY="0"
+ refX="0">
+ <path
+ id="path3209-0"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(-0.4,0,0,-0.4,-4,0)"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z " />
+ </marker>
+ <marker
+ id="Arrow1Mstart-7"
+ style="overflow:visible"
+ orient="auto"
+ refY="0"
+ refX="0">
+ <path
+ id="path3206-2"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="matrix(0.4,0,0,0.4,4,0)"
+ d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z " />
+ </marker>
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-height="965"
+ inkscape:window-width="1280"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ showgrid="false"
+ inkscape:zoom="0.15951335"
+ inkscape:cx="1033.4421"
+ inkscape:cy="994.65682"
+ inkscape:window-x="-4"
+ inkscape:window-y="-6"
+ inkscape:current-layer="svg2"
+ inkscape:window-maximized="1"
+ inkscape:object-paths="true"
+ inkscape:snap-nodes="false"
+ inkscape:snap-bbox="true" />
+ <title
+ id="title4">generated by pstoedit</title>
+ <!-- generated by pstoedit version:3.50 -->
+ <g
+ id="g3468"
+ transform="matrix(-1.2705261,1.2705261,1.26345,1.26345,389.29787,-726.3541)">
+ <path
+ style="fill:#c4ccbe"
+ inkscape:connector-curvature="0"
+ id="path2407"
+ d="m 551.43,460.93 a 200,200 0 1 1 -400,0 200,200 0 1 1 400,0 z"
+ transform="matrix(0.13119,0,0,0.13119,265.51,542.98)" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path2409"
+ d="m 308.24,579.84 c -12.11,1.77 -20.84,12.18 -20.83,24.08 2.76,-10.26 11.56,-17.11 22.74,-18.75 8.24,-1.2 15.98,0.09 21.81,5.16 -5.07,-7.51 -14.16,-11.89 -23.72,-10.49 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2411"
+ d="m 306.85,575.63 c -12.12,1.78 -21.59,10.51 -21.58,22.4 2.76,-10.26 11.37,-18.42 22.55,-20.06 8.24,-1.21 16.16,1.39 22,6.46 -5.08,-7.5 -13.41,-10.19 -22.97,-8.8 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path2413"
+ d="m 323.98,632.86 c 11.41,-4.43 16.84,-18.21 14.2,-29.8 -0.41,10.61 -6.99,20.49 -17.53,24.57 -7.76,3.01 -16.07,2.24 -22.89,-1.41 6.62,6.2 17.2,10.13 26.22,6.64 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2415"
+ d="m 317.07,627.04 c 11.89,-2.93 19.56,-14.15 18.4,-25.98 -1.75,10.47 -8.78,18.31 -19.75,21.02 -8.09,2 -16.98,1.31 -23.27,-3.18 5.78,6.98 15.24,10.46 24.62,8.14 z" />
+ </g>
+ <g
+ id="g3376"
+ transform="translate(-366.08185,6.8571058)">
+ <path
+ d="m 737.83252,197.3382 a 22.377738,22.503065 45 1 0 31.82414,-31.82414 22.377738,22.503065 45 1 0 -31.82414,31.82414 z"
+ id="path2419"
+ inkscape:connector-curvature="0"
+ style="fill:#c4ccbe" />
+ <path
+ d="m 741.55503,165.12884 c 8.41758,-6.2697 19.98231,-5.27575 27.15871,1.90065 -7.868,-4.51381 -17.33569,-3.30908 -25.09309,2.47733 -5.72604,4.28571 -9.64357,9.74465 -10.11809,16.33426 -1.44848,-7.59782 1.41229,-15.73981 8.05247,-20.71224 z"
+ id="path2421"
+ inkscape:connector-curvature="0"
+ style="fill:#808080" />
+ <path
+ d="m 739.86668,161.7634 c 8.40494,-6.28235 19.4163,-6.75654 26.5927,0.41986 -7.85529,-4.52652 -18.01732,-4.21941 -25.77471,1.56701 -5.71334,4.273 -8.96195,10.65497 -9.43647,17.24458 -1.46111,-7.61046 1.97837,-14.28437 8.61848,-19.23145 z"
+ id="path2423"
+ inkscape:connector-curvature="0"
+ style="fill:#ececec" />
+ <path
+ d="m 763.9913,206.64841 c -9.59025,4.25849 -21.20711,-0.75164 -26.58042,-9.35209 6.63445,6.15166 16.60009,8.11299 25.44186,4.19867 6.52039,-2.90692 11.09683,-8.39304 13.04034,-14.73336 -0.28768,7.74204 -4.32855,16.53348 -11.90178,19.88678 z"
+ id="path2425"
+ inkscape:connector-curvature="0"
+ style="fill:#808080" />
+ <path
+ d="m 764.67158,198.96863 c -8.98535,5.42242 -20.39493,3.31308 -26.83464,-4.5242 7.38449,5.25001 16.36606,5.71905 24.6661,0.70398 6.10451,-3.70395 11.0746,-9.50792 12.1951,-16.03599 0.70064,7.71394 -2.94481,15.55405 -10.02656,19.85621 z"
+ id="path2427"
+ inkscape:connector-curvature="0"
+ style="fill:#ececec" />
+ </g>
+ <path
+ style="fill:#daded5"
+ inkscape:connector-curvature="0"
+ id="path2431"
+ d="m 477.99202,72.998425 a 42.282553,42.519363 45 1 0 60.13146,-60.13146 42.282553,42.519363 45 0 0 -60.13146,60.13146 z" />
+ <path
+ style="fill:#808080"
+ inkscape:connector-curvature="0"
+ id="path2433"
+ d="m 485.01368,12.160781 c 15.90837,-11.86533063 37.7585,-9.9878703 51.30269,3.556314 -14.85053,-8.5233028 -32.74662,-6.2434466 -47.4108,4.706185 -10.80453,8.075483 -18.2072,18.409357 -19.1162,30.866291 -2.73455,-14.372566 2.68043,-29.768802 15.22431,-39.12879 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2435"
+ d="M 481.82607,5.7714423 C 497.73444,-6.093888 518.52808,-7.0008294 532.0722,6.5686943 517.20904,-1.9672427 498.05077,-1.4069521 483.38659,9.5426795 472.55672,17.618233 466.42893,29.658968 465.51993,42.115902 462.78538,27.743336 469.28219,15.13143 481.82607,5.7714423 z" />
+ <path
+ style="fill:#808080"
+ inkscape:connector-curvature="0"
+ id="path2437"
+ d="m 527.4031,90.607725 c -18.11488,8.032548 -40.04514,-1.446558 -50.22427,-17.698802 12.57394,11.633756 31.35287,15.344242 48.07236,7.92374 12.34297,-5.469804 20.96209,-15.857754 24.61908,-27.828241 -0.52236,14.647727 -8.17056,31.241159 -22.46717,37.603303 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2439"
+ d="m 528.68536,76.059235 c -16.96818,10.271897 -38.5337,6.290458 -50.706,-8.524535 13.97237,9.932101 30.94747,10.796922 46.60842,1.326872 11.53635,-6.987926 20.92999,-17.973519 23.04224,-30.294445 1.3403,14.579176 -5.5554,29.384068 -18.94466,37.492108 z" />
+ <path
+ style="fill:#daded5"
+ inkscape:connector-curvature="0"
+ id="path2455"
+ d="m 267.79765,192.31588 a 22.377735,22.503062 45 0 0 31.82414,-31.82414 22.377735,22.503062 45 1 0 -31.82414,31.82414 z" />
+ <path
+ style="fill:#808080"
+ inkscape:connector-curvature="0"
+ id="path2457"
+ d="m 271.52016,160.10652 c 8.41757,-6.26971 19.98231,-5.27575 27.1587,1.90065 -7.868,-4.51381 -17.33569,-3.30909 -25.09308,2.47733 -5.72604,4.2857 -9.64358,9.74465 -10.11809,16.33426 -1.44848,-7.59782 1.41229,-15.73981 8.05247,-20.71224 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2459"
+ d="m 269.8318,156.74107 c 8.40494,-6.28234 19.41631,-6.75653 26.5927,0.41986 -7.85529,-4.52651 -18.01731,-4.2194 -25.77471,1.56701 -5.71333,4.27301 -8.96195,10.65498 -9.43646,17.24459 -1.46111,-7.61046 1.97836,-14.28437 8.61847,-19.23146 z" />
+ <path
+ style="fill:#808080"
+ inkscape:connector-curvature="0"
+ id="path2461"
+ d="m 293.95643,201.62609 c -9.59025,4.25849 -21.20712,-0.75164 -26.58043,-9.35209 6.63446,6.15166 16.6001,8.11298 25.44187,4.19867 6.52038,-2.90692 11.09682,-8.39304 13.04033,-14.73336 -0.28768,7.74204 -4.32855,16.53348 -11.90177,19.88678 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2463"
+ d="m 294.6367,193.9463 c -8.98535,5.42242 -20.39493,3.31309 -26.83463,-4.52419 7.38449,5.25001 16.36605,5.71905 24.6661,0.70397 6.1045,-3.70395 11.0746,-9.50792 12.1951,-16.03598 0.70063,7.71394 -2.94482,15.55404 -10.02657,19.8562 z" />
+ <g
+ id="g3418"
+ transform="matrix(-0.72129759,1.0777674,1.2794218,0.85229632,104.1786,-411.8976)">
+ <path
+ style="fill:#c4ccbe"
+ inkscape:connector-curvature="0"
+ id="path2491"
+ d="m 551.43,460.93 a 200,200 0 1 1 -400,0 200,200 0 1 1 400,0 z"
+ transform="matrix(0.11832,0,0,0.11832,443.45,470.93)" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path2493"
+ d="m 481.99,504.17 c -10.93,1.6 -18.79,10.99 -18.79,21.71 2.49,-9.25 10.43,-15.43 20.51,-16.9 7.43,-1.08 14.41,0.08 19.67,4.65 -4.58,-6.77 -12.77,-10.72 -21.39,-9.46 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2495"
+ d="m 480.73,500.38 c -10.93,1.6 -19.47,9.47 -19.46,20.2 2.49,-9.26 10.25,-16.62 20.33,-18.09 7.44,-1.09 14.59,1.25 19.85,5.82 -4.58,-6.77 -12.1,-9.19 -20.72,-7.93 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path2497"
+ d="m 496.18,551.99 c 10.29,-3.99 15.19,-16.42 12.8,-26.88 -0.37,9.58 -6.3,18.48 -15.8,22.16 -7.01,2.72 -14.49,2.02 -20.64,-1.27 5.97,5.59 15.51,9.13 23.64,5.99 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2499"
+ d="m 489.95,546.74 c 10.72,-2.65 17.64,-12.76 16.6,-23.44 -1.59,9.46 -7.93,16.52 -17.82,18.97 -7.29,1.8 -15.31,1.17 -20.99,-2.87 5.21,6.3 13.75,9.43 22.21,7.34 z" />
+ </g>
+ <path
+ style="fill:#c4ccbe"
+ inkscape:connector-curvature="0"
+ id="path2568"
+ d="m 554.80317,481.06024 a 44.255169,44.503024 45 1 0 62.93678,-62.93678 44.255169,44.503024 45 1 0 -62.93678,62.93678 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path2570"
+ d="m 562.16164,412.16764 c 16.63208,-12.41215 39.50822,-10.44887 53.69676,3.73967 -15.53356,-8.92682 -34.26615,-6.54327 -49.61592,4.91506 -11.33773,8.45707 -19.08379,19.26068 -20.03247,32.31321 -2.8594,-15.03105 2.81103,-31.16284 15.95163,-40.96794 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2572"
+ d="m 558.81014,410.69291 c 16.65741,-12.41222 38.42674,-13.35989 52.60258,0.84135 -15.5462,-8.93946 -35.61678,-8.35128 -50.96654,3.10706 -11.33773,8.45706 -17.74581,21.05605 -18.68178,34.09587 -2.87204,-15.04368 3.91784,-28.25188 17.04574,-38.04428 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path2574"
+ d="m 606.5173,495.58472 c -18.95216,8.41498 -41.92007,-1.51734 -52.5659,-18.5158 13.14257,12.17697 32.82059,16.04965 50.32654,8.29754 12.90116,-5.72476 21.93976,-16.608 25.77568,-29.13646 -0.56224,15.31934 -8.55476,32.71193 -23.53632,39.35472 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2576"
+ d="m 607.86479,484.26872 c -17.75506,10.75555 -40.33361,6.57422 -53.06147,-8.92339 14.59189,10.39915 32.37771,11.31239 48.76209,1.39687 12.0821,-7.33153 21.92058,-18.81248 24.13581,-31.71651 1.38907,15.26321 -5.82532,30.76583 -19.83643,39.24303 z" />
+ <path
+ style="fill:#e2e4df;fill-opacity:0.97646999"
+ inkscape:connector-curvature="0"
+ id="path2597"
+ d="M 345.06872,36.033812 A 16.011413,35.471259 55.13194 1 0 403.29514,-4.4942038 16.011413,35.471259 55.13194 0 0 345.06872,36.033812 z" />
+ <path
+ style="fill:#808080"
+ inkscape:connector-curvature="0"
+ id="path2599"
+ d="m 369.73627,1.3206138 c 14.04909,-8.4646367 27.34393,-9.9841269 31.48295,-4.0155481 -6.64323,-3.0095266 -18.77761,0.3565111 -31.74795,8.1719766 -9.56908,5.7534627 -17.70891,12.3771497 -22.41644,19.4346937 3.02424,-7.699003 11.57672,-16.908477 22.68144,-23.5911222 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2601"
+ d="m 369.8085,-1.8597031 c 14.06179,-8.4773419 27.60129,-11.4038609 31.74031,-5.4352823 -6.63052,-3.0222316 -19.02874,-0.4536537 -31.99909,7.36181179 C 359.98064,5.8202893 352.10465,13.241435 347.38449,20.286345 350.40866,12.612682 358.72912,4.8228714 369.8085,-1.8597031 z" />
+ <path
+ style="fill:#808080"
+ inkscape:connector-curvature="0"
+ id="path2603"
+ d="m 370.70498,40.074771 c -14.19589,6.589919 -25.02096,3.870805 -26.11397,-3.981407 4.14171,5.005668 14.88605,4.874306 27.97828,-1.21841 9.6669,-4.486757 18.6181,-11.290087 24.90947,-18.390063 -5.19224,8.224517 -15.5718,18.376658 -26.77378,23.58988 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2605"
+ d="m 376.34077,31.811005 c -14.21171,7.717574 -26.61626,8.018279 -29.46055,1.184539 5.60183,3.89932 16.12193,2.400248 29.22969,-4.718763 9.68166,-5.234316 19.29282,-12.444922 24.72271,-19.5678322 -3.98792,7.9804292 -13.28747,17.0272822 -24.49185,23.1020562 z" />
+ <g
+ id="g3369">
+ <path
+ d="m 840.28494,289.31978 a 39.752241,17.207074 68.840856 0 0 32.03091,-12.58489 39.752241,17.207074 68.840856 1 0 -32.03091,12.58489 z"
+ id="path2621"
+ inkscape:connector-curvature="0"
+ style="fill:#c4ccbe" />
+ <path
+ d="m 845.41613,248.86481 c 8.36318,-0.40345 19.38864,12.22287 25.91736,29.01744 -7.3099,-13.81499 -16.43632,-21.39137 -24.16594,-21.01503 -5.67681,0.26924 -9.70339,3.94206 -10.4875,12.50902 -1.01859,-11.81806 2.13419,-20.17625 8.73608,-20.51143 z"
+ id="path2623"
+ inkscape:connector-curvature="0"
+ style="fill:#a2ae98" />
+ <path
+ d="m 843.9639,242.60999 c 8.36318,-0.40345 18.92704,9.6522 25.45576,26.44677 -7.32253,-13.82763 -17.03917,-23.29016 -24.76879,-22.91382 -5.68945,0.25661 -9.11318,5.82821 -9.89729,14.39517 -1.00588,-11.83077 2.6085,-17.61828 9.21032,-17.92812 z"
+ id="path2625"
+ inkscape:connector-curvature="0"
+ style="fill:#ececec" />
+ <path
+ d="m 864.87263,327.52783 c -9.37851,-3.50868 -20.24914,-21.67213 -25.00351,-38.67437 6.07791,14.89536 15.50768,27.27274 24.17745,30.50466 6.3916,2.37674 11.02464,-0.68961 13.19748,-7.48668 -0.64966,10.32769 -4.95465,18.42303 -12.37142,15.65639 z"
+ id="path2627"
+ inkscape:connector-curvature="0"
+ style="fill:#a2ae98" />
+ <path
+ d="m 865.90112,317.65519 c -8.86524,-1.2929 -19.68416,-15.28813 -25.47746,-32.28747 6.81418,14.38651 15.40344,23.7635 23.58479,24.95696 6.02831,0.89539 11.06693,-2.22278 12.46984,-10.06929 0.298,11.24993 -3.57367,18.43184 -10.57717,17.3998 z"
+ id="path2629"
+ inkscape:connector-curvature="0"
+ style="fill:#ececec" />
+ </g>
+ <g
+ id="g3633"
+ transform="matrix(-1.4688182,0.85217884,0.72653868,1.2603375,659.03127,-542.96386)">
+ <path
+ style="fill:#c4ccbe"
+ inkscape:connector-curvature="0"
+ id="path2443"
+ d="m 551.43,460.93 a 200,200 0 1 1 -400,0 200,200 0 1 1 400,0 z"
+ transform="matrix(0.17954,0,0,0.17954,370.24,308.37)" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path2445"
+ d="m 428.71,358.82 c -16.58,2.42 -28.52,16.67 -28.52,32.95 3.78,-14.04 15.83,-23.42 31.13,-25.65 11.28,-1.65 21.87,0.11 29.85,7.05 -6.94,-10.27 -19.38,-16.27 -32.46,-14.35 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2447"
+ d="m 426.8,353.06 c -16.58,2.43 -29.54,14.38 -29.53,30.65 3.77,-14.04 15.56,-25.21 30.86,-27.45 11.28,-1.65 22.12,1.9 30.11,8.84 -6.95,-10.27 -18.36,-13.95 -31.44,-12.04 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path2449"
+ d="m 450.24,431.38 c 15.62,-6.06 23.06,-24.92 19.44,-40.79 -0.56,14.53 -9.57,28.05 -23.99,33.63 -10.63,4.12 -21.99,3.07 -31.32,-1.92 9.06,8.47 23.54,13.85 35.87,9.08 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2451"
+ d="m 440.8,423.42 c 16.26,-4.02 26.76,-19.37 25.18,-35.57 -2.4,14.34 -12.03,25.07 -27.04,28.78 -11.06,2.73 -23.23,1.78 -31.85,-4.35 7.91,9.55 20.87,14.31 33.71,11.14 z" />
+ <g
+ id="g2530"
+ transform="matrix(0.10015,0,0,0.10015,386.4,347.37)">
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path2534"
+ d="m 329.56,392.23 c -32.32,4.72 -55.59,32.51 -55.59,64.23 7.37,-27.37 30.86,-45.64 60.68,-50 21.99,-3.21 42.63,0.22 58.19,13.76 -13.54,-20.04 -37.77,-31.72 -63.28,-27.99 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2536"
+ d="m 325.84,381.01 c -32.32,4.73 -57.58,28.03 -57.57,59.75 7.36,-27.37 30.34,-49.15 60.16,-53.51 21.99,-3.22 43.13,3.7 58.7,17.24 -13.55,-20.03 -35.78,-27.21 -61.29,-23.48 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path2538"
+ d="m 371.54,533.68 c 30.45,-11.8 44.95,-48.58 37.88,-79.51 -1.09,28.33 -18.65,54.68 -46.75,65.56 -20.72,8.03 -42.88,5.98 -61.06,-3.75 17.66,16.52 45.89,27.01 69.93,17.7 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2540"
+ d="m 353.12,518.16 c 31.71,-7.83 52.17,-37.75 49.09,-69.33 -4.68,27.96 -23.44,48.86 -52.69,56.09 -21.58,5.33 -45.3,3.49 -62.1,-8.47 15.42,18.62 40.67,27.9 65.7,21.71 z" />
+ </g>
+ <g
+ id="g3535"
+ transform="matrix(0.072158,0,0,0.072158,413.73,346.21)">
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3539"
+ d="m 329.56,392.23 c -32.32,4.72 -55.59,32.51 -55.59,64.23 7.37,-27.37 30.86,-45.64 60.68,-50 21.99,-3.21 42.63,0.22 58.19,13.76 -13.54,-20.04 -37.77,-31.72 -63.28,-27.99 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3541"
+ d="m 325.84,381.01 c -32.32,4.73 -57.58,28.03 -57.57,59.75 7.36,-27.37 30.34,-49.15 60.16,-53.51 21.99,-3.22 43.13,3.7 58.7,17.24 -13.55,-20.03 -35.78,-27.21 -61.29,-23.48 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3543"
+ d="m 371.54,533.68 c 30.45,-11.8 44.95,-48.58 37.88,-79.51 -1.09,28.33 -18.65,54.68 -46.75,65.56 -20.72,8.03 -42.88,5.98 -61.06,-3.75 17.66,16.52 45.89,27.01 69.93,17.7 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3545"
+ d="m 353.12,518.16 c 31.71,-7.83 52.17,-37.75 49.09,-69.33 -4.68,27.96 -23.44,48.86 -52.69,56.09 -21.58,5.33 -45.3,3.49 -62.1,-8.47 15.42,18.62 40.67,27.9 65.7,21.71 z" />
+ </g>
+ </g>
+ <g
+ id="g3356"
+ transform="matrix(-0.49245592,0.49245592,0.48971322,0.48971322,514.97811,37.308113)">
+ <path
+ style="fill:#c4ccbe"
+ inkscape:connector-curvature="0"
+ id="path3358"
+ d="m 551.43,460.93 a 200,200 0 1 1 -400,0 200,200 0 1 1 400,0 z"
+ transform="matrix(0.13119,0,0,0.13119,265.51,542.98)" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3360"
+ d="m 308.24,579.84 c -12.11,1.77 -20.84,12.18 -20.83,24.08 2.76,-10.26 11.56,-17.11 22.74,-18.75 8.24,-1.2 15.98,0.09 21.81,5.16 -5.07,-7.51 -14.16,-11.89 -23.72,-10.49 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3362"
+ d="m 306.85,575.63 c -12.12,1.78 -21.59,10.51 -21.58,22.4 2.76,-10.26 11.37,-18.42 22.55,-20.06 8.24,-1.21 16.16,1.39 22,6.46 -5.08,-7.5 -13.41,-10.19 -22.97,-8.8 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3364"
+ d="m 323.98,632.86 c 11.41,-4.43 16.84,-18.21 14.2,-29.8 -0.41,10.61 -6.99,20.49 -17.53,24.57 -7.76,3.01 -16.07,2.24 -22.89,-1.41 6.62,6.2 17.2,10.13 26.22,6.64 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3366"
+ d="m 317.07,627.04 c 11.89,-2.93 19.56,-14.15 18.4,-25.98 -1.75,10.47 -8.78,18.31 -19.75,21.02 -8.09,2 -16.98,1.31 -23.27,-3.18 5.78,6.98 15.24,10.46 24.62,8.14 z" />
+ </g>
+ <g
+ id="g3368"
+ transform="matrix(-0.3750593,0.3750593,0.37297044,0.37297044,648.90217,72.004088)">
+ <path
+ style="fill:#c4ccbe"
+ inkscape:connector-curvature="0"
+ id="path3370"
+ d="m 551.43,460.93 a 200,200 0 1 1 -400,0 200,200 0 1 1 400,0 z"
+ transform="matrix(0.13119,0,0,0.13119,265.51,542.98)" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3372"
+ d="m 308.24,579.84 c -12.11,1.77 -20.84,12.18 -20.83,24.08 2.76,-10.26 11.56,-17.11 22.74,-18.75 8.24,-1.2 15.98,0.09 21.81,5.16 -5.07,-7.51 -14.16,-11.89 -23.72,-10.49 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3374"
+ d="m 306.85,575.63 c -12.12,1.78 -21.59,10.51 -21.58,22.4 2.76,-10.26 11.37,-18.42 22.55,-20.06 8.24,-1.21 16.16,1.39 22,6.46 -5.08,-7.5 -13.41,-10.19 -22.97,-8.8 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3376"
+ d="m 323.98,632.86 c 11.41,-4.43 16.84,-18.21 14.2,-29.8 -0.41,10.61 -6.99,20.49 -17.53,24.57 -7.76,3.01 -16.07,2.24 -22.89,-1.41 6.62,6.2 17.2,10.13 26.22,6.64 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3378"
+ d="m 317.07,627.04 c 11.89,-2.93 19.56,-14.15 18.4,-25.98 -1.75,10.47 -8.78,18.31 -19.75,21.02 -8.09,2 -16.98,1.31 -23.27,-3.18 5.78,6.98 15.24,10.46 24.62,8.14 z" />
+ </g>
+ <g
+ id="g3380"
+ transform="matrix(-0.29120458,0.29120458,0.28958274,0.28958274,601.16283,185.29122)">
+ <path
+ style="fill:#c4ccbe"
+ inkscape:connector-curvature="0"
+ id="path3382"
+ d="m 551.43,460.93 a 200,200 0 1 1 -400,0 200,200 0 1 1 400,0 z"
+ transform="matrix(0.13119,0,0,0.13119,265.51,542.98)" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3384"
+ d="m 308.24,579.84 c -12.11,1.77 -20.84,12.18 -20.83,24.08 2.76,-10.26 11.56,-17.11 22.74,-18.75 8.24,-1.2 15.98,0.09 21.81,5.16 -5.07,-7.51 -14.16,-11.89 -23.72,-10.49 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3386"
+ d="m 306.85,575.63 c -12.12,1.78 -21.59,10.51 -21.58,22.4 2.76,-10.26 11.37,-18.42 22.55,-20.06 8.24,-1.21 16.16,1.39 22,6.46 -5.08,-7.5 -13.41,-10.19 -22.97,-8.8 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3388"
+ d="m 323.98,632.86 c 11.41,-4.43 16.84,-18.21 14.2,-29.8 -0.41,10.61 -6.99,20.49 -17.53,24.57 -7.76,3.01 -16.07,2.24 -22.89,-1.41 6.62,6.2 17.2,10.13 26.22,6.64 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3390"
+ d="m 317.07,627.04 c 11.89,-2.93 19.56,-14.15 18.4,-25.98 -1.75,10.47 -8.78,18.31 -19.75,21.02 -8.09,2 -16.98,1.31 -23.27,-3.18 5.78,6.98 15.24,10.46 24.62,8.14 z" />
+ </g>
+ <g
+ id="g3394"
+ transform="matrix(-0.7891535,0.42773099,0.33687688,0.62609944,622.48286,84.019995)">
+ <path
+ style="fill:#c4ccbe"
+ inkscape:connector-curvature="0"
+ id="path3396"
+ d="m 551.43,460.93 a 200,200 0 1 1 -400,0 200,200 0 1 1 400,0 z"
+ transform="matrix(0.13119,0,0,0.13119,265.51,542.98)" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3398"
+ d="m 308.24,579.84 c -12.11,1.77 -20.84,12.18 -20.83,24.08 2.76,-10.26 11.56,-17.11 22.74,-18.75 8.24,-1.2 15.98,0.09 21.81,5.16 -5.07,-7.51 -14.16,-11.89 -23.72,-10.49 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3400"
+ d="m 306.85,575.63 c -12.12,1.78 -21.59,10.51 -21.58,22.4 2.76,-10.26 11.37,-18.42 22.55,-20.06 8.24,-1.21 16.16,1.39 22,6.46 -5.08,-7.5 -13.41,-10.19 -22.97,-8.8 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3402"
+ d="m 323.98,632.86 c 11.41,-4.43 16.84,-18.21 14.2,-29.8 -0.41,10.61 -6.99,20.49 -17.53,24.57 -7.76,3.01 -16.07,2.24 -22.89,-1.41 6.62,6.2 17.2,10.13 26.22,6.64 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3404"
+ d="m 317.07,627.04 c 11.89,-2.93 19.56,-14.15 18.4,-25.98 -1.75,10.47 -8.78,18.31 -19.75,21.02 -8.09,2 -16.98,1.31 -23.27,-3.18 5.78,6.98 15.24,10.46 24.62,8.14 z" />
+ </g>
+ <g
+ id="g3406"
+ transform="matrix(-0.614617,0.614617,0.77796934,0.77796934,18.355513,-189.8468)">
+ <path
+ style="fill:#c4ccbe"
+ inkscape:connector-curvature="0"
+ id="path3408"
+ d="m 551.43,460.93 a 200,200 0 1 1 -400,0 200,200 0 1 1 400,0 z"
+ transform="matrix(0.13119,0,0,0.13119,265.51,542.98)" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3410"
+ d="m 308.24,579.84 c -12.11,1.77 -20.84,12.18 -20.83,24.08 2.76,-10.26 11.56,-17.11 22.74,-18.75 8.24,-1.2 15.98,0.09 21.81,5.16 -5.07,-7.51 -14.16,-11.89 -23.72,-10.49 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3412"
+ d="m 306.85,575.63 c -12.12,1.78 -21.59,10.51 -21.58,22.4 2.76,-10.26 11.37,-18.42 22.55,-20.06 8.24,-1.21 16.16,1.39 22,6.46 -5.08,-7.5 -13.41,-10.19 -22.97,-8.8 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3414"
+ d="m 323.98,632.86 c 11.41,-4.43 16.84,-18.21 14.2,-29.8 -0.41,10.61 -6.99,20.49 -17.53,24.57 -7.76,3.01 -16.07,2.24 -22.89,-1.41 6.62,6.2 17.2,10.13 26.22,6.64 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3416"
+ d="m 317.07,627.04 c 11.89,-2.93 19.56,-14.15 18.4,-25.98 -1.75,10.47 -8.78,18.31 -19.75,21.02 -8.09,2 -16.98,1.31 -23.27,-3.18 5.78,6.98 15.24,10.46 24.62,8.14 z" />
+ </g>
+ <path
+ style="fill:#ffffff;fill-opacity:1"
+ inkscape:connector-curvature="0"
+ id="path2385"
+ d="m 582.68118,214.50453 a 109.15131,109.76263 45 0 0 155.2278,-155.2278 109.15131,109.76263 45 1 0 -155.2278,155.2278 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path2387"
+ d="m 600.83503,57.45593 c 41.03425,-30.62342 97.4773,-25.78914 132.46223,9.19579 -38.35331,-22.01434 -84.55112,-16.12058 -122.41132,12.1374 -27.91905,20.84373 -47.03623,47.51633 -49.36863,79.69142 -7.06749,-37.10273 6.9296,-76.84891 39.31771,-101.02461 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path2392"
+ d="M 592.59505,40.95755 C 633.64194,10.34676 687.34298,8.0176 722.3152,43.01523 683.9619,21.0009 634.46968,22.45676 596.59684,50.7021 c -27.93169,20.83111 -43.74174,51.92889 -46.07413,84.10398 -7.06748,-37.10273 9.6716,-69.68547 42.07235,-93.84853 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path2394"
+ d="m 580.58492,213.07206 c 8.08779,7.47793 17.18006,13.6734 26.92236,18.48605 -3.04283,0.74335 -5.99806,1.87921 -8.8151,3.43279 -6.9501,-6.54354 -13.08707,-13.90022 -18.10726,-21.91884 z m 11.37155,42.95682 c 10.47612,9.7138 26.178,12.81206 40.11936,6.62829 10.15048,-5.2483 18.46379,-10.47879 10.19272,-20.37614 2.97626,0.4098 5.97821,0.69282 8.98044,0.87448 0.53553,-1.21779 1.02052,-2.48613 1.40416,-3.75418 -0.0415,1.25443 -0.19716,2.54718 -0.36544,3.8273 17.41843,0.90159 35.34213,-2.18921 52.4168,-9.76274 31.8279,-14.11433 54.15086,-40.9099 63.58742,-71.79984 -1.37249,37.78512 -21.11769,80.65145 -58.04517,97.03524 -19.04095,8.45324 -39.69533,9.3978 -59.28244,4.72667 -5.28716,-3.15268 -5.27279,0.77491 -17.08681,7.38351 -15.12111,6.70654 -33.44481,-1.22426 -41.92104,-14.78259 z" />
+ <path
+ style="fill:#ececec"
+ d="m 647.03634,236.32559 c 22.88072,-7.61067 34.7814,-10.09358 61.83807,-21.55927 32.80025,-22.03566 47.53189,-52.61097 56.96846,-83.50091 -1.37249,37.78512 -21.11769,80.65145 -58.04517,97.03524 -40.30058,17.76825 -64.67554,8.61159 -60.76136,8.02494 z"
+ id="path2528"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#c4ccbe"
+ inkscape:connector-curvature="0"
+ id="path3289"
+ d="M 610.66836,131.5605 A 26.358341,28.663196 45 1 0 651.20424,91.02462 26.358341,28.663196 45 0 0 610.66836,131.5605 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3291"
+ d="m 616.77879,91.89856 c 10.61452,-8.08763 24.73949,-7.43023 33.19198,1.02225 -9.42461,-5.15562 -21.08619,-3.22259 -30.87545,4.24191 -7.23719,5.51889 -12.28634,12.41268 -13.19587,20.52388 -1.40584,-9.25768 2.49938,-19.37907 10.87933,-25.78804 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3293"
+ d="m 614.86428,87.84957 c 10.6146,-8.11296 24.13636,-9.22765 32.57614,-0.76246 -9.42458,-5.15563 -21.86868,-4.31001 -31.67062,3.16719 -7.22448,5.50619 -11.50378,13.47476 -12.40061,21.57326 -1.41855,-9.24498 3.11522,-17.59436 11.49509,-23.97799 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3295"
+ d="m 642.2833,141.72094 c -11.96344,5.67146 -25.96062,0.0852 -32.14013,-10.18545 7.84779,7.21253 19.96738,9.14251 30.99205,3.90444 8.13211,-3.86165 14.00499,-10.82109 16.67489,-18.67114 -0.71071,9.50432 -6.08796,20.46602 -15.52681,24.95215 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3297"
+ d="m 643.47532,132.26595 c -11.25789,7.08851 -25.15091,5.03679 -32.66349,-4.25452 8.78849,6.09496 19.79814,6.22892 30.193,-0.32504 7.65334,-4.82322 14.03414,-12.18951 15.71636,-20.23952 0.49311,9.43761 -4.34869,19.20686 -13.24588,24.81908 z" />
+ <path
+ id="path2255-5"
+ style="fill:#e99b4a;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 457.6962,165.34157 0,36.7642 26.42994,0 10.85514,38.38614 -80.70573,143.27223 39.64493,0 57.57952,-97.317 37.75707,109.2113 59.46737,-21.62602 -9.43926,-33.52027 -27.37389,9.73169 -64.18701,-184.90228 -50.02808,0 z"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#fbfbf7;fill-opacity:1"
+ inkscape:connector-curvature="0"
+ id="path2524"
+ d="m 592.65652,257.36261 a 35.279776,35.477364 45 1 0 50.17256,-50.17257 35.279776,35.477364 45 0 0 -50.17256,50.17257 z" />
+ <path
+ style="fill:#a2ae98"
+ inkscape:connector-curvature="0"
+ id="path3425"
+ d="m 616.23428,205.2186 c 13.09467,-2.43115 25.36479,4.57898 29.04525,15.95884 -6.04399,-8.88998 -17.2975,-12.4441 -29.39072,-10.20579 -8.91149,1.65929 -16.53681,5.51952 -21.01564,12.34837 2.93891,-8.90239 11.00456,-16.1847 21.36112,-18.10142 z" />
+ <path
+ style="fill:#ececec"
+ inkscape:connector-curvature="0"
+ id="path3427"
+ d="m 610.64453,201.53464 c 12.32921,-5.07701 25.66369,-2.64363 31.61487,7.72897 -7.74581,-7.44087 -19.97811,-9.83931 -31.35599,-5.15773 -8.40972,3.45699 -14.5983,10.04989 -17.58429,17.6601 1.05227,-9.31523 7.58384,-16.22583 17.3254,-20.23134 z" />
+ <path
+ style="fill:#ececec"
+ d="m 605.76803,254.22989 c 10.47613,9.7138 31.60604,-2.72358 41.76766,-16.49867 0,0 5.70421,-0.45504 -8.04842,19.26791 -4.03054,5.09183 -13.8578,17.09222 -33.71924,-2.76921 z"
+ id="path2528-8"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <g
+ id="g5190">
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path5137"
+ d="m 937.14068,-7.7167955 -6.08391,4.8107089 240.54523,75.3549016 -0.4075,-2.918744 z"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#787878;fill-opacity:1;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4150"
+ d="m 818.94116,5.2026955 c -0.29229,-0.1153077 -2.35517,0.3054801 -2.35517,0.3054801 l -2.95279,8.2073614 c 3.07091,7.617342 6.78428,15.488208 10.37968,23.312208 l 2.11411,1.212694 c 36.4223,68.353331 55.46431,109.598621 112.01396,203.717571 l 1.16047,-0.71178 C 898.0779,174.3516 828.9688,34.749076 828.9688,34.749076 c 0.25827,-0.0587 0.72945,-0.505187 0.57121,-0.985939 0,0 -9.09478,-20.220272 -9.09478,-20.220272 l -1.50192,-8.3424334 z"
+ style="fill:#777777;fill-opacity:1;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4174"
+ d="m 917.62673,23.735291 c 0,0 121.77467,112.372819 162.66457,147.374429 l 1.1896,-1.52322 C 1059.6975,152.95891 927.87133,27.227356 927.87133,27.227356 l 0.6206,-0.823456 -6.43964,-5.619804 c -1.08179,0.740429 -3.17482,1.165447 -4.10245,0.823639 l -0.32512,2.124011 z"
+ style="fill:#777777;fill-opacity:1;stroke:none" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path4176"
+ d="m 1151.4299,-134.49903 -0.2145,-2.39061 c -32.5473,1.6736 -281.83741,34.93472 -281.83741,34.93472 l -4.34575,0.75128 c -5.6179,16.905635 220.66866,-28.17687 286.39766,-33.29539 z"
+ style="fill:#777777;fill-opacity:1;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4178"
+ d="m 930.55319,-32.548475 c 0,0 157.83041,3.755633 226.56811,10.003361 l 9.2776,-0.130698 0.6034,-1.489176 -1.422,-0.162356 c -7.6921,-0.272863 -237.88276,-15.118424 -237.88276,-15.118424 1.08971,1.203513 2.11854,2.89347 2.85841,6.898525 z"
+ style="fill:#777777;fill-opacity:1;stroke:none" />
+ <path
+ transform="matrix(0.41485831,-0.01993231,0.02026452,0.42177261,736.80359,313.50603)"
+ d="m 576.27704,-798.61469 a 208.34631,208.34631 0 1 1 -416.69263,0 208.34631,208.34631 0 1 1 416.69263,0 z"
+ sodipodi:ry="208.34631"
+ sodipodi:rx="208.34631"
+ sodipodi:cy="-798.61469"
+ sodipodi:cx="367.93073"
+ id="path4616"
+ style="fill:#777777;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.50190154,0,0,0.50190154,243.91433,-188.39601)"
+ d="m 1256.725,224.69398 a 35.47731,35.47731 0 1 1 -70.9546,0 35.47731,35.47731 0 1 1 70.9546,0 z"
+ sodipodi:ry="35.47731"
+ sodipodi:rx="35.47731"
+ sodipodi:cy="224.69398"
+ sodipodi:cx="1221.2477"
+ id="path5111"
+ style="fill:#ececec;fill-opacity:0.97647005;fill-rule:nonzero;stroke:none"
+ sodipodi:type="arc" />
+ <path
+ inkscape:transform-center-y="254.9588"
+ inkscape:transform-center-x="22.693568"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="rect5145"
+ d="m 1176.6252,68.80541 c 0.9274,2.633527 -1.1442,6.475631 -3.3527,7.655075 -9.7843,-1.500395 -20.7497,-3.890343 -30.5339,-5.390738 3.2747,-6.559499 4.2071,-9.966553 6.4,-17.247252 8.4686,5.868813 19.0182,9.114104 27.4866,14.982915 z"
+ style="fill:#787878;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+</svg>
diff --git a/Data/DefaultContent/Libraries/luafun/doc/make.bat b/Data/DefaultContent/Libraries/luafun/doc/make.bat
new file mode 100644
index 0000000..0f68e89
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/make.bat
@@ -0,0 +1,190 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+set I18NSPHINXOPTS=%SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+ set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^<target^>` where ^<target^> is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. texinfo to make Texinfo files
+ echo. gettext to make PO message catalogs
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\LuaFunctional.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\LuaFunctional.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "texinfo" (
+ %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+ goto end
+)
+
+if "%1" == "gettext" (
+ %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+:end
diff --git a/Data/DefaultContent/Libraries/luafun/doc/operators.rst b/Data/DefaultContent/Libraries/luafun/doc/operators.rst
new file mode 100644
index 0000000..2f3edd4
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/operators.rst
@@ -0,0 +1,203 @@
+Operators
+=========
+
+.. module:: fun.operator
+
+This auxiliary module exports a set of Lua operators as intrinsic functions
+to use with the library high-order primitives.
+
+.. contents::
+
+.. note:: **op** can be used as a shortcut to **operator**.
+
+Comparison operators
+--------------------
+
+.. seealso:: `Lua Relational Operators
+ <http://www.lua.org/manual/5.2/manual.html#3.4.3>`_
+
+.. function:: le(a, b)
+
+ :returns: **a** <= **b**
+
+.. function:: lt(a, b)
+
+ :returns: **a** < **b**
+
+.. function:: eq(a, b)
+
+ :returns: **a** == **b**
+
+.. function:: ne(a, b)
+
+ :returns: **a** ~= **b**
+
+.. function:: ge(a, b)
+
+ :returns: **a** >= **b**
+
+.. function:: gt(a, b)
+
+ :returns: **a** > **b**
+
+Arithmetic operators
+--------------------
+
+.. seealso:: `Lua Arithmetic Operators
+ <http://www.lua.org/manual/5.2/manual.html#3.4.1>`_
+
+.. function:: add(a, b)
+
+ :returns: **a** + **b**
+
+.. function:: div(a, b)
+
+ An alias for :func:`truediv`.
+
+.. function:: truediv(a, b)
+
+ :returns: **a** / **b**
+
+ Performs "true" float division.
+ Examples:
+
+ .. code-block:: lua
+
+ > print(operator.div(10, 3))
+ 3.3333333333333
+ > print(operator.div(-10, 3))
+ -3.3333333333333
+
+.. function:: floordiv(a, b)
+
+ :returns: math.floor(**a** / **b**)
+
+ Performs division where a result is rounded down. Examples:
+
+ .. code-block:: lua
+
+ > print(operator.floordiv(10, 3))
+ 3
+ > print(operator.floordiv(12, 3))
+ 4
+ > print(operator.floordiv(-10, 3))
+ -4
+ > print(operator.floordiv(-12, 3))
+ -4
+
+.. function:: intdiv(a, b)
+
+ Performs C-like integer division.
+
+ Equvalent to:
+
+ .. code-block:: lua
+
+ function(a, b)
+ local q = a / b
+ if a >= 0 then return math.floor(q) else return math.ceil(q) end
+ end
+
+ Examples:
+
+ .. code-block:: lua
+
+ > print(operator.floordiv(10, 3))
+ 3
+ > print(operator.floordiv(12, 3))
+ 4
+ > print(operator.floordiv(-10, 3))
+ -3
+ > print(operator.floordiv(-12, 3))
+ -4
+
+.. function:: mod(a, b)
+
+ :returns: **a** % **b**
+
+ .. note:: Result has same sign as **divisor**. Modulo in Lua is defined as
+ ``a % b == a - math.floor(a/b)*b``.
+
+ Examples:
+
+ .. code-block:: lua
+ :emphasize-lines: 5-6
+
+ > print(operator.mod(10, 2))
+ 0
+ > print(operator.mod(10, 3))
+ 2
+ print(operator.mod(-10, 3))
+ 2 -- == -1 in C, Java, JavaScript and but not in Lua, Python, Haskell!
+
+.. function:: neq(a)
+
+ :returns: -**a**
+
+.. function:: unm(a)
+
+ Unary minus. An alias for :func:`neq`.
+
+.. function:: pow(a, b)
+
+ :returns: math.pow(**a**, **b**)
+
+.. function:: sub(a, b)
+
+ :returns: **a** - **b**
+
+String operators
+----------------
+
+.. seealso:: `Lua Concatenation Operator
+ <http://www.lua.org/manual/5.2/manual.html#3.4.5>`_
+
+.. function:: concat(a, b)
+
+ :returns: **a** .. **b**
+
+.. function:: len(a)
+
+ :returns: # **a**
+
+.. function:: length(a)
+
+ An alias for :func:`len`.
+
+Logical operators
+-----------------
+
+.. seealso:: `Lua Logical Operators
+ <http://www.lua.org/manual/5.2/manual.html#3.4.4>`_
+
+.. function:: land(a, b)
+
+ :returns: **a** and **b**
+
+.. function:: lor(a, b)
+
+ :returns: **a** or **b**
+
+.. function:: lnot(a)
+
+ :returns: not **a**
+
+.. function:: truth(a)
+
+ :returns: not not **a**
+
+ Return ``true`` if **a** is true, and ``false`` otherwise. Examples:
+
+ .. code-block:: lua
+
+ > print(operator.truth(1))
+ true
+ > print(operator.truth(0))
+ true -- It is Lua, baby!
+ > print(operator.truth(nil))
+ false
+ > print(operator.truth(""))
+ true
+ > print(operator.truth({}))
+ true
+
diff --git a/Data/DefaultContent/Libraries/luafun/doc/reducing.rst b/Data/DefaultContent/Libraries/luafun/doc/reducing.rst
new file mode 100644
index 0000000..f7b89da
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/reducing.rst
@@ -0,0 +1,323 @@
+Reducing
+========
+
+.. module:: fun
+
+The section contains functions to analyze iteration values and recombine
+through use of a given combining operation the results of recursively processing
+its constituent parts, building up a return value
+
+.. contents::
+
+.. note:: An attempt to use infinity iterators with the most function from
+ the module causes an infinite loop.
+
+Folds
+-----
+
+.. function:: foldl(accfun, initval, gen, param, state)
+ iterator:reduce(accfun, initval)
+
+ :param accfun: an accumulating function
+ :type param: (function(prevval, ...) -> val)
+ :param initval: an initial value that passed to **accfun** on the first
+ iteration
+
+ The function reduces the iterator from left to right using the binary
+ operator **accfun** and the initial value **initval**.
+ Equivalent to::
+
+ local val = initval
+ for _k, ... in gen, param, state do
+ val = accfun(val, ...)
+ end
+ return val
+
+ Examples:
+
+ .. code-block:: lua
+
+ > print(foldl(function(acc, x) return acc + x end, 0, range(5)))
+ 15
+
+ > print(foldl(operator.add, 0, range(5)))
+ 15
+
+ > print(foldl(function(acc, x, y) return acc + x * y; end, 0,
+ zip(range(1, 5), {4, 3, 2, 1})))
+ 20
+
+.. function:: reduce(accfun, initval, gen, param, state)
+ iterator:reduce(accfun, initval)
+
+ An alias to :func:`foldl`.
+
+.. function:: length(gen, param, state)
+ iterator:length()
+
+ :returns: a number of elements in ``gen, param, state`` iterator.
+
+ Return a number of elements in ``gen, param, state`` iterator.
+ This function is equivalent to ``#obj`` for basic array and string iterators.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > print(length({"a", "b", "c", "d", "e"}))
+ 5
+
+ > print(length({}))
+ 0
+
+ > print(length(range(0)))
+ 0
+
+ .. warning:: An attempt to call this function on an infinite iterator will
+ result an infinite loop.
+
+ .. note:: This function has ``O(n)`` complexity for all iterators except
+ basic array and string iterators.
+
+.. function:: totable(gen, param, state)
+
+ :returns: a new table (array) from iterated values.
+
+ The function reduces the iterator from left to right using ``table.insert``.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > local tab = totable("abcdef")
+ > print(type(tab), #tab)
+ table 6
+ > each(print, tab)
+ a
+ b
+ c
+ d
+ e
+ f
+
+.. function:: tomap(gen, param, state)
+
+ :returns: a new table (map) from iterated values.
+
+ The function reduces the iterator from left to right using
+ ``tab[val1] = val2`` expression.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > local tab = tomap(zip(range(1, 7), 'abcdef'))
+ > print(type(tab), #tab)
+ table 6
+ > each(print, iter(tab))
+ a
+ b
+ c
+ d
+ e
+ f
+
+Predicates
+----------
+
+.. function:: is_prefix_of(iterator1, iterator2)
+ iterator1:is_prefix_of(iterator2)
+
+ The function takes two iterators and returns ``true`` if the first iterator
+ is a prefix of the second.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > print(is_prefix_of({"a"}, {"a", "b", "c"}))
+ true
+
+ > print(is_prefix_of(range(6), range(5)))
+ false
+
+.. function:: is_null(gen, param, state)
+ iterator:is_null()
+
+ :returns: true when `gen, param, state`` iterator is empty or finished.
+ :returns: false otherwise.
+
+ Example::
+
+ > print(is_null({"a", "b", "c", "d", "e"}))
+ false
+
+ > print(is_null({}))
+ true
+
+ > print(is_null(range(0)))
+ true
+
+.. function:: all(predicate, gen, param, state)
+ iterator:all(predicate)
+
+ :param predicate: a predicate
+
+ Returns true if all return values of iterator satisfy the **predicate**.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > print(all(function(x) return x end, {true, true, true, true}))
+ true
+
+ > print(all(function(x) return x end, {true, true, true, false}))
+ false
+
+.. function:: every(predicate, gen, param, state)
+
+ An alias for :func:`all`.
+
+.. function:: any(predicate, gen, param, state)
+ iterator:any(predicate)
+
+ :param predicate: a predicate
+
+ Returns ``true`` if at least one return values of iterator satisfy the
+ **predicate**. The iteration stops on the first such value. Therefore,
+ infinity iterators that have at least one satisfying value might work.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > print(any(function(x) return x end, {false, false, false, false}))
+ false
+
+ > print(any(function(x) return x end, {false, false, false, true}))
+ true
+
+.. function:: some(predicate, gen, param, state)
+
+ An alias for :func:`any`.
+
+Special folds
+-------------
+
+.. function:: sum(gen, param, state)
+ iterator:sum()
+
+ Sum up all iteration values. An optimized alias for::
+
+ foldl(operator.add, 0, gen, param, state)
+
+ For an empty iterator ``0`` is returned.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > print(sum(range(5)))
+ 15
+
+.. function:: product(gen, param, state)
+ iterator:product()
+
+ Multiply all iteration values. An optimized alias for::
+
+ foldl(operator.mul, 1, gen, param, state)
+
+ For an empty iterator ``1`` is returned.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > print(product(range(1, 5)))
+ 120
+
+.. function:: min(gen, param, state)
+ iterator:min()
+
+ Return a minimum value from the iterator using :func:`operator.min` or ``<``
+ for numbers and other types respectivly. The iterator must be
+ non-null, otherwise an error is raised.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > print(min(range(1, 10, 1)))
+ 1
+
+ > print(min({"f", "d", "c", "d", "e"}))
+ c
+
+ > print(min({}))
+ error: min: iterator is empty
+
+.. function:: minimum(gen, param, state)
+
+ An alias for :func:`min`.
+
+.. function:: min_by(cmp, gen, param, state)
+ iterator:min_by(cmp)
+
+ Return a minimum value from the iterator using the **cmp** as a ``<``
+ operator. The iterator must be non-null, otherwise an error is raised.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > function min_cmp(a, b) if -a < -b then return a else return b end end
+ > print(min_by(min_cmp, range(1, 10, 1)))
+ 9
+
+.. function:: minimum_by(cmp, gen, param, state)
+
+ An alias for :func:`min_by`.
+
+.. function:: max(gen, param, state)
+ iterator:max()
+
+ Return a maximum value from the iterator using :func:`operator.max` or ``>``
+ for numbers and other types respectivly.
+
+ The iterator must be non-null, otherwise an error is raised.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > print(max(range(1, 10, 1)))
+ 9
+
+ > print(max({"f", "d", "c", "d", "e"}))
+ f
+
+ > print(max({}))
+ error: max: iterator is empty
+
+.. function:: maximum(gen, param, state)
+
+ An alias for :func:`max`.
+
+.. function:: max_by(cmp, gen, param, state)
+ iterator:max_by(cmp)
+
+ Return a maximum value from the iterator using the **cmp** as a `>`
+ operator. The iterator must be non-null, otherwise an error is raised.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > function max_cmp(a, b) if -a > -b then return a else return b end end
+ > print(max_by(max_cmp, range(1, 10, 1)))
+ 1
+
+.. function:: maximum_by(cmp, gen, param, state)
+
+ An alias for :func:`max_by`.
diff --git a/Data/DefaultContent/Libraries/luafun/doc/reference.rst b/Data/DefaultContent/Libraries/luafun/doc/reference.rst
new file mode 100644
index 0000000..f1f9cfc
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/reference.rst
@@ -0,0 +1,14 @@
+API Reference
+=============
+
+.. toctree::
+
+ basic.rst
+ generators.rst
+ slicing.rst
+ indexing.rst
+ filtering.rst
+ reducing.rst
+ transformations.rst
+ compositions.rst
+ operators.rst \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/luafun/doc/slicing.rst b/Data/DefaultContent/Libraries/luafun/doc/slicing.rst
new file mode 100644
index 0000000..1af642f
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/slicing.rst
@@ -0,0 +1,246 @@
+Slicing
+=======
+
+.. module:: fun
+
+This section contains functions to make subsequences from iterators.
+
+Basic
+-----
+
+.. function:: nth(n, gen, param, state)
+ iterator:nth(n)
+
+ :param uint n: a sequential number (indexed starting from ``1``,
+ like Lua tables)
+ :returns: **n**-th element of ``gen, param, state`` iterator
+
+ This function returns the **n**-th element of ``gen, param, state``
+ iterator. If the iterator does not have **n** items then ``nil`` is returned.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > print(nth(2, range(5)))
+ 2
+
+ > print(nth(10, range(5)))
+ nil
+
+ > print(nth(2, {"a", "b", "c", "d", "e"}))
+ b
+
+ > print(nth(2, enumerate({"a", "b", "c", "d", "e"})))
+ 2 b
+
+ This function is optimized for basic array and string iterators and has
+ ``O(1)`` complexity for these cases.
+
+.. function:: head(gen, param, state)
+ iterator:head()
+
+ :returns: a first element of ``gen, param, state`` iterator
+
+ Extract the first element of ``gen, param, state`` iterator.
+ If the iterator is empty then an error is raised.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > print(head({"a", "b", "c", "d", "e"}))
+ a
+ > print(head({}))
+ error: head: iterator is empty
+ > print(head(range(0)))
+ error: head: iterator is empty
+ > print(head(enumerate({"a", "b"})))
+ 1 a
+
+.. function:: car(gen, param, state)
+
+ An alias for :func:`head`.
+
+.. function:: tail(gen, param, state)
+ iterator:tail()
+
+ :returns: ``gen, param, state`` iterator without a first element
+
+ Return a copy of ``gen, param, state`` iterator without its first element.
+ If the iterator is empty then an empty iterator is returned.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, tail({"a", "b", "c", "d", "e"}))
+ b
+ c
+ d
+ e
+ > each(print, tail({}))
+ > each(print, tail(range(0)))
+ > each(print, tail(enumerate({"a", "b", "c"})))
+ 2 b
+ 3 c
+
+.. function:: cdr(gen, param, state)
+
+ An alias for :func:`tail`.
+
+Subsequences
+------------
+
+.. function:: take_n(n, gen, param, state)
+ iterator:take_n(n)
+
+ :param n: a number of elements to take
+ :type n: uint
+ :returns: an iterator on the subsequence of first **n** elements
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, take_n(5, range(10)))
+ 1
+ 2
+ 3
+ 4
+ 5
+
+ > each(print, take_n(5, enumerate(duplicate('x'))))
+ 1 x
+ 2 x
+ 3 x
+ 4 x
+ 5 x
+
+.. function:: take_while(predicate, gen, param, state)
+ iterator:take_while(predicate)
+
+ :type predicate: function(...) -> bool
+ :returns: an iterator on the longest prefix of ``gen, param, state``
+ elements that satisfy **predicate**.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, take_while(function(x) return x < 5 end, range(10)))
+ 1
+ 2
+ 3
+ 4
+
+ > each(print, take_while(function(i, a) return i ~=a end,
+ enumerate({5, 3, 4, 4, 2})))
+ 1 5
+ 2 3
+ 3 4
+
+ .. seealso:: :func:`filter`
+
+.. function:: take(n_or_predicate, gen, param, state)
+ iterator:take(n_or_predicate)
+
+ An alias for :func:`take_n` and :func:`take_while` that autodetects
+ required function based on **n_or_predicate** type.
+
+.. function:: drop_n(n, gen, param, state)
+ iterator:drop_n(n)
+
+ :param n: the number of elements to drop
+ :type n: uint
+ :returns: ``gen, param, state`` iterator after skipping first **n**
+ elements
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, drop_n(2, range(5)))
+ 3
+ 4
+ 5
+
+ > each(print, drop_n(2, enumerate({'a', 'b', 'c', 'd', 'e'})))
+ 3 c
+ 4 d
+ 5 e
+
+.. function:: drop_while(predicate, gen, param, state)
+ iterator:drop_while(predicate)
+
+ :type predicate: function(...) -> bool
+ :returns: ``gen, param, state`` after skipping the longest prefix
+ of elements that satisfy **predicate**.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, drop_while(function(x) return x < 5 end, range(10)))
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+
+ .. seealso:: :func:`filter`
+
+.. function:: drop(n_or_predicate, gen, param, state)
+ iterator:drop(n_or_predicate)
+
+ An alias for :func:`drop_n` and :func:`drop_while` that autodetects
+ required function based on **n_or_predicate** type.
+
+
+.. function:: span(n_or_predicate, gen, param, state)
+ iterator:span(n_or_predicate)
+
+ :type n_or_predicate: function(...) -> bool or uint
+ :returns: iterator, iterator
+
+ Return an iterator pair where the first operates on the longest prefix
+ (possibly empty) of ``gen, param, state`` iterator of elements that
+ satisfy **predicate** and second operates the remainder of
+ ``gen, param, state`` iterator.
+ Equivalent to:
+
+ .. code-block:: lua
+
+ return take(n_or_predicate, gen, param, state),
+ drop(n_or_predicate, gen, param, state);
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, zip(span(function(x) return x < 5 end, range(10))))
+ 1 5
+ 2 6
+ 3 7
+ 4 8
+
+ > each(print, zip(span(5, range(10))))
+ 1 6
+ 2 7
+ 3 8
+ 4 9
+ 5 10
+
+ .. note:: ``gen, param, state`` must be pure functional to work properly
+ with the function.
+
+ .. seealso:: :func:`partition`
+
+.. function:: split(n_or_predicate, gen, param, state)
+
+ An alias for :func:`span`.
+
+.. function:: split_at(n, gen, param, state)
+
+ An alias for :func:`span`.
diff --git a/Data/DefaultContent/Libraries/luafun/doc/transformations.rst b/Data/DefaultContent/Libraries/luafun/doc/transformations.rst
new file mode 100644
index 0000000..e446d2f
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/transformations.rst
@@ -0,0 +1,87 @@
+Transformations
+===============
+
+.. module:: fun
+
+.. function:: map(fun, gen, param, state)
+ iterator:map(fun)
+
+ :param fun: a function to apply
+ :type fun: (function(...) -> ...)
+ :returns: a new iterator
+
+ Return a new iterator by applying the **fun** to each element of
+ ``gen, param, state`` iterator. The mapping is performed on the fly
+ and no values are buffered.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, map(function(x) return 2 * x end, range(4)))
+ 2
+ 4
+ 6
+ 8
+
+ fun = function(...) return 'map', ... end
+ > each(print, map(fun, range(4)))
+ map 1
+ map 2
+ map 3
+ map 4
+
+.. function:: enumerate(gen, param, state)
+ iterator:enumerate()
+
+ :returns: a new iterator
+
+ Return a new iterator by enumerating all elements of the
+ ``gen, param, state`` iterator starting from ``1``. The mapping is performed
+ on the fly and no values are buffered.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, enumerate({"a", "b", "c", "d", "e"}))
+ 1 a
+ 2 b
+ 3 c
+ 4 d
+ 5 e
+
+ > each(print, enumerate(zip({"one", "two", "three", "four", "five"},
+ {"a", "b", "c", "d", "e"})))
+ 1 one a
+ 2 two b
+ 3 three c
+ 4 four d
+ 5 five e
+
+.. function:: intersperse(x, gen, param, state)
+ iterator:intersperse(x)
+
+ :type x: any
+ :returns: a new iterator
+
+ Return a new iterator where the **x** value is interspersed between the
+ elements of the source iterator. The **x** value can also be added as a
+ last element of returning iterator if the source iterator contains the odd
+ number of elements.
+
+ Examples:
+
+ .. code-block:: lua
+
+ > each(print, intersperse("x", {"a", "b", "c", "d", "e"}))
+ a
+ x
+ b
+ x
+ c
+ x
+ d
+ x
+ e
+ x
diff --git a/Data/DefaultContent/Libraries/luafun/doc/under_the_hood.rst b/Data/DefaultContent/Libraries/luafun/doc/under_the_hood.rst
new file mode 100644
index 0000000..802659e
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/doc/under_the_hood.rst
@@ -0,0 +1,154 @@
+Under the Hood
+==============
+
+.. module:: fun
+
+The section shed some light on the internal library structure and working
+principles.
+
+Iterators
+---------
+
+A basic primitive of the library after functions is an iterator. Most functions
+takes an iterator and returns a new iteraror(s). Iterators all the way down!
+[#iterators]_.
+
+The simplest iterator is (surprise!) :func:`pairs` and :func:`ipairs`
+Lua functions. Have you ever tried to call, say, :func:`ipairs` function
+without using it inside a ``for`` loop? Try to do that on any Lua
+implementation:
+
+.. _iterator_triplet:
+.. code-block:: bash
+
+ > =ipairs({'a', 'b', 'c'})
+ function: builtin#6 table: 0x40f80e38 0
+
+The function returned three strange values which look useless without a ``for``
+loop. We call these values **iterator triplet**.
+Let's see how each value is used for:
+
+``gen`` -- first value
+ A generating function that can produce a next value on each iteration.
+ Usually returns a new ``state`` and iteration values (multireturn).
+
+``param`` -- second value
+ A permanent (constant) parameter of a generating function is used to create
+ specific instance of the generating function. For example, a table itself
+ for ``ipairs`` case.
+
+``state`` -- third value
+ A some transient state of an iterator that is changed after each iteration.
+ For example, an array index for ``ipairs`` case.
+
+Try to call ``gen`` function manually:
+
+ .. code-block:: lua
+
+ > gen, param, state = ipairs({'a', 'b', 'c'})
+ > =gen(param, state)
+ 1 a
+
+The ``gen`` function returned a new state ``1`` and the next iteration
+value ``a``. The second call to ``gen`` with the new state will return the next
+state and the next iteration value. When the iterator finishes to the end
+the ``nil`` value is returned instead of the next state.
+
+**Please do not panic!** You do not have to use these values directly.
+It is just a nice trick to get ``for .. in`` loop working in Lua.
+
+Iterations
+----------
+
+What happens when you type the following code into a Lua console::
+
+ for _it, x in ipairs({'a', 'b', 'c'}) do print(x) end
+
+According to Lua reference manual [#lua_for]_ the code above is equivalent to::
+
+ do
+ -- Initialize the iterator
+ local gen, param, state = ipairs({'a', 'b', 'c'})
+ while true do
+ -- Next iteration
+ local state, var_1, ···, var_n = gen(param, state)
+ if state == nil then break end
+ -- Assign values to our variables
+ _it = state
+ x = var_1
+ -- Execute the code block
+ print(x)
+ end
+ end
+
+What does it mean for us?
+
+* An iterator can be used together with ``for .. in`` to generate a loop
+* An iterator is fully defined using ``gen``, ``param`` and ``state`` iterator
+ triplet
+* The ``nil`` state marks the end of an iteration
+* An iterator can return an arbitrary number of values (multireturn)
+* It is possible to make some wrapping functions to take an iterator and
+
+ return a new modified iterator
+
+**The library provides a set of iterators** that can be used like ``pairs``
+and ``ipairs``.
+
+Iterator Types
+--------------
+
+Pure functional iterators
+`````````````````````````
+
+Iterators can be either pure functional or have some side effects and returns
+different values for some initial conditions [#pure_function]_. An **iterator is
+pure functional** if it meets the following criteria:
+
+- ``gen`` function always returns the same values for the same ``param`` and
+ ``state`` values (idempotence property)
+- ``param`` and ``state`` values are not modified during ``gen`` call and
+ a new ``state`` object is returned instead (referential transparency
+ property).
+
+Pure functional iterators are very important for us. Pure functional iterator
+can be safety cloned or reapplied without creating side effects. Many library
+function use these properties.
+
+Finite iterators
+````````````````
+
+Iterators can be **finite** (sooner or later end up) or **infinite**
+(never end).
+Since there is no way to determine automatically if an iterator is finite or
+not [#turing]_ the library function can not automatically resolve infinite
+loops. It is your obligation to do not pass infinite iterator to reducing
+functions.
+
+Tracing JIT
+-----------
+
+Tracing just-in-time compilation is a technique used by virtual machines to
+optimize the execution of a program at runtime. This is done by recording a
+linear sequence of frequently executed operations, compiling them to native
+machine code and executing them.
+
+First profiling information for loops is collected. After a hot loop has been
+identified, a special tracing mode is entered which records all executed
+operations of that loop. This sequence of operations is called a **trace**.
+The trace is then optimized and compiled to machine code (trace). When this
+loop is executed again the compiled trace is called instead of the program
+counterpart [#tracing_jit]_.
+
+Why the tracing JIT is important for us? The LuaJIT tracing compiler can detect
+tail-, up- and down-recursion [#luajit-recursion]_, unroll compositions of
+functions and inline high-order functions [#luajit-optimizations]_.
+All of these concepts make the foundation for functional programming.
+
+.. [#iterators] http://en.wikipedia.org/wiki/Turtles_all_the_way_down
+.. [#lua_for] http://www.lua.org/manual/5.2/manual.html#3.3.5
+.. [#pure_function] http://en.wikipedia.org/wiki/Pure_function
+.. [#turing] `Proved by Turing <http://en.wikipedia.org/wiki/Halting_problem>`_
+.. [#tracing_jit] http://en.wikipedia.org/wiki/Tracing_just-in-time_compilation
+.. [#luajit-recursion] http://lambda-the-ultimate.org/node/3851#comment-57679
+.. [#luajit-optimizations] http://wiki.luajit.org/Optimizations
diff --git a/Data/DefaultContent/Libraries/luafun/fun-scm-1.rockspec b/Data/DefaultContent/Libraries/luafun/fun-scm-1.rockspec
new file mode 100644
index 0000000..8f22022
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/fun-scm-1.rockspec
@@ -0,0 +1,34 @@
+package = "fun"
+version = "scm-1"
+
+source = {
+ url = "git://github.com/luafun/luafun.git",
+}
+
+description = {
+ summary = "High-performance functional programming library for Lua",
+ homepage = "https://luafun.github.io/",
+ license = "MIT/X11",
+ maintainer = "Roman Tsisyk <roman@tarantool.org>",
+ detailed = [[
+Lua Fun is a high-performance functional programming library for Lua
+designed with LuaJIT's trace compiler in mind.
+
+Lua Fun provides a set of more than 50 programming primitives typically
+found in languages like Standard ML, Haskell, Erlang, JavaScript, Python and
+even Lisp. High-order functions such as map, filter, reduce, zip, etc.,
+make it easy to write simple and efficient functional code.
+]]
+}
+
+dependencies = {
+ "lua"
+}
+
+build = {
+ type = "builtin",
+ modules = {
+ fun = "fun.lua",
+ },
+ copy_directories = { "tests" },
+}
diff --git a/Data/DefaultContent/Libraries/luafun/fun.lua b/Data/DefaultContent/Libraries/luafun/fun.lua
new file mode 100644
index 0000000..2427bb2
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/fun.lua
@@ -0,0 +1,1058 @@
+---
+--- Lua Fun - a high-performance functional programming library for LuaJIT
+---
+--- Copyright (c) 2013-2017 Roman Tsisyk <roman@tsisyk.com>
+---
+--- Distributed under the MIT/X11 License. See COPYING.md for more details.
+---
+
+local exports = {}
+local methods = {}
+
+-- compatibility with Lua 5.1/5.2
+local unpack = rawget(table, "unpack") or unpack
+
+--------------------------------------------------------------------------------
+-- Tools
+--------------------------------------------------------------------------------
+
+local return_if_not_empty = function(state_x, ...)
+ if state_x == nil then
+ return nil
+ end
+ return ...
+end
+
+local call_if_not_empty = function(fun, state_x, ...)
+ if state_x == nil then
+ return nil
+ end
+ return state_x, fun(...)
+end
+
+local function deepcopy(orig) -- used by cycle()
+ local orig_type = type(orig)
+ local copy
+ if orig_type == 'table' then
+ copy = {}
+ for orig_key, orig_value in next, orig, nil do
+ copy[deepcopy(orig_key)] = deepcopy(orig_value)
+ end
+ else
+ copy = orig
+ end
+ return copy
+end
+
+local iterator_mt = {
+ -- usually called by for-in loop
+ __call = function(self, param, state)
+ return self.gen(param, state)
+ end;
+ __tostring = function(self)
+ return '<generator>'
+ end;
+ -- add all exported methods
+ __index = methods;
+}
+
+local wrap = function(gen, param, state)
+ return setmetatable({
+ gen = gen,
+ param = param,
+ state = state
+ }, iterator_mt), param, state
+end
+exports.wrap = wrap
+
+local unwrap = function(self)
+ return self.gen, self.param, self.state
+end
+methods.unwrap = unwrap
+
+--------------------------------------------------------------------------------
+-- Basic Functions
+--------------------------------------------------------------------------------
+
+local nil_gen = function(_param, _state)
+ return nil
+end
+
+local string_gen = function(param, state)
+ local state = state + 1
+ if state > #param then
+ return nil
+ end
+ local r = string.sub(param, state, state)
+ return state, r
+end
+
+local ipairs_gen = ipairs({}) -- get the generating function from ipairs
+
+local pairs_gen = pairs({ a = 0 }) -- get the generating function from pairs
+local map_gen = function(tab, key)
+ local value
+ local key, value = pairs_gen(tab, key)
+ return key, key, value
+end
+
+local rawiter = function(obj, param, state)
+ assert(obj ~= nil, "invalid iterator")
+ if type(obj) == "table" then
+ local mt = getmetatable(obj);
+ if mt ~= nil then
+ if mt == iterator_mt then
+ return obj.gen, obj.param, obj.state
+ elseif mt.__ipairs ~= nil then
+ return mt.__ipairs(obj)
+ elseif mt.__pairs ~= nil then
+ return mt.__pairs(obj)
+ end
+ end
+ if #obj > 0 then
+ -- array
+ return ipairs(obj)
+ else
+ -- hash
+ return map_gen, obj, nil
+ end
+ elseif (type(obj) == "function") then
+ return obj, param, state
+ elseif (type(obj) == "string") then
+ if #obj == 0 then
+ return nil_gen, nil, nil
+ end
+ return string_gen, obj, 0
+ end
+ error(string.format('object %s of type "%s" is not iterable',
+ obj, type(obj)))
+end
+
+local iter = function(obj, param, state)
+ return wrap(rawiter(obj, param, state))
+end
+exports.iter = iter
+
+local method0 = function(fun)
+ return function(self)
+ return fun(self.gen, self.param, self.state)
+ end
+end
+
+local method1 = function(fun)
+ return function(self, arg1)
+ return fun(arg1, self.gen, self.param, self.state)
+ end
+end
+
+local method2 = function(fun)
+ return function(self, arg1, arg2)
+ return fun(arg1, arg2, self.gen, self.param, self.state)
+ end
+end
+
+local export0 = function(fun)
+ return function(gen, param, state)
+ return fun(rawiter(gen, param, state))
+ end
+end
+
+local export1 = function(fun)
+ return function(arg1, gen, param, state)
+ return fun(arg1, rawiter(gen, param, state))
+ end
+end
+
+local export2 = function(fun)
+ return function(arg1, arg2, gen, param, state)
+ return fun(arg1, arg2, rawiter(gen, param, state))
+ end
+end
+
+local each = function(fun, gen, param, state)
+ repeat
+ state = call_if_not_empty(fun, gen(param, state))
+ until state == nil
+end
+methods.each = method1(each)
+exports.each = export1(each)
+methods.for_each = methods.each
+exports.for_each = exports.each
+methods.foreach = methods.each
+exports.foreach = exports.each
+
+--------------------------------------------------------------------------------
+-- Generators
+--------------------------------------------------------------------------------
+
+local range_gen = function(param, state)
+ local stop, step = param[1], param[2]
+ local state = state + step
+ if state > stop then
+ return nil
+ end
+ return state, state
+end
+
+local range_rev_gen = function(param, state)
+ local stop, step = param[1], param[2]
+ local state = state + step
+ if state < stop then
+ return nil
+ end
+ return state, state
+end
+
+local range = function(start, stop, step)
+ if step == nil then
+ if stop == nil then
+ if start == 0 then
+ return nil_gen, nil, nil
+ end
+ stop = start
+ start = stop > 0 and 1 or -1
+ end
+ step = start <= stop and 1 or -1
+ end
+
+ assert(type(start) == "number", "start must be a number")
+ assert(type(stop) == "number", "stop must be a number")
+ assert(type(step) == "number", "step must be a number")
+ assert(step ~= 0, "step must not be zero")
+
+ if (step > 0) then
+ return wrap(range_gen, {stop, step}, start - step)
+ elseif (step < 0) then
+ return wrap(range_rev_gen, {stop, step}, start - step)
+ end
+end
+exports.range = range
+
+local duplicate_table_gen = function(param_x, state_x)
+ return state_x + 1, unpack(param_x)
+end
+
+local duplicate_fun_gen = function(param_x, state_x)
+ return state_x + 1, param_x(state_x)
+end
+
+local duplicate_gen = function(param_x, state_x)
+ return state_x + 1, param_x
+end
+
+local duplicate = function(...)
+ if select('#', ...) <= 1 then
+ return wrap(duplicate_gen, select(1, ...), 0)
+ else
+ return wrap(duplicate_table_gen, {...}, 0)
+ end
+end
+exports.duplicate = duplicate
+exports.replicate = duplicate
+exports.xrepeat = duplicate
+
+local tabulate = function(fun)
+ assert(type(fun) == "function")
+ return wrap(duplicate_fun_gen, fun, 0)
+end
+exports.tabulate = tabulate
+
+local zeros = function()
+ return wrap(duplicate_gen, 0, 0)
+end
+exports.zeros = zeros
+
+local ones = function()
+ return wrap(duplicate_gen, 1, 0)
+end
+exports.ones = ones
+
+local rands_gen = function(param_x, _state_x)
+ return 0, math.random(param_x[1], param_x[2])
+end
+
+local rands_nil_gen = function(_param_x, _state_x)
+ return 0, math.random()
+end
+
+local rands = function(n, m)
+ if n == nil and m == nil then
+ return wrap(rands_nil_gen, 0, 0)
+ end
+ assert(type(n) == "number", "invalid first arg to rands")
+ if m == nil then
+ m = n
+ n = 0
+ else
+ assert(type(m) == "number", "invalid second arg to rands")
+ end
+ assert(n < m, "empty interval")
+ return wrap(rands_gen, {n, m - 1}, 0)
+end
+exports.rands = rands
+
+--------------------------------------------------------------------------------
+-- Slicing
+--------------------------------------------------------------------------------
+
+local nth = function(n, gen_x, param_x, state_x)
+ assert(n > 0, "invalid first argument to nth")
+ -- An optimization for arrays and strings
+ if gen_x == ipairs_gen then
+ return param_x[n]
+ elseif gen_x == string_gen then
+ if n <= #param_x then
+ return string.sub(param_x, n, n)
+ else
+ return nil
+ end
+ end
+ for i=1,n-1,1 do
+ state_x = gen_x(param_x, state_x)
+ if state_x == nil then
+ return nil
+ end
+ end
+ return return_if_not_empty(gen_x(param_x, state_x))
+end
+methods.nth = method1(nth)
+exports.nth = export1(nth)
+
+local head_call = function(state, ...)
+ if state == nil then
+ error("head: iterator is empty")
+ end
+ return ...
+end
+
+local head = function(gen, param, state)
+ return head_call(gen(param, state))
+end
+methods.head = method0(head)
+exports.head = export0(head)
+exports.car = exports.head
+methods.car = methods.head
+
+local tail = function(gen, param, state)
+ state = gen(param, state)
+ if state == nil then
+ return wrap(nil_gen, nil, nil)
+ end
+ return wrap(gen, param, state)
+end
+methods.tail = method0(tail)
+exports.tail = export0(tail)
+exports.cdr = exports.tail
+methods.cdr = methods.tail
+
+local take_n_gen_x = function(i, state_x, ...)
+ if state_x == nil then
+ return nil
+ end
+ return {i, state_x}, ...
+end
+
+local take_n_gen = function(param, state)
+ local n, gen_x, param_x = param[1], param[2], param[3]
+ local i, state_x = state[1], state[2]
+ if i >= n then
+ return nil
+ end
+ return take_n_gen_x(i + 1, gen_x(param_x, state_x))
+end
+
+local take_n = function(n, gen, param, state)
+ assert(n >= 0, "invalid first argument to take_n")
+ return wrap(take_n_gen, {n, gen, param}, {0, state})
+end
+methods.take_n = method1(take_n)
+exports.take_n = export1(take_n)
+
+local take_while_gen_x = function(fun, state_x, ...)
+ if state_x == nil or not fun(...) then
+ return nil
+ end
+ return state_x, ...
+end
+
+local take_while_gen = function(param, state_x)
+ local fun, gen_x, param_x = param[1], param[2], param[3]
+ return take_while_gen_x(fun, gen_x(param_x, state_x))
+end
+
+local take_while = function(fun, gen, param, state)
+ assert(type(fun) == "function", "invalid first argument to take_while")
+ return wrap(take_while_gen, {fun, gen, param}, state)
+end
+methods.take_while = method1(take_while)
+exports.take_while = export1(take_while)
+
+local take = function(n_or_fun, gen, param, state)
+ if type(n_or_fun) == "number" then
+ return take_n(n_or_fun, gen, param, state)
+ else
+ return take_while(n_or_fun, gen, param, state)
+ end
+end
+methods.take = method1(take)
+exports.take = export1(take)
+
+local drop_n = function(n, gen, param, state)
+ assert(n >= 0, "invalid first argument to drop_n")
+ local i
+ for i=1,n,1 do
+ state = gen(param, state)
+ if state == nil then
+ return wrap(nil_gen, nil, nil)
+ end
+ end
+ return wrap(gen, param, state)
+end
+methods.drop_n = method1(drop_n)
+exports.drop_n = export1(drop_n)
+
+local drop_while_x = function(fun, state_x, ...)
+ if state_x == nil or not fun(...) then
+ return state_x, false
+ end
+ return state_x, true, ...
+end
+
+local drop_while = function(fun, gen_x, param_x, state_x)
+ assert(type(fun) == "function", "invalid first argument to drop_while")
+ local cont, state_x_prev
+ repeat
+ state_x_prev = deepcopy(state_x)
+ state_x, cont = drop_while_x(fun, gen_x(param_x, state_x))
+ until not cont
+ if state_x == nil then
+ return wrap(nil_gen, nil, nil)
+ end
+ return wrap(gen_x, param_x, state_x_prev)
+end
+methods.drop_while = method1(drop_while)
+exports.drop_while = export1(drop_while)
+
+local drop = function(n_or_fun, gen_x, param_x, state_x)
+ if type(n_or_fun) == "number" then
+ return drop_n(n_or_fun, gen_x, param_x, state_x)
+ else
+ return drop_while(n_or_fun, gen_x, param_x, state_x)
+ end
+end
+methods.drop = method1(drop)
+exports.drop = export1(drop)
+
+local split = function(n_or_fun, gen_x, param_x, state_x)
+ return take(n_or_fun, gen_x, param_x, state_x),
+ drop(n_or_fun, gen_x, param_x, state_x)
+end
+methods.split = method1(split)
+exports.split = export1(split)
+methods.split_at = methods.split
+exports.split_at = exports.split
+methods.span = methods.split
+exports.span = exports.split
+
+--------------------------------------------------------------------------------
+-- Indexing
+--------------------------------------------------------------------------------
+
+local index = function(x, gen, param, state)
+ local i = 1
+ for _k, r in gen, param, state do
+ if r == x then
+ return i
+ end
+ i = i + 1
+ end
+ return nil
+end
+methods.index = method1(index)
+exports.index = export1(index)
+methods.index_of = methods.index
+exports.index_of = exports.index
+methods.elem_index = methods.index
+exports.elem_index = exports.index
+
+local indexes_gen = function(param, state)
+ local x, gen_x, param_x = param[1], param[2], param[3]
+ local i, state_x = state[1], state[2]
+ local r
+ while true do
+ state_x, r = gen_x(param_x, state_x)
+ if state_x == nil then
+ return nil
+ end
+ i = i + 1
+ if r == x then
+ return {i, state_x}, i
+ end
+ end
+end
+
+local indexes = function(x, gen, param, state)
+ return wrap(indexes_gen, {x, gen, param}, {0, state})
+end
+methods.indexes = method1(indexes)
+exports.indexes = export1(indexes)
+methods.elem_indexes = methods.indexes
+exports.elem_indexes = exports.indexes
+methods.indices = methods.indexes
+exports.indices = exports.indexes
+methods.elem_indices = methods.indexes
+exports.elem_indices = exports.indexes
+
+--------------------------------------------------------------------------------
+-- Filtering
+--------------------------------------------------------------------------------
+
+local filter1_gen = function(fun, gen_x, param_x, state_x, a)
+ while true do
+ if state_x == nil or fun(a) then break; end
+ state_x, a = gen_x(param_x, state_x)
+ end
+ return state_x, a
+end
+
+-- call each other
+local filterm_gen
+local filterm_gen_shrink = function(fun, gen_x, param_x, state_x)
+ return filterm_gen(fun, gen_x, param_x, gen_x(param_x, state_x))
+end
+
+filterm_gen = function(fun, gen_x, param_x, state_x, ...)
+ if state_x == nil then
+ return nil
+ end
+ if fun(...) then
+ return state_x, ...
+ end
+ return filterm_gen_shrink(fun, gen_x, param_x, state_x)
+end
+
+local filter_detect = function(fun, gen_x, param_x, state_x, ...)
+ if select('#', ...) < 2 then
+ return filter1_gen(fun, gen_x, param_x, state_x, ...)
+ else
+ return filterm_gen(fun, gen_x, param_x, state_x, ...)
+ end
+end
+
+local filter_gen = function(param, state_x)
+ local fun, gen_x, param_x = param[1], param[2], param[3]
+ return filter_detect(fun, gen_x, param_x, gen_x(param_x, state_x))
+end
+
+local filter = function(fun, gen, param, state)
+ return wrap(filter_gen, {fun, gen, param}, state)
+end
+methods.filter = method1(filter)
+exports.filter = export1(filter)
+methods.remove_if = methods.filter
+exports.remove_if = exports.filter
+
+local grep = function(fun_or_regexp, gen, param, state)
+ local fun = fun_or_regexp
+ if type(fun_or_regexp) == "string" then
+ fun = function(x) return string.find(x, fun_or_regexp) ~= nil end
+ end
+ return filter(fun, gen, param, state)
+end
+methods.grep = method1(grep)
+exports.grep = export1(grep)
+
+local partition = function(fun, gen, param, state)
+ local neg_fun = function(...)
+ return not fun(...)
+ end
+ return filter(fun, gen, param, state),
+ filter(neg_fun, gen, param, state)
+end
+methods.partition = method1(partition)
+exports.partition = export1(partition)
+
+--------------------------------------------------------------------------------
+-- Reducing
+--------------------------------------------------------------------------------
+
+local foldl_call = function(fun, start, state, ...)
+ if state == nil then
+ return nil, start
+ end
+ return state, fun(start, ...)
+end
+
+local foldl = function(fun, start, gen_x, param_x, state_x)
+ while true do
+ state_x, start = foldl_call(fun, start, gen_x(param_x, state_x))
+ if state_x == nil then
+ break;
+ end
+ end
+ return start
+end
+methods.foldl = method2(foldl)
+exports.foldl = export2(foldl)
+methods.reduce = methods.foldl
+exports.reduce = exports.foldl
+
+local length = function(gen, param, state)
+ if gen == ipairs_gen or gen == string_gen then
+ return #param
+ end
+ local len = 0
+ repeat
+ state = gen(param, state)
+ len = len + 1
+ until state == nil
+ return len - 1
+end
+methods.length = method0(length)
+exports.length = export0(length)
+
+local is_null = function(gen, param, state)
+ return gen(param, deepcopy(state)) == nil
+end
+methods.is_null = method0(is_null)
+exports.is_null = export0(is_null)
+
+local is_prefix_of = function(iter_x, iter_y)
+ local gen_x, param_x, state_x = iter(iter_x)
+ local gen_y, param_y, state_y = iter(iter_y)
+
+ local r_x, r_y
+ for i=1,10,1 do
+ state_x, r_x = gen_x(param_x, state_x)
+ state_y, r_y = gen_y(param_y, state_y)
+ if state_x == nil then
+ return true
+ end
+ if state_y == nil or r_x ~= r_y then
+ return false
+ end
+ end
+end
+methods.is_prefix_of = is_prefix_of
+exports.is_prefix_of = is_prefix_of
+
+local all = function(fun, gen_x, param_x, state_x)
+ local r
+ repeat
+ state_x, r = call_if_not_empty(fun, gen_x(param_x, state_x))
+ until state_x == nil or not r
+ return state_x == nil
+end
+methods.all = method1(all)
+exports.all = export1(all)
+methods.every = methods.all
+exports.every = exports.all
+
+local any = function(fun, gen_x, param_x, state_x)
+ local r
+ repeat
+ state_x, r = call_if_not_empty(fun, gen_x(param_x, state_x))
+ until state_x == nil or r
+ return not not r
+end
+methods.any = method1(any)
+exports.any = export1(any)
+methods.some = methods.any
+exports.some = exports.any
+
+local sum = function(gen, param, state)
+ local s = 0
+ local r = 0
+ repeat
+ s = s + r
+ state, r = gen(param, state)
+ until state == nil
+ return s
+end
+methods.sum = method0(sum)
+exports.sum = export0(sum)
+
+local product = function(gen, param, state)
+ local p = 1
+ local r = 1
+ repeat
+ p = p * r
+ state, r = gen(param, state)
+ until state == nil
+ return p
+end
+methods.product = method0(product)
+exports.product = export0(product)
+
+local min_cmp = function(m, n)
+ if n < m then return n else return m end
+end
+
+local max_cmp = function(m, n)
+ if n > m then return n else return m end
+end
+
+local min = function(gen, param, state)
+ local state, m = gen(param, state)
+ if state == nil then
+ error("min: iterator is empty")
+ end
+
+ local cmp
+ if type(m) == "number" then
+ -- An optimization: use math.min for numbers
+ cmp = math.min
+ else
+ cmp = min_cmp
+ end
+
+ for _, r in gen, param, state do
+ m = cmp(m, r)
+ end
+ return m
+end
+methods.min = method0(min)
+exports.min = export0(min)
+methods.minimum = methods.min
+exports.minimum = exports.min
+
+local min_by = function(cmp, gen_x, param_x, state_x)
+ local state_x, m = gen_x(param_x, state_x)
+ if state_x == nil then
+ error("min: iterator is empty")
+ end
+
+ for _, r in gen_x, param_x, state_x do
+ m = cmp(m, r)
+ end
+ return m
+end
+methods.min_by = method1(min_by)
+exports.min_by = export1(min_by)
+methods.minimum_by = methods.min_by
+exports.minimum_by = exports.min_by
+
+local max = function(gen_x, param_x, state_x)
+ local state_x, m = gen_x(param_x, state_x)
+ if state_x == nil then
+ error("max: iterator is empty")
+ end
+
+ local cmp
+ if type(m) == "number" then
+ -- An optimization: use math.max for numbers
+ cmp = math.max
+ else
+ cmp = max_cmp
+ end
+
+ for _, r in gen_x, param_x, state_x do
+ m = cmp(m, r)
+ end
+ return m
+end
+methods.max = method0(max)
+exports.max = export0(max)
+methods.maximum = methods.max
+exports.maximum = exports.max
+
+local max_by = function(cmp, gen_x, param_x, state_x)
+ local state_x, m = gen_x(param_x, state_x)
+ if state_x == nil then
+ error("max: iterator is empty")
+ end
+
+ for _, r in gen_x, param_x, state_x do
+ m = cmp(m, r)
+ end
+ return m
+end
+methods.max_by = method1(max_by)
+exports.max_by = export1(max_by)
+methods.maximum_by = methods.maximum_by
+exports.maximum_by = exports.maximum_by
+
+local totable = function(gen_x, param_x, state_x)
+ local tab, key, val = {}
+ while true do
+ state_x, val = gen_x(param_x, state_x)
+ if state_x == nil then
+ break
+ end
+ table.insert(tab, val)
+ end
+ return tab
+end
+methods.totable = method0(totable)
+exports.totable = export0(totable)
+
+local tomap = function(gen_x, param_x, state_x)
+ local tab, key, val = {}
+ while true do
+ state_x, key, val = gen_x(param_x, state_x)
+ if state_x == nil then
+ break
+ end
+ tab[key] = val
+ end
+ return tab
+end
+methods.tomap = method0(tomap)
+exports.tomap = export0(tomap)
+
+--------------------------------------------------------------------------------
+-- Transformations
+--------------------------------------------------------------------------------
+
+local map_gen = function(param, state)
+ local gen_x, param_x, fun = param[1], param[2], param[3]
+ return call_if_not_empty(fun, gen_x(param_x, state))
+end
+
+local map = function(fun, gen, param, state)
+ return wrap(map_gen, {gen, param, fun}, state)
+end
+methods.map = method1(map)
+exports.map = export1(map)
+
+local enumerate_gen_call = function(state, i, state_x, ...)
+ if state_x == nil then
+ return nil
+ end
+ return {i + 1, state_x}, i, ...
+end
+
+local enumerate_gen = function(param, state)
+ local gen_x, param_x = param[1], param[2]
+ local i, state_x = state[1], state[2]
+ return enumerate_gen_call(state, i, gen_x(param_x, state_x))
+end
+
+local enumerate = function(gen, param, state)
+ return wrap(enumerate_gen, {gen, param}, {1, state})
+end
+methods.enumerate = method0(enumerate)
+exports.enumerate = export0(enumerate)
+
+local intersperse_call = function(i, state_x, ...)
+ if state_x == nil then
+ return nil
+ end
+ return {i + 1, state_x}, ...
+end
+
+local intersperse_gen = function(param, state)
+ local x, gen_x, param_x = param[1], param[2], param[3]
+ local i, state_x = state[1], state[2]
+ if i % 2 == 1 then
+ return {i + 1, state_x}, x
+ else
+ return intersperse_call(i, gen_x(param_x, state_x))
+ end
+end
+
+-- TODO: interperse must not add x to the tail
+local intersperse = function(x, gen, param, state)
+ return wrap(intersperse_gen, {x, gen, param}, {0, state})
+end
+methods.intersperse = method1(intersperse)
+exports.intersperse = export1(intersperse)
+
+--------------------------------------------------------------------------------
+-- Compositions
+--------------------------------------------------------------------------------
+
+local function zip_gen_r(param, state, state_new, ...)
+ if #state_new == #param / 2 then
+ return state_new, ...
+ end
+
+ local i = #state_new + 1
+ local gen_x, param_x = param[2 * i - 1], param[2 * i]
+ local state_x, r = gen_x(param_x, state[i])
+ if state_x == nil then
+ return nil
+ end
+ table.insert(state_new, state_x)
+ return zip_gen_r(param, state, state_new, r, ...)
+end
+
+local zip_gen = function(param, state)
+ return zip_gen_r(param, state, {})
+end
+
+-- A special hack for zip/chain to skip last two state, if a wrapped iterator
+-- has been passed
+local numargs = function(...)
+ local n = select('#', ...)
+ if n >= 3 then
+ -- Fix last argument
+ local it = select(n - 2, ...)
+ if type(it) == 'table' and getmetatable(it) == iterator_mt and
+ it.param == select(n - 1, ...) and it.state == select(n, ...) then
+ return n - 2
+ end
+ end
+ return n
+end
+
+local zip = function(...)
+ local n = numargs(...)
+ if n == 0 then
+ return wrap(nil_gen, nil, nil)
+ end
+ local param = { [2 * n] = 0 }
+ local state = { [n] = 0 }
+
+ local i, gen_x, param_x, state_x
+ for i=1,n,1 do
+ local it = select(n - i + 1, ...)
+ gen_x, param_x, state_x = rawiter(it)
+ param[2 * i - 1] = gen_x
+ param[2 * i] = param_x
+ state[i] = state_x
+ end
+
+ return wrap(zip_gen, param, state)
+end
+methods.zip = zip
+exports.zip = zip
+
+local cycle_gen_call = function(param, state_x, ...)
+ if state_x == nil then
+ local gen_x, param_x, state_x0 = param[1], param[2], param[3]
+ return gen_x(param_x, deepcopy(state_x0))
+ end
+ return state_x, ...
+end
+
+local cycle_gen = function(param, state_x)
+ local gen_x, param_x, state_x0 = param[1], param[2], param[3]
+ return cycle_gen_call(param, gen_x(param_x, state_x))
+end
+
+local cycle = function(gen, param, state)
+ return wrap(cycle_gen, {gen, param, state}, deepcopy(state))
+end
+methods.cycle = method0(cycle)
+exports.cycle = export0(cycle)
+
+-- call each other
+local chain_gen_r1
+local chain_gen_r2 = function(param, state, state_x, ...)
+ if state_x == nil then
+ local i = state[1]
+ i = i + 1
+ if param[3 * i - 1] == nil then
+ return nil
+ end
+ local state_x = param[3 * i]
+ return chain_gen_r1(param, {i, state_x})
+ end
+ return {state[1], state_x}, ...
+end
+
+chain_gen_r1 = function(param, state)
+ local i, state_x = state[1], state[2]
+ local gen_x, param_x = param[3 * i - 2], param[3 * i - 1]
+ return chain_gen_r2(param, state, gen_x(param_x, state[2]))
+end
+
+local chain = function(...)
+ local n = numargs(...)
+ if n == 0 then
+ return wrap(nil_gen, nil, nil)
+ end
+
+ local param = { [3 * n] = 0 }
+ local i, gen_x, param_x, state_x
+ for i=1,n,1 do
+ local elem = select(i, ...)
+ gen_x, param_x, state_x = iter(elem)
+ param[3 * i - 2] = gen_x
+ param[3 * i - 1] = param_x
+ param[3 * i] = state_x
+ end
+
+ return wrap(chain_gen_r1, param, {1, param[3]})
+end
+methods.chain = chain
+exports.chain = chain
+
+--------------------------------------------------------------------------------
+-- Operators
+--------------------------------------------------------------------------------
+
+local operator = {
+ ----------------------------------------------------------------------------
+ -- Comparison operators
+ ----------------------------------------------------------------------------
+ lt = function(a, b) return a < b end,
+ le = function(a, b) return a <= b end,
+ eq = function(a, b) return a == b end,
+ ne = function(a, b) return a ~= b end,
+ ge = function(a, b) return a >= b end,
+ gt = function(a, b) return a > b end,
+
+ ----------------------------------------------------------------------------
+ -- Arithmetic operators
+ ----------------------------------------------------------------------------
+ add = function(a, b) return a + b end,
+ div = function(a, b) return a / b end,
+ floordiv = function(a, b) return math.floor(a/b) end,
+ intdiv = function(a, b)
+ local q = a / b
+ if a >= 0 then return math.floor(q) else return math.ceil(q) end
+ end,
+ mod = function(a, b) return a % b end,
+ mul = function(a, b) return a * b end,
+ neq = function(a) return -a end,
+ unm = function(a) return -a end, -- an alias
+ pow = function(a, b) return a ^ b end,
+ sub = function(a, b) return a - b end,
+ truediv = function(a, b) return a / b end,
+
+ ----------------------------------------------------------------------------
+ -- String operators
+ ----------------------------------------------------------------------------
+ concat = function(a, b) return a..b end,
+ len = function(a) return #a end,
+ length = function(a) return #a end, -- an alias
+
+ ----------------------------------------------------------------------------
+ -- Logical operators
+ ----------------------------------------------------------------------------
+ land = function(a, b) return a and b end,
+ lor = function(a, b) return a or b end,
+ lnot = function(a) return not a end,
+ truth = function(a) return not not a end,
+}
+exports.operator = operator
+methods.operator = operator
+exports.op = operator
+methods.op = operator
+
+--------------------------------------------------------------------------------
+-- module definitions
+--------------------------------------------------------------------------------
+
+-- a special syntax sugar to export all functions to the global table
+setmetatable(exports, {
+ __call = function(t, override)
+ for k, v in pairs(t) do
+ if rawget(_G, k) ~= nil then
+ local msg = 'function ' .. k .. ' already exists in global scope.'
+ if override then
+ rawset(_G, k, v)
+ print('WARNING: ' .. msg .. ' Overwritten.')
+ else
+ print('NOTICE: ' .. msg .. ' Skipped.')
+ end
+ else
+ rawset(_G, k, v)
+ end
+ end
+ end,
+})
+
+return exports
diff --git a/Data/DefaultContent/Libraries/luafun/rpm/lua-fun.spec b/Data/DefaultContent/Libraries/luafun/rpm/lua-fun.spec
new file mode 100644
index 0000000..b200c76
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/rpm/lua-fun.spec
@@ -0,0 +1,76 @@
+%define luaver 5.3
+%define luapkgdir %{_datadir}/lua/%{luaver}
+# LuaJIT is compatible with Lua 5.1 and uses the same directory for modules
+%global ljpkgdir %{_datadir}/lua/5.1
+
+Name: lua-fun
+Version: 0.1.3
+Release: 1%{?dist}
+Summary: Functional programming library for Lua
+Group: Development/Libraries
+License: MIT
+URL: https://github.com/luafun/luafun
+Source0: https://github.com/luafun/luafun/archive/%{version}/luafun-%{version}.tar.gz
+BuildArch: noarch
+BuildRequires: luajit >= 2.0
+BuildRequires: lua >= 5.1
+Requires: lua >= 5.1
+
+%package -n luajit-fun
+Summary: Functional programming library for LuaJIT
+Requires: luajit >= 2.0
+
+%description -n lua-fun
+Lua Fun is a high-performance functional programming library for Lua
+designed with LuaJIT's trace compiler in mind.
+
+Lua Fun provides a set of more than 50 programming primitives typically
+found in languages like Standard ML, Haskell, Erlang, JavaScript, Python and
+even Lisp. High-order functions such as map, filter, reduce, zip, etc.,
+make it easy to write simple and efficient functional code.
+
+This package provides a module for Lua %{luaver}.
+
+%description -n luajit-fun
+Lua Fun is a high-performance functional programming library for Lua
+designed with LuaJIT's trace compiler in mind.
+
+Lua Fun provides a set of more than 50 programming primitives typically
+found in languages like Standard ML, Haskell, Erlang, JavaScript, Python and
+even Lisp. High-order functions such as map, filter, reduce, zip, etc.,
+make it easy to write simple and efficient functional code.
+
+This package provides a module for LuaJIT.
+
+%prep
+%setup -q -n luafun-%{version}
+
+%build
+# nothing to do
+
+%install
+# Install for Lua
+mkdir -p %{buildroot}%{luapkgdir}
+cp -av fun.lua %{buildroot}%{luapkgdir}/fun.lua
+# Install for LuaJIT
+mkdir -p %{buildroot}%{ljpkgdir}
+cp -av fun.lua %{buildroot}%{ljpkgdir}/fun.lua
+
+%check
+cd tests
+luajit ./runtest *.lua
+lua ./runtest *.lua
+
+%files -n lua-fun
+%{luapkgdir}/fun.lua
+%doc README.md CONTRIBUTING.md
+%license COPYING.md
+
+%files -n luajit-fun
+%{ljpkgdir}/fun.lua
+%doc README.md CONTRIBUTING.md
+%license COPYING.md
+
+%changelog
+* Mon Jan 18 2016 Roman Tsisyk <roman@tarantool.org> - 0.1.3-1
+- Initial version.
diff --git a/Data/DefaultContent/Libraries/luafun/tests/.gitignore b/Data/DefaultContent/Libraries/luafun/tests/.gitignore
new file mode 100644
index 0000000..ce0a7f3
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/tests/.gitignore
@@ -0,0 +1 @@
+*.new
diff --git a/Data/DefaultContent/Libraries/luafun/tests/basic.lua b/Data/DefaultContent/Libraries/luafun/tests/basic.lua
new file mode 100644
index 0000000..97e7aae
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/tests/basic.lua
@@ -0,0 +1,332 @@
+--------------------------------------------------------------------------------
+-- iter
+--------------------------------------------------------------------------------
+
+--
+-- Arrays
+--
+
+for _it, a in iter({1, 2, 3}) do print(a) end
+--[[test
+1
+2
+3
+--test]]
+
+for _it, a in iter(iter(iter({1, 2, 3}))) do print(a) end
+--[[test
+1
+2
+3
+--test]]
+
+for _it, a in wrap(wrap(iter({1, 2, 3}))) do print(a) end
+--[[test
+1
+2
+3
+--test]]
+
+for _it, a in wrap(wrap(ipairs({1, 2, 3}))) do print(a) end
+--[[test
+1
+2
+3
+--test]]
+
+for _it, a in iter({}) do print(a) end
+--[[test
+--test]]
+
+for _it, a in iter(iter(iter({}))) do print(a) end
+--[[test
+--test]]
+
+for _it, a in wrap(wrap(iter({}))) do print(a) end
+--[[test
+--test]]
+
+for _it, a in wrap(wrap(ipairs({}))) do print(a) end
+--[[test
+--test]]
+
+-- Check that ``iter`` for arrays is equivalent to ``ipairs``
+local t = {1, 2, 3}
+gen1, param1, state1 = iter(t):unwrap()
+gen2, param2, state2 = ipairs(t)
+print(gen1 == gen2, param1 == param2, state1 == state2)
+--[[test
+true true true
+--test]]
+
+-- Test that ``wrap`` do nothing for wrapped iterators
+gen1, param1, state1 = iter({1, 2, 3})
+gen2, param2, state2 = wrap(gen1, param1, state1):unwrap()
+print(gen1 == gen2, param1 == param2, state1 == state2)
+--[[test
+true true true
+--test]]
+
+--
+-- Maps
+--
+
+local t = {}
+for _it, k, v in iter({ a = 1, b = 2, c = 3}) do t[#t + 1] = k end
+table.sort(t)
+for _it, v in iter(t) do print(v) end
+--[[test
+a
+b
+c
+--test]]
+
+local t = {}
+for _it, k, v in iter(iter(iter({ a = 1, b = 2, c = 3}))) do t[#t + 1] = k end
+table.sort(t)
+for _it, v in iter(t) do print(v) end
+--[[test
+a
+b
+c
+--test]]
+
+for _it, k, v in iter({}) do print(k, v) end
+--[[test
+--test]]
+
+for _it, k, v in iter(iter(iter({}))) do print(k, v) end
+--[[test
+--test]]
+
+--
+-- String
+--
+
+for _it, a in iter("abcde") do print(a) end
+--[[test
+a
+b
+c
+d
+e
+--test]]
+
+for _it, a in iter(iter(iter("abcde"))) do print(a) end
+--[[test
+a
+b
+c
+d
+e
+--test]]
+
+for _it, a in iter("") do print(a) end
+--[[test
+--test]]
+
+for _it, a in iter(iter(iter(""))) do print(a) end
+--[[test
+--test]]
+
+--
+-- Custom generators
+--
+
+local function mypairs_gen(max, state)
+ if (state >= max) then
+ return nil
+ end
+ return state + 1, state + 1
+end
+
+local function mypairs(max)
+ return mypairs_gen, max, 0
+end
+
+for _it, a in iter(mypairs(10)) do print(a) end
+--[[test
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+--test]]
+
+--
+-- Invalid values
+--
+
+for _it, a in iter(1) do print(a) end
+--[[test
+error: object 1 of type "number" is not iterable
+--test]]
+
+for _it, a in iter(1, 2, 3, 4, 5, 6, 7) do print(a) end
+--[[test
+error: object 1 of type "number" is not iterable
+--test]]
+
+--------------------------------------------------------------------------------
+-- each
+--------------------------------------------------------------------------------
+
+each(print, {1, 2, 3})
+--[[test
+1
+2
+3
+--test]]
+
+each(print, iter({1, 2, 3}))
+--[[test
+1
+2
+3
+--test]]
+
+each(print, {})
+--[[test
+--test]]
+
+
+each(print, iter({}))
+--[[test
+--test]]
+
+local keys, vals = {}, {}
+each(function(k, v)
+ keys[#keys + 1] = k
+ vals[#vals + 1] = v
+end, { a = 1, b = 2, c = 3})
+table.sort(keys)
+table.sort(vals)
+each(print, keys)
+each(print, vals)
+--[[test
+a
+b
+c
+1
+2
+3
+--test]]
+
+each(print, "abc")
+--[[test
+a
+b
+c
+--test]]
+
+each(print, iter("abc"))
+--[[test
+a
+b
+c
+--test]]
+
+print(for_each == each) -- an alias
+--[[test
+true
+--test]]
+
+print(foreach == each) -- an alias
+--[[test
+true
+--test]]
+
+--------------------------------------------------------------------------------
+-- totable
+--------------------------------------------------------------------------------
+
+local tab = totable(range(5))
+print(type(tab), #tab)
+each(print, tab)
+--[[test
+table 5
+1
+2
+3
+4
+5
+--test]]
+
+local tab = totable(range(0))
+print(type(tab), #tab)
+--[[test
+table 0
+--test]]
+
+local tab = totable("abcdef")
+print(type(tab), #tab)
+each(print, tab)
+--[[test
+table 6
+a
+b
+c
+d
+e
+f
+--test]]
+
+local unpack = rawget(table, "unpack") or unpack
+local tab = totable({ 'a', {'b', 'c'}, {'d', 'e', 'f'}})
+print(type(tab), #tab)
+each(print, tab[1])
+each(print, map(unpack, drop(1, tab)))
+--[[test
+table 3
+a
+b c
+d e f
+--test]]
+
+--------------------------------------------------------------------------------
+-- tomap
+--------------------------------------------------------------------------------
+
+local tab = tomap(zip(range(1, 7), 'abcdef'))
+print(type(tab), #tab)
+each(print, iter(tab))
+--[[test
+table 6
+a
+b
+c
+d
+e
+f
+--test]]
+
+local tab = tomap({a = 1, b = 2, c = 3})
+print(type(tab), #tab)
+local t = {}
+for _it, k, v in iter(tab) do t[v] = k end
+table.sort(t)
+for k, v in ipairs(t) do print(k, v) end
+--[[test
+table 0
+1 a
+2 b
+3 c
+--test]]
+
+local tab = tomap(enumerate("abcdef"))
+print(type(tab), #tab)
+each(print, tab)
+--[[test
+table 6
+a
+b
+c
+d
+e
+f
+--test]]
diff --git a/Data/DefaultContent/Libraries/luafun/tests/compositions.lua b/Data/DefaultContent/Libraries/luafun/tests/compositions.lua
new file mode 100644
index 0000000..7b81d88
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/tests/compositions.lua
@@ -0,0 +1,170 @@
+--------------------------------------------------------------------------------
+-- zip
+--------------------------------------------------------------------------------
+
+dump(zip({"a", "b", "c", "d"}, {"one", "two", "three"}))
+--[[test
+a one
+b two
+c three
+--test]]
+
+dump(zip())
+--[[test
+--test]]
+
+dump(zip(range(0)))
+--[[test
+error: invalid iterator
+--test]]
+
+dump(zip(range(0), range(0)))
+--[[test
+error: invalid iterator
+--test]]
+
+print(nth(10, zip(range(1, 100, 3), range(1, 100, 5), range(1, 100, 7))))
+--[[test
+28 46 64
+--test]]
+
+dump(zip(partition(function(x) return x > 7 end, range(1, 15, 1))))
+--[[test
+8 1
+9 2
+10 3
+11 4
+12 5
+13 6
+14 7
+--test]]
+
+--------------------------------------------------------------------------------
+-- cycle
+--------------------------------------------------------------------------------
+
+dump(take(15, cycle({"a", "b", "c", "d", "e"})))
+--[[test
+a
+b
+c
+d
+e
+a
+b
+c
+d
+e
+a
+b
+c
+d
+e
+--test]]
+
+
+dump(take(15, cycle(range(5))))
+--[[test
+1
+2
+3
+4
+5
+1
+2
+3
+4
+5
+1
+2
+3
+4
+5
+--test]]
+
+dump(take(15, cycle(zip(range(5), {"a", "b", "c", "d", "e"}))))
+--[[test
+1 a
+2 b
+3 c
+4 d
+5 e
+1 a
+2 b
+3 c
+4 d
+5 e
+1 a
+2 b
+3 c
+4 d
+5 e
+--test]]
+
+--------------------------------------------------------------------------------
+-- chain
+--------------------------------------------------------------------------------
+
+dump(chain(range(2)))
+--[[test
+1
+2
+--test]]
+
+dump(chain(range(2), {"a", "b", "c"}, {"one", "two", "three"}))
+--[[test
+1
+2
+a
+b
+c
+one
+two
+three
+--test]]
+
+dump(take(15, cycle(chain(enumerate({"a", "b", "c"}),
+ {"one", "two", "three"}))))
+--[[test
+1 a
+2 b
+3 c
+one
+two
+three
+1 a
+2 b
+3 c
+one
+two
+three
+1 a
+2 b
+3 c
+--test]]
+
+local tab = {}
+local keys = {}
+for _it, k, v in chain({ a = 11, b = 12, c = 13}, { d = 21, e = 22 }) do
+ tab[k] = v
+ table.insert(keys, k)
+end
+table.sort(keys)
+for _, key in ipairs(keys) do print(key, tab[key]) end
+--[[test
+a 11
+b 12
+c 13
+d 21
+e 22
+--test]]
+
+dump(chain(range(0), range(0), range(0)))
+--[[test
+error: invalid iterator
+--test]]
+
+dump(chain(range(0), range(1), range(0)))
+--[[test
+error: invalid iterator
+--test]]
diff --git a/Data/DefaultContent/Libraries/luafun/tests/filtering.lua b/Data/DefaultContent/Libraries/luafun/tests/filtering.lua
new file mode 100644
index 0000000..a5fdfe2
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/tests/filtering.lua
@@ -0,0 +1,102 @@
+--------------------------------------------------------------------------------
+-- filter
+--------------------------------------------------------------------------------
+
+dump(filter(function(x) return x % 3 == 0 end, range(10)))
+--[[test
+3
+6
+9
+--test]]
+
+dump(filter(function(x) return x % 3 == 0 end, range(0)))
+--[[test
+--test]]
+
+
+dump(take(5, filter(function(i, x) return i % 3 == 0 end,
+ enumerate(duplicate('x')))))
+--[[test
+3 x
+6 x
+9 x
+12 x
+15 x
+--test]]
+
+function filter_fun(a, b, c)
+ if a % 16 == 0 then
+ return true
+ else
+ return false
+ end
+end
+
+function test3(a, b, c)
+ return a, c, b
+end
+
+n = 50
+dump(filter(filter_fun, map(test3, zip(range(0, n, 1),
+ range(0, n, 2), range(0, n, 3)))))
+--[[test
+0 0 0
+16 48 32
+--test]]
+
+print(remove_if == filter) -- an alias
+--[[test
+true
+--test]]
+
+--------------------------------------------------------------------------------
+-- grep
+--------------------------------------------------------------------------------
+
+lines_to_grep = {
+ [[Lorem ipsum dolor sit amet, consectetur adipisicing elit, ]],
+ [[sed do eiusmod tempor incididunt ut labore et dolore magna ]],
+ [[aliqua. Ut enim ad minim veniam, quis nostrud exercitation ]],
+ [[ullamco laboris nisi ut aliquip ex ea commodo consequat.]],
+ [[Duis aute irure dolor in reprehenderit in voluptate velit ]],
+ [[esse cillum dolore eu fugiat nulla pariatur. Excepteur sint ]],
+ [[occaecat cupidatat non proident, sunt in culpa qui officia ]],
+ [[deserunt mollit anim id est laborum.]]
+}
+
+dump(grep("lab", lines_to_grep))
+--[[test
+sed do eiusmod tempor incididunt ut labore et dolore magna
+ullamco laboris nisi ut aliquip ex ea commodo consequat.
+deserunt mollit anim id est laborum.
+--test]]
+
+lines_to_grep = {
+ [[Emily]],
+ [[Chloe]],
+ [[Megan]],
+ [[Jessica]],
+ [[Emma]],
+ [[Sarah]],
+ [[Elizabeth]],
+ [[Sophie]],
+ [[Olivia]],
+ [[Lauren]]
+}
+
+dump(grep("^Em", lines_to_grep))
+--[[test
+Emily
+Emma
+--test]]
+
+--------------------------------------------------------------------------------
+-- partition
+--------------------------------------------------------------------------------
+
+dump(zip(partition(function(i, x) return i % 3 == 0 end, range(10))))
+--[[test
+3 1
+6 2
+9 4
+--test]]
diff --git a/Data/DefaultContent/Libraries/luafun/tests/generators.lua b/Data/DefaultContent/Libraries/luafun/tests/generators.lua
new file mode 100644
index 0000000..7a89ebf
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/tests/generators.lua
@@ -0,0 +1,287 @@
+--------------------------------------------------------------------------------
+-- range
+--------------------------------------------------------------------------------
+
+dump(range(0))
+print('--')
+for i=1,0 do print(i) end
+--[[test
+--
+--test]]
+
+dump(range(0, 0))
+print('--')
+for i=0,0 do print(i) end
+--[[test
+0
+--
+0
+--test]]
+
+dump(range(5))
+print('--')
+for i=1,5 do print(i) end
+--[[test
+1
+2
+3
+4
+5
+--
+1
+2
+3
+4
+5
+--test]]
+
+dump(range(0, 5))
+print('--')
+for i=0,5 do print(i) end
+--[[test
+0
+1
+2
+3
+4
+5
+--
+0
+1
+2
+3
+4
+5
+--test]]
+
+dump(range(0, 5, 1))
+print('--')
+for i=0,5,1 do print(i) end
+--[[test
+0
+1
+2
+3
+4
+5
+--
+0
+1
+2
+3
+4
+5
+--test]]
+
+dump(range(0, 10, 2))
+print('--')
+for i=0,10,2 do print(i) end
+--[[test
+0
+2
+4
+6
+8
+10
+--
+0
+2
+4
+6
+8
+10
+--test]]
+
+dump(range(-5))
+print('--')
+for i=-1,-5,-1 do print(i) end
+--[[test
+-1
+-2
+-3
+-4
+-5
+--
+-1
+-2
+-3
+-4
+-5
+--test]]
+
+dump(range(0, -5, 1))
+print('--')
+for i=0,-5,1 do print(i) end
+--[[test
+--
+--test]]
+
+dump(range(0, -5, -1))
+print('--')
+for i=0,-5,-1 do print(i) end
+--[[test
+0
+-1
+-2
+-3
+-4
+-5
+--
+0
+-1
+-2
+-3
+-4
+-5
+--test]]
+
+dump(range(0, -10, -2))
+print('--')
+for i=0,-10,-2 do print(i) end
+--[[test
+0
+-2
+-4
+-6
+-8
+-10
+--
+0
+-2
+-4
+-6
+-8
+-10
+--test]]
+
+dump(range(1.2, 1.6, 0.1))
+--[[test
+1.2
+1.3
+1.4
+1.5
+--test]]
+
+-- Invalid step
+dump(range(0, 5, 0))
+--[[test
+error: step must not be zero
+--test]]
+
+--------------------------------------------------------------------------------
+-- duplicate
+--------------------------------------------------------------------------------
+
+dump(take(5, duplicate(48)))
+--[[test
+48
+48
+48
+48
+48
+--test]]
+
+dump(take(5, duplicate(1,2,3,4,5)))
+--[[test
+1 2 3 4 5
+1 2 3 4 5
+1 2 3 4 5
+1 2 3 4 5
+1 2 3 4 5
+--test]]
+
+print(xrepeat == duplicate) -- an alias
+--[[test
+true
+--test]]
+
+print(replicate == duplicate) -- an alias
+--[[test
+true
+--test]]
+
+--------------------------------------------------------------------------------
+-- tabulate
+--------------------------------------------------------------------------------
+
+dump(take(5, tabulate(function(x) return 2 * x end)))
+--[[test
+0
+2
+4
+6
+8
+--test]]
+
+--------------------------------------------------------------------------------
+-- zeros
+--------------------------------------------------------------------------------
+
+dump(take(5, zeros()))
+--[[test
+0
+0
+0
+0
+0
+--test]]
+
+--------------------------------------------------------------------------------
+-- ones
+--------------------------------------------------------------------------------
+
+dump(take(5, ones()))
+--[[test
+1
+1
+1
+1
+1
+--test]]
+
+--------------------------------------------------------------------------------
+-- rands
+--------------------------------------------------------------------------------
+
+print(all(function(x) return x >= 0 and x < 1 end, take(5, rands())))
+--[[test
+true
+--test]]
+
+dump(take(5, rands(0)))
+--[[test
+error: empty interval
+--test]]
+
+print(all(function(x) return math.floor(x) == x end, take(5, rands(10))))
+--[[test
+true
+--test]]
+
+print(all(function(x) return math.floor(x) == x end, take(5, rands(1024))))
+--[[test
+true
+--test]]
+
+dump(take(5, rands(0, 1)))
+--[[test
+0
+0
+0
+0
+0
+--test]]
+
+dump(take(5, rands(5, 6)))
+--[[test
+5
+5
+5
+5
+5
+--test]]
+
+print(all(function(x) return x >= 10 and x < 20 end, take(20, rands(10, 20))))
+--[[test
+true
+--test]]
diff --git a/Data/DefaultContent/Libraries/luafun/tests/indexing.lua b/Data/DefaultContent/Libraries/luafun/tests/indexing.lua
new file mode 100644
index 0000000..febc1ae
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/tests/indexing.lua
@@ -0,0 +1,83 @@
+--------------------------------------------------------------------------------
+-- index
+--------------------------------------------------------------------------------
+
+print(index(2, range(5)))
+--[[test
+2
+--test]]
+
+print(index(10, range(5)))
+--[[test
+nil
+--test]]
+
+print(index(2, range(0)))
+--[[test
+nil
+--test]]
+
+print(index("b", {"a", "b", "c", "d", "e"}))
+--[[test
+2
+--test]]
+
+print(index(1, enumerate({"a", "b", "c", "d", "e"})))
+--[[test
+1
+--test]]
+
+print(index("b", "abcdef"))
+--[[test
+2
+--test]]
+
+print(index_of == index) -- an alias
+--[[test
+true
+--test]]
+
+print(elem_index == index) -- an alias
+--[[test
+true
+--test]]
+
+--------------------------------------------------------------------------------
+-- indexes
+--------------------------------------------------------------------------------
+
+dump(indexes("a", {"a", "b", "c", "d", "e", "a", "b", "c", "d", "a", "a"}))
+--[[test
+1
+6
+10
+11
+--test]]
+
+dump(indexes("f", {"a", "b", "c", "d", "e", "a", "b", "c", "d", "a", "a"}))
+--[[test
+--test]]
+
+dump(indexes("f", {}))
+--[[test
+--test]]
+
+dump(indexes(1, enumerate({"a", "b", "c", "d", "e"})))
+--[[test
+1
+--test]]
+
+print(indices == indexes) -- an alias
+--[[test
+true
+--test]]
+
+print(elem_indexes == indexes) -- an alias
+--[[test
+true
+--test]]
+
+print(elem_indices == indexes) -- an alias
+--[[test
+true
+--test]]
diff --git a/Data/DefaultContent/Libraries/luafun/tests/operators.lua b/Data/DefaultContent/Libraries/luafun/tests/operators.lua
new file mode 100644
index 0000000..98ab7bb
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/tests/operators.lua
@@ -0,0 +1,322 @@
+--
+-- All these functions are fully covered by Lua tests.
+-- This test just checks that all functions were defined correctly.
+--
+
+print(op == operator) -- an alias
+--[[test
+true
+--test]]
+
+--------------------------------------------------------------------------------
+-- Comparison operators
+--------------------------------------------------------------------------------
+
+local comparators = { 'le', 'lt', 'eq', 'ne', 'ge', 'gt' }
+for _k, op in iter(comparators) do
+ print('op', op)
+ print('==')
+ print('num:')
+ print(operator[op](0, 1))
+ print(operator[op](1, 0))
+ print(operator[op](0, 0))
+ print('str:')
+ print(operator[op]("abc", "cde"))
+ print(operator[op]("cde", "abc"))
+ print(operator[op]("abc", "abc"))
+ print('')
+end
+--[[test
+op le
+==
+num:
+true
+false
+true
+str:
+true
+false
+true
+
+op lt
+==
+num:
+true
+false
+false
+str:
+true
+false
+false
+
+op eq
+==
+num:
+false
+false
+true
+str:
+false
+false
+true
+
+op ne
+==
+num:
+true
+true
+false
+str:
+true
+true
+false
+
+op ge
+==
+num:
+false
+true
+true
+str:
+false
+true
+true
+
+op gt
+==
+num:
+false
+true
+false
+str:
+false
+true
+false
+
+--test]]
+
+--------------------------------------------------------------------------------
+-- Arithmetic operators
+--------------------------------------------------------------------------------
+
+print(operator.add(-1.0, 1.0))
+print(operator.add(0, 0))
+print(operator.add(12, 2))
+--[[test
+0
+0
+14
+--test]]
+
+print(operator.div(10, 2))
+print(operator.div(10, 3))
+print(operator.div(-10, 3))
+--[[test
+5
+3.3333333333333
+-3.3333333333333
+--test]]
+
+print(operator.floordiv(10, 3))
+print(operator.floordiv(11, 3))
+print(operator.floordiv(12, 3))
+print(operator.floordiv(-10, 3))
+print(operator.floordiv(-11, 3))
+print(operator.floordiv(-12, 3))
+--[[test
+3
+3
+4
+-4
+-4
+-4
+--test]]
+
+print(operator.intdiv(10, 3))
+print(operator.intdiv(11, 3))
+print(operator.intdiv(12, 3))
+print(operator.intdiv(-10, 3))
+print(operator.intdiv(-11, 3))
+print(operator.intdiv(-12, 3))
+--[[test
+3
+3
+4
+-3
+-3
+-4
+--test]]
+
+print(operator.truediv(10, 3))
+print(operator.truediv(11, 3))
+print(operator.truediv(12, 3))
+print(operator.truediv(-10, 3))
+print(operator.truediv(-11, 3))
+print(operator.truediv(-12, 3))
+--[[test
+3.3333333333333
+3.6666666666667
+4
+-3.3333333333333
+-3.6666666666667
+-4
+--test]]
+
+print(operator.mod(10, 2))
+print(operator.mod(10, 3))
+print(operator.mod(-10, 3))
+--[[test
+0
+1
+2
+--test]]
+
+print(operator.mul(10, 0.1))
+print(operator.mul(0, 0))
+print(operator.mul(-1, -1))
+--[[test
+1
+0
+1
+--test]]
+
+print(operator.neq(1))
+print(operator.neq(0) == 0)
+print(operator.neq(-0) == 0)
+print(operator.neq(-1))
+--[[test
+-1
+true
+true
+1
+--test]]
+
+print(operator.unm(1))
+print(operator.unm(0) == 0)
+print(operator.unm(-0) == 0)
+print(operator.unm(-1))
+--[[test
+-1
+true
+true
+1
+--test]]
+
+print(operator.pow(2, 3))
+print(operator.pow(0, 10))
+print(operator.pow(2, 0))
+--[[test
+8
+0
+1
+--test]]
+
+print(operator.sub(2, 3))
+print(operator.sub(0, 10))
+print(operator.sub(2, 2))
+--[[test
+-1
+-10
+0
+--test]]
+
+--------------------------------------------------------------------------------
+-- String operators
+--------------------------------------------------------------------------------
+
+print(operator.concat("aa", "bb"))
+print(operator.concat("aa", ""))
+print(operator.concat("", "bb"))
+--[[test
+aabb
+aa
+bb
+--test]]
+
+print(operator.len(""))
+print(operator.len("ab"))
+print(operator.len("abcd"))
+--[[test
+0
+2
+4
+--test]]
+
+print(operator.length(""))
+print(operator.length("ab"))
+print(operator.length("abcd"))
+--[[test
+0
+2
+4
+--test]]
+
+----------------------------------------------------------------------------
+-- Logical operators
+----------------------------------------------------------------------------
+
+print(operator.land(true, true))
+print(operator.land(true, false))
+print(operator.land(false, true))
+print(operator.land(false, false))
+print(operator.land(1, 0))
+print(operator.land(0, 1))
+print(operator.land(1, 1))
+print(operator.land(0, 0))
+--[[test
+true
+false
+false
+false
+0
+1
+1
+0
+--test]]
+
+print(operator.lor(true, true))
+print(operator.lor(true, false))
+print(operator.lor(false, true))
+print(operator.lor(false, false))
+print(operator.lor(1, 0))
+print(operator.lor(0, 1))
+print(operator.lor(1, 1))
+print(operator.lor(0, 0))
+--[[test
+true
+true
+true
+false
+1
+0
+1
+0
+--test]]
+
+print(operator.lnot(true))
+print(operator.lnot(false))
+print(operator.lor(1))
+print(operator.lor(0))
+--[[test
+false
+true
+1
+0
+--test]]
+
+print(operator.truth(true))
+print(operator.truth(false))
+print(operator.truth(1))
+print(operator.truth(0))
+print(operator.truth(nil))
+print(operator.truth(""))
+print(operator.truth({}))
+--[[test
+true
+false
+true
+true
+false
+true
+true
+--test]]
diff --git a/Data/DefaultContent/Libraries/luafun/tests/reducing.lua b/Data/DefaultContent/Libraries/luafun/tests/reducing.lua
new file mode 100644
index 0000000..8e4aaeb
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/tests/reducing.lua
@@ -0,0 +1,289 @@
+--------------------------------------------------------------------------------
+-- foldl
+--------------------------------------------------------------------------------
+
+print(foldl(function(acc, x) return acc + x end, 0, range(5)))
+--[[test
+15
+--test]]
+
+print(foldl(operator.add, 0, range(5)))
+--[[test
+15
+--test]]
+
+print(foldl(function(acc, x, y) return acc + x * y; end, 0,
+ zip(range(1, 5), {4, 3, 2, 1})))
+--[[test
+20
+--test]]
+
+print(reduce == foldl) -- an alias
+--[[test
+true
+--test]]
+
+--------------------------------------------------------------------------------
+-- length
+--------------------------------------------------------------------------------
+
+print(length({"a", "b", "c", "d", "e"}))
+--[[test
+5
+--test]]
+
+print(length({}))
+--[[test
+0
+--test]]
+
+print(length(range(0)))
+--[[test
+0
+--test]]
+
+--------------------------------------------------------------------------------
+-- is_null
+--------------------------------------------------------------------------------
+
+print(is_null({"a", "b", "c", "d", "e"}))
+--[[test
+false
+--test]]
+
+print(is_null({}))
+--[[test
+true
+--test]]
+
+print(is_null(range(0)))
+--[[test
+true
+--test]]
+
+local gen, init, state = range(5)
+print(is_null(gen, init, state))
+dump(gen, init, state)
+--[[test
+false
+1
+2
+3
+4
+5
+--test]]
+
+--------------------------------------------------------------------------------
+-- is_prefix_of
+--------------------------------------------------------------------------------
+
+print(is_prefix_of({"a"}, {"a", "b", "c"}))
+--[[test
+true
+--test]]
+
+print(is_prefix_of({}, {"a", "b", "c"}))
+--[[test
+true
+--test]]
+
+print(is_prefix_of({}, {}))
+--[[test
+true
+--test]]
+
+print(is_prefix_of({"a"}, {}))
+--[[test
+false
+--test]]
+
+print(is_prefix_of(range(5), range(6)))
+--[[test
+true
+--test]]
+
+print(is_prefix_of(range(6), range(5)))
+--[[test
+false
+--test]]
+
+--------------------------------------------------------------------------------
+-- all
+--------------------------------------------------------------------------------
+
+print(all(function(x) return x end, {true, true, true, true}))
+--[[test
+true
+--test]]
+
+print(all(function(x) return x end, {true, true, true, false}))
+--[[test
+false
+--test]]
+
+print(all(function(x) return x end, {}))
+--[[test
+true
+--test]]
+
+print(every == all) -- an alias
+--[[test
+true
+--test]]
+
+--------------------------------------------------------------------------------
+-- any
+--------------------------------------------------------------------------------
+
+print(any(function(x) return x end, {false, false, false, false}))
+--[[test
+false
+--test]]
+
+print(any(function(x) return x end, {false, false, false, true}))
+--[[test
+true
+--test]]
+
+print(any(function(x) return x end, {}))
+--[[test
+false
+--test]]
+
+print(some == any) -- an alias
+--[[test
+true
+--test]]
+
+--------------------------------------------------------------------------------
+-- sum
+--------------------------------------------------------------------------------
+
+print(sum(range(1, 5)))
+--[[test
+15
+--test]]
+
+print(sum(range(1, 5, 0.5)))
+--[[test
+27
+--test]]
+
+print(sum(range(0)))
+--[[test
+0
+--test]]
+
+--------------------------------------------------------------------------------
+-- product
+--------------------------------------------------------------------------------
+
+print(product(range(1, 5)))
+--[[test
+120
+--test]]
+
+print(product(range(1, 5, 0.5)))
+--[[test
+7087.5
+--test]]
+
+print(product(range(0)))
+--[[test
+1
+--test]]
+
+
+--------------------------------------------------------------------------------
+-- min
+--------------------------------------------------------------------------------
+
+print(min(range(1, 10, 1)))
+--[[test
+1
+--test]]
+
+print(min({"f", "d", "c", "d", "e"}))
+--[[test
+c
+--test]]
+
+print(min({}))
+--[[test
+error: min: iterator is empty
+--test]]
+
+print(minimum == min) -- an alias
+--[[test
+true
+--test]]
+
+--------------------------------------------------------------------------------
+-- min_by
+--------------------------------------------------------------------------------
+
+function min_cmp(a, b) if -a < -b then return a else return b end end
+--[[test
+--test]]
+
+print(min_by(min_cmp, range(1, 10, 1)))
+--[[test
+10
+--test]]
+
+print(min_by(min_cmp, {}))
+--[[test
+error: min: iterator is empty
+--test]]
+
+print(minimum_by == min_by) -- an alias
+--[[test
+true
+--test]]
+
+--------------------------------------------------------------------------------
+-- max
+--------------------------------------------------------------------------------
+
+print(max(range(1, 10, 1)))
+--[[test
+10
+--test]]
+
+print(max({"f", "d", "c", "d", "e"}))
+--[[test
+f
+--test]]
+
+print(max({}))
+--[[test
+error: max: iterator is empty
+--test]]
+
+print(maximum == max) -- an alias
+--[[test
+true
+--test]]
+
+--------------------------------------------------------------------------------
+-- max_by
+--------------------------------------------------------------------------------
+
+function max_cmp(a, b) if -a > -b then return a else return b end end
+--[[test
+--test]]
+
+print(max_by(max_cmp, range(1, 10, 1)))
+--[[test
+1
+--test]]
+
+print(max_by(max_cmp, {}))
+--[[test
+error: max: iterator is empty
+--test]]
+
+print(maximum_by == maximum_by) -- an alias
+--[[test
+true
+--test]]
diff --git a/Data/DefaultContent/Libraries/luafun/tests/runtest b/Data/DefaultContent/Libraries/luafun/tests/runtest
new file mode 100644
index 0000000..f6774f6
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/tests/runtest
@@ -0,0 +1,114 @@
+#!/usr/bin/env lua
+
+package.path = "../?.lua;"..package.path
+require "fun" ()
+function dump(gen, init, state) each(print, gen, init, state) end
+
+local unpack = rawget(table, "unpack") or unpack
+local loadstring = rawget(_G, "loadstring") or load
+
+function file_print(file, ...)
+ local n, i = select("#",...)
+ for i=1,n do
+ local x = select(i, ...)
+ if type(x) == "number" and math.floor(x) == math.ceil(x) then
+ -- A special hack for Lua 5.3: remove .0 for integer
+ x = string.match(select(i,...), '^-?%d+')
+ end
+ file:write(tostring(x))
+ if i~=n then
+ file:write(' ')
+ end
+ end
+ file:write('\n')
+end
+
+local globals = {}
+setmetatable(_G, {
+ __newindex = function(t,k,v)
+ local info = debug.getinfo(2, "S")
+ if info.short_src:sub(1,7) ~= '[string' then
+ local file = info.short_src
+ local func = debug.getinfo(2, "n").name or ""
+ local line = info.linedefined
+ globals[file..':'..line..':'..k] = {file, line, func, k}
+ end
+ rawset(t, k, v)
+ end
+})
+
+local function process(test_name)
+ io.write("Testing ", test_name, "\n")
+ local new_name = test_name..".new"
+ local test_file = io.open(test_name, 'r')
+ local content = test_file:read("*a");
+ test_file:close()
+
+ local new_file = io.open(new_name, 'w')
+
+ local prev_print = print
+ print = function(...) file_print(new_file, ...) end
+
+ io.flush()
+ local expr
+ for expr in content:gmatch("(.-)%s*--%[%[test.-test%]%]") do
+ new_file:write(expr)
+ new_file:write("\n--[[test\n")
+ local res, err = loadstring(expr)
+ if res then
+ res, err = pcall(res, expr)
+ end
+ if not res then
+ new_file:write('error: ', err:match(".-:%d+:%s*(.*)"), "\n")
+ end
+ new_file:write("--test]]")
+ end
+ new_file:write("\n")
+ new_file:close()
+
+ print = prev_print
+
+ local r = os.execute(string.format('diff -U4 "%s" "%s" 2>&1',
+ test_name, new_name))
+ if r then
+ os.remove(new_name)
+ return true
+ else
+ return false
+ end
+end
+
+if #arg <= 0 then
+ io.write("Usage: runtest *.lua", "\n")
+ os.exit(1)
+end
+
+local failed, i = {}
+for i=1,#arg,1 do
+ local test_name = arg[i]
+ if not process(test_name) then
+ table.insert(failed, test_name)
+ end
+end
+
+if #failed > 0 then
+ io.write("\n")
+ io.write("Failed tests:", "\n")
+ for _k,test_name in ipairs(failed) do
+ io.write(" ", test_name, "\n")
+ end
+ io.write("\n", "Please review *.new files and update tests", "\n")
+end
+
+if next(globals) then
+ io.write("\n")
+ io.write("Some global variables have been declared by mistake:", "\n")
+ for k, pollution in pairs(globals) do
+ local file, line, func, var = unpack(pollution)
+ io.write(file..":"..line.." function "..func.."() = var '"..var.."'", "\n")
+ end
+ io.write("\n", "Please declare them with the local statement", "\n")
+elseif #failed == 0 then
+ io.write("All tests have passed!", "\n")
+ os.exit(0)
+end
diff --git a/Data/DefaultContent/Libraries/luafun/tests/slicing.lua b/Data/DefaultContent/Libraries/luafun/tests/slicing.lua
new file mode 100644
index 0000000..c4678c4
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/tests/slicing.lua
@@ -0,0 +1,339 @@
+--------------------------------------------------------------------------------
+-- nth
+--------------------------------------------------------------------------------
+
+print(nth(2, range(5)))
+--[[test
+2
+--test]]
+
+print(nth(10, range(5)))
+--[[test
+nil
+--test]]
+
+print(nth(2, range(0)))
+--[[test
+nil
+--test]]
+
+print(nth(2, {"a", "b", "c", "d", "e"}))
+--[[test
+b
+--test]]
+
+print(nth(2, enumerate({"a", "b", "c", "d", "e"})))
+--[[test
+2 b
+--test]]
+
+print(nth(1, "abcdef"))
+--[[test
+a
+--test]]
+
+print(nth(2, "abcdef"))
+--[[test
+b
+--test]]
+
+print(nth(6, "abcdef"))
+--[[test
+f
+--test]]
+
+print(nth(0, "abcdef"))
+--[[test
+error: invalid first argument to nth
+--test]]
+
+print(nth(7, "abcdef"))
+--[[test
+nil
+--test]]
+
+--------------------------------------------------------------------------------
+-- head
+--------------------------------------------------------------------------------
+
+print(head({"a", "b", "c", "d", "e"}))
+--[[test
+a
+--test]]
+
+print(head({}))
+--[[test
+error: head: iterator is empty
+--test]]
+
+print(head(range(0)))
+--[[test
+error: head: iterator is empty
+--test]]
+
+print(head(enumerate({"a", "b"})))
+--[[test
+1 a
+--test]]
+
+print(car == head) -- an alias
+--[[test
+true
+--test]]
+
+--------------------------------------------------------------------------------
+-- tail
+--------------------------------------------------------------------------------
+
+dump(tail({"a", "b", "c", "d", "e"}))
+--[[test
+b
+c
+d
+e
+--test]]
+
+dump(tail({}))
+--[[test
+--test]]
+
+dump(tail(range(0)))
+--[[test
+--test]]
+
+dump(tail(enumerate({"a", "b"})))
+--[[test
+2 b
+--test]]
+
+print(cdr == tail) -- an alias
+--[[test
+true
+--test]]
+
+
+--------------------------------------------------------------------------------
+-- take_n
+--------------------------------------------------------------------------------
+
+dump(take_n(0, duplicate(48)))
+--[[test
+--test]]
+
+dump(take_n(5, range(0)))
+--[[test
+--test]]
+
+dump(take_n(1, duplicate(48)))
+--[[test
+48
+--test]]
+
+dump(take_n(5, duplicate(48)))
+--[[test
+48
+48
+48
+48
+48
+--test]]
+
+dump(take_n(5, enumerate(duplicate('x'))))
+--[[test
+1 x
+2 x
+3 x
+4 x
+5 x
+--test]]
+
+--------------------------------------------------------------------------------
+-- take_while
+--------------------------------------------------------------------------------
+
+dump(take_while(function(x) return x < 5 end, range(10)))
+--[[test
+1
+2
+3
+4
+--test]]
+
+dump(take_while(function(x) return x < 5 end, range(0)))
+--[[test
+--test]]
+
+dump(take_while(function(x) return x > 100 end, range(10)))
+--[[test
+--test]]
+
+dump(take_while(function(i, a) return i ~=a end, enumerate({5, 2, 1, 3, 4})))
+--[[test
+1 5
+--test]]
+
+--------------------------------------------------------------------------------
+-- take
+--------------------------------------------------------------------------------
+
+dump(take(function(x) return x < 5 end, range(10)))
+--[[test
+1
+2
+3
+4
+--test]]
+
+dump(take(5, duplicate(48)))
+--[[test
+48
+48
+48
+48
+48
+--test]]
+
+--------------------------------------------------------------------------------
+-- drop_n
+--------------------------------------------------------------------------------
+
+dump(drop_n(5, range(10)))
+--[[test
+6
+7
+8
+9
+10
+--test]]
+
+dump(drop_n(0, range(5)))
+--[[test
+1
+2
+3
+4
+5
+--test]]
+
+dump(drop_n(5, range(0)))
+--[[test
+--test]]
+
+dump(drop_n(2, enumerate({'a', 'b', 'c', 'd', 'e'})))
+--[[test
+3 c
+4 d
+5 e
+--test]]
+
+--------------------------------------------------------------------------------
+-- drop_while
+--------------------------------------------------------------------------------
+
+dump(drop_while(function(x) return x < 5 end, range(10)))
+--[[test
+5
+6
+7
+8
+9
+10
+--test]]
+
+dump(drop_while(function(x) return x < 5 end, range(0)))
+--[[test
+--test]]
+
+dump(drop_while(function(x) return x > 100 end, range(10)))
+--[[test
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+--test]]
+
+dump(drop_while(function(i, a) return i ~=a end, enumerate({5, 2, 1, 3, 4})))
+--[[test
+2 2
+3 1
+4 3
+5 4
+--test]]
+
+dump(drop_while(function(i, a) return i ~=a end,
+ zip({1, 2, 3, 4, 5}, {5, 4, 3, 2, 1})))
+--[[test
+3 3
+4 2
+5 1
+--test]]
+
+--------------------------------------------------------------------------------
+-- drop
+--------------------------------------------------------------------------------
+
+dump(drop(5, range(10)))
+--[[test
+6
+7
+8
+9
+10
+--test]]
+
+dump(drop(function(x) return x < 5 end, range(10)))
+--[[test
+5
+6
+7
+8
+9
+10
+--test]]
+
+
+--------------------------------------------------------------------------------
+-- span
+--------------------------------------------------------------------------------
+
+dump(zip(span(function(x) return x < 5 end, range(10))))
+--[[test
+1 5
+2 6
+3 7
+4 8
+--test]]
+
+dump(zip(span(5, range(10))))
+--[[test
+1 6
+2 7
+3 8
+4 9
+5 10
+--test]]
+
+dump(zip(span(function(x) return x < 5 end, range(0))))
+--[[test
+--test]]
+
+dump(zip(span(function(x) return x < 5 end, range(5))))
+--[[test
+1 5
+--test]]
+
+print(split == span) -- an alias
+--[[test
+true
+--test]]
+
+print(split_at == span) -- an alias
+--[[test
+true
+--test]]
diff --git a/Data/DefaultContent/Libraries/luafun/tests/transformations.lua b/Data/DefaultContent/Libraries/luafun/tests/transformations.lua
new file mode 100644
index 0000000..b4fddab
--- /dev/null
+++ b/Data/DefaultContent/Libraries/luafun/tests/transformations.lua
@@ -0,0 +1,107 @@
+--------------------------------------------------------------------------------
+-- map
+--------------------------------------------------------------------------------
+
+fun = function(...) return 'map', ... end
+
+dump(map(fun, range(0)))
+--[[test
+--test]]
+
+
+dump(map(fun, range(4)))
+--[[test
+map 1
+map 2
+map 3
+map 4
+--test]]
+
+dump(map(fun, enumerate({"a", "b", "c", "d", "e"})))
+--[[test
+map 1 a
+map 2 b
+map 3 c
+map 4 d
+map 5 e
+--test]]
+
+dump(map(function(x) return 2 * x end, range(4)))
+--[[test
+2
+4
+6
+8
+--test]]
+
+fun = nil
+--[[test
+--test]]
+
+--------------------------------------------------------------------------------
+-- enumerate
+--------------------------------------------------------------------------------
+
+dump(enumerate({"a", "b", "c", "d", "e"}))
+--[[test
+1 a
+2 b
+3 c
+4 d
+5 e
+--test]]
+
+dump(enumerate(enumerate(enumerate({"a", "b", "c", "d", "e"}))))
+--[[test
+1 1 1 a
+2 2 2 b
+3 3 3 c
+4 4 4 d
+5 5 5 e
+--test]]
+
+dump(enumerate(zip({"one", "two", "three", "four", "five"},
+ {"a", "b", "c", "d", "e"})))
+--[[test
+1 one a
+2 two b
+3 three c
+4 four d
+5 five e
+--test]]
+
+--------------------------------------------------------------------------------
+-- intersperse
+--------------------------------------------------------------------------------
+
+dump(intersperse("x", {}))
+
+dump(intersperse("x", {"a", "b", "c", "d", "e"}))
+--[[test
+a
+x
+b
+x
+c
+x
+d
+x
+e
+x
+--test]]
+
+dump(intersperse("x", {"a", "b", "c", "d", "e", "f"}))
+--[[test
+a
+x
+b
+x
+c
+x
+d
+x
+e
+x
+f
+x
+--test]]
diff --git a/Data/DefaultContent/Libraries/md5.lua/.travis.yml b/Data/DefaultContent/Libraries/md5.lua/.travis.yml
new file mode 100644
index 0000000..90bd434
--- /dev/null
+++ b/Data/DefaultContent/Libraries/md5.lua/.travis.yml
@@ -0,0 +1,34 @@
+language: python
+sudo: false
+
+env:
+ - LUA="lua=5.1"
+ - LUA="lua=5.2"
+ - LUA="lua=5.3"
+ - LUA="luajit=2.0"
+ - LUA="luajit=2.1"
+
+before_install:
+ - pip install hererocks
+ - hererocks lua_install -r^ --$LUA
+ - export PATH=$PATH:$PWD/lua_install/bin # Add directory with all installed binaries to PATH
+
+install:
+ - luarocks install busted
+ - luarocks install luacov
+ - luarocks install luacov-coveralls
+
+script:
+ - busted --verbose --coverage
+
+after_success:
+ - luacov-coveralls --exclude $TRAVIS_BUILD_DIR/lua_install
+
+branches:
+ except:
+ - gh-pages
+
+notifications:
+ email:
+ on_success: change
+ on_failure: always
diff --git a/Data/DefaultContent/Libraries/md5.lua/CHANGELOG.md b/Data/DefaultContent/Libraries/md5.lua/CHANGELOG.md
new file mode 100644
index 0000000..a48c47a
--- /dev/null
+++ b/Data/DefaultContent/Libraries/md5.lua/CHANGELOG.md
@@ -0,0 +1,5 @@
+
+# 1.1.0
+
+* Fixes error with long strings in Lua 5.1 (@pgimeno)
+* Adds incremental mode (@pgimeno)
diff --git a/Data/DefaultContent/Libraries/md5.lua/MIT-LICENSE.txt b/Data/DefaultContent/Libraries/md5.lua/MIT-LICENSE.txt
new file mode 100644
index 0000000..1630e47
--- /dev/null
+++ b/Data/DefaultContent/Libraries/md5.lua/MIT-LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright (c) 2013 Enrique García Cota + Adam Baldwin + hanzao + Equi 4 Software
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Data/DefaultContent/Libraries/md5.lua/README.md b/Data/DefaultContent/Libraries/md5.lua/README.md
new file mode 100644
index 0000000..ee7bbd8
--- /dev/null
+++ b/Data/DefaultContent/Libraries/md5.lua/README.md
@@ -0,0 +1,62 @@
+md5.lua [![Build Status](https://travis-ci.org/kikito/md5.lua.svg)](https://travis-ci.org/kikito/md5.lua)
+=========================================================================================================
+
+This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1.
+
+It implements md5.sum and md5.sumhex like the [kernel project md5 package](http://www.keplerproject.org/md5/), but it's done completely in Lua, with no dependencies on other libs or C files.
+
+Usage
+=====
+
+Simple example:
+
+ local md5 = require 'md5'
+
+ local md5_as_data = md5.sum(message) -- returns raw bytes
+ local md5_as_hex = md5.sumhexa(message) -- returns a hex string
+ local md5_as_hex2 = md5.tohex(md5_as_data) -- returns the same string as md5_as_hex
+
+Incremental example (for computing md5 of streams, or big files which have to be loaded in chunks - new since 1.1.0):
+
+ local m = md5.new()
+ m:update('some bytes')
+ m:update('some more bytes')
+ m:update('etc')
+ return md5.tohex(m:finish())
+
+Credits
+=======
+
+This is a cleanup of an implementation by Adam Baldwin - https://gist.github.com/evilpacket/3647908
+
+Which in turn was a mix of the bitwise lib, http://luaforge.net/projects/bit/ by hanzhao (`abrash_han - at - hotmail.com`),
+and http://equi4.com/md5/md5calc.lua, by Equi 4 Software.
+
+Lua 5.2 and LuaJIT compatibility by [Positive07](https://github.com/kikito/md5.lua/pull/2)
+
+A very important fix and the incremental variant by [pgimeno](https://github.com/kikito/md5.lua/pull/10)
+
+
+License
+=======
+
+This library, as well as all the previous ones in which is based, is released under the MIT license (See license file for details).
+
+Specs
+=====
+
+The specs for this library are implemented with [busted](http://ovinelabs.com/busted/). In order to run them, install busted and then:
+
+ cd path/to/where/the/spec/folder/is
+ busted
+
+Install
+=======
+
+Either copy the file or using luarocks:
+
+ luarocks install --server=http://luarocks.org/manifests/kikito md5
+
+
+
+
diff --git a/Data/DefaultContent/Libraries/md5.lua/md5.lua b/Data/DefaultContent/Libraries/md5.lua/md5.lua
new file mode 100644
index 0000000..5e73ba6
--- /dev/null
+++ b/Data/DefaultContent/Libraries/md5.lua/md5.lua
@@ -0,0 +1,396 @@
+local md5 = {
+ _VERSION = "md5.lua 1.1.0",
+ _DESCRIPTION = "MD5 computation in Lua (5.1-3, LuaJIT)",
+ _URL = "https://github.com/kikito/md5.lua",
+ _LICENSE = [[
+ MIT LICENSE
+
+ Copyright (c) 2013 Enrique García Cota + Adam Baldwin + hanzao + Equi 4 Software
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ ]]
+}
+
+-- bit lib implementions
+
+local char, byte, format, rep, sub =
+ string.char, string.byte, string.format, string.rep, string.sub
+local bit_or, bit_and, bit_not, bit_xor, bit_rshift, bit_lshift
+
+local ok, bit = pcall(require, 'bit')
+if ok then
+ bit_or, bit_and, bit_not, bit_xor, bit_rshift, bit_lshift = bit.bor, bit.band, bit.bnot, bit.bxor, bit.rshift, bit.lshift
+else
+ ok, bit = pcall(require, 'bit32')
+
+ if ok then
+
+ bit_not = bit.bnot
+
+ local tobit = function(n)
+ return n <= 0x7fffffff and n or -(bit_not(n) + 1)
+ end
+
+ local normalize = function(f)
+ return function(a,b) return tobit(f(tobit(a), tobit(b))) end
+ end
+
+ bit_or, bit_and, bit_xor = normalize(bit.bor), normalize(bit.band), normalize(bit.bxor)
+ bit_rshift, bit_lshift = normalize(bit.rshift), normalize(bit.lshift)
+
+ else
+
+ local function tbl2number(tbl)
+ local result = 0
+ local power = 1
+ for i = 1, #tbl do
+ result = result + tbl[i] * power
+ power = power * 2
+ end
+ return result
+ end
+
+ local function expand(t1, t2)
+ local big, small = t1, t2
+ if(#big < #small) then
+ big, small = small, big
+ end
+ -- expand small
+ for i = #small + 1, #big do
+ small[i] = 0
+ end
+ end
+
+ local to_bits -- needs to be declared before bit_not
+
+ bit_not = function(n)
+ local tbl = to_bits(n)
+ local size = math.max(#tbl, 32)
+ for i = 1, size do
+ if(tbl[i] == 1) then
+ tbl[i] = 0
+ else
+ tbl[i] = 1
+ end
+ end
+ return tbl2number(tbl)
+ end
+
+ -- defined as local above
+ to_bits = function (n)
+ if(n < 0) then
+ -- negative
+ return to_bits(bit_not(math.abs(n)) + 1)
+ end
+ -- to bits table
+ local tbl = {}
+ local cnt = 1
+ local last
+ while n > 0 do
+ last = n % 2
+ tbl[cnt] = last
+ n = (n-last)/2
+ cnt = cnt + 1
+ end
+
+ return tbl
+ end
+
+ bit_or = function(m, n)
+ local tbl_m = to_bits(m)
+ local tbl_n = to_bits(n)
+ expand(tbl_m, tbl_n)
+
+ local tbl = {}
+ for i = 1, #tbl_m do
+ if(tbl_m[i]== 0 and tbl_n[i] == 0) then
+ tbl[i] = 0
+ else
+ tbl[i] = 1
+ end
+ end
+
+ return tbl2number(tbl)
+ end
+
+ bit_and = function(m, n)
+ local tbl_m = to_bits(m)
+ local tbl_n = to_bits(n)
+ expand(tbl_m, tbl_n)
+
+ local tbl = {}
+ for i = 1, #tbl_m do
+ if(tbl_m[i]== 0 or tbl_n[i] == 0) then
+ tbl[i] = 0
+ else
+ tbl[i] = 1
+ end
+ end
+
+ return tbl2number(tbl)
+ end
+
+ bit_xor = function(m, n)
+ local tbl_m = to_bits(m)
+ local tbl_n = to_bits(n)
+ expand(tbl_m, tbl_n)
+
+ local tbl = {}
+ for i = 1, #tbl_m do
+ if(tbl_m[i] ~= tbl_n[i]) then
+ tbl[i] = 1
+ else
+ tbl[i] = 0
+ end
+ end
+
+ return tbl2number(tbl)
+ end
+
+ bit_rshift = function(n, bits)
+ local high_bit = 0
+ if(n < 0) then
+ -- negative
+ n = bit_not(math.abs(n)) + 1
+ high_bit = 0x80000000
+ end
+
+ local floor = math.floor
+
+ for i=1, bits do
+ n = n/2
+ n = bit_or(floor(n), high_bit)
+ end
+ return floor(n)
+ end
+
+ bit_lshift = function(n, bits)
+ if(n < 0) then
+ -- negative
+ n = bit_not(math.abs(n)) + 1
+ end
+
+ for i=1, bits do
+ n = n*2
+ end
+ return bit_and(n, 0xFFFFFFFF)
+ end
+ end
+end
+
+-- convert little-endian 32-bit int to a 4-char string
+local function lei2str(i)
+ local f=function (s) return char( bit_and( bit_rshift(i, s), 255)) end
+ return f(0)..f(8)..f(16)..f(24)
+end
+
+-- convert raw string to big-endian int
+local function str2bei(s)
+ local v=0
+ for i=1, #s do
+ v = v * 256 + byte(s, i)
+ end
+ return v
+end
+
+-- convert raw string to little-endian int
+local function str2lei(s)
+ local v=0
+ for i = #s,1,-1 do
+ v = v*256 + byte(s, i)
+ end
+ return v
+end
+
+-- cut up a string in little-endian ints of given size
+local function cut_le_str(s,...)
+ local o, r = 1, {}
+ local args = {...}
+ for i=1, #args do
+ table.insert(r, str2lei(sub(s, o, o + args[i] - 1)))
+ o = o + args[i]
+ end
+ return r
+end
+
+local swap = function (w) return str2bei(lei2str(w)) end
+
+-- An MD5 mplementation in Lua, requires bitlib (hacked to use LuaBit from above, ugh)
+-- 10/02/2001 jcw@equi4.com
+
+local CONSTS = {
+ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+ 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
+ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
+ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
+}
+
+local f=function (x,y,z) return bit_or(bit_and(x,y),bit_and(-x-1,z)) end
+local g=function (x,y,z) return bit_or(bit_and(x,z),bit_and(y,-z-1)) end
+local h=function (x,y,z) return bit_xor(x,bit_xor(y,z)) end
+local i=function (x,y,z) return bit_xor(y,bit_or(x,-z-1)) end
+local z=function (ff,a,b,c,d,x,s,ac)
+ a=bit_and(a+ff(b,c,d)+x+ac,0xFFFFFFFF)
+ -- be *very* careful that left shift does not cause rounding!
+ return bit_or(bit_lshift(bit_and(a,bit_rshift(0xFFFFFFFF,s)),s),bit_rshift(a,32-s))+b
+end
+
+local function transform(A,B,C,D,X)
+ local a,b,c,d=A,B,C,D
+ local t=CONSTS
+
+ a=z(f,a,b,c,d,X[ 0], 7,t[ 1])
+ d=z(f,d,a,b,c,X[ 1],12,t[ 2])
+ c=z(f,c,d,a,b,X[ 2],17,t[ 3])
+ b=z(f,b,c,d,a,X[ 3],22,t[ 4])
+ a=z(f,a,b,c,d,X[ 4], 7,t[ 5])
+ d=z(f,d,a,b,c,X[ 5],12,t[ 6])
+ c=z(f,c,d,a,b,X[ 6],17,t[ 7])
+ b=z(f,b,c,d,a,X[ 7],22,t[ 8])
+ a=z(f,a,b,c,d,X[ 8], 7,t[ 9])
+ d=z(f,d,a,b,c,X[ 9],12,t[10])
+ c=z(f,c,d,a,b,X[10],17,t[11])
+ b=z(f,b,c,d,a,X[11],22,t[12])
+ a=z(f,a,b,c,d,X[12], 7,t[13])
+ d=z(f,d,a,b,c,X[13],12,t[14])
+ c=z(f,c,d,a,b,X[14],17,t[15])
+ b=z(f,b,c,d,a,X[15],22,t[16])
+
+ a=z(g,a,b,c,d,X[ 1], 5,t[17])
+ d=z(g,d,a,b,c,X[ 6], 9,t[18])
+ c=z(g,c,d,a,b,X[11],14,t[19])
+ b=z(g,b,c,d,a,X[ 0],20,t[20])
+ a=z(g,a,b,c,d,X[ 5], 5,t[21])
+ d=z(g,d,a,b,c,X[10], 9,t[22])
+ c=z(g,c,d,a,b,X[15],14,t[23])
+ b=z(g,b,c,d,a,X[ 4],20,t[24])
+ a=z(g,a,b,c,d,X[ 9], 5,t[25])
+ d=z(g,d,a,b,c,X[14], 9,t[26])
+ c=z(g,c,d,a,b,X[ 3],14,t[27])
+ b=z(g,b,c,d,a,X[ 8],20,t[28])
+ a=z(g,a,b,c,d,X[13], 5,t[29])
+ d=z(g,d,a,b,c,X[ 2], 9,t[30])
+ c=z(g,c,d,a,b,X[ 7],14,t[31])
+ b=z(g,b,c,d,a,X[12],20,t[32])
+
+ a=z(h,a,b,c,d,X[ 5], 4,t[33])
+ d=z(h,d,a,b,c,X[ 8],11,t[34])
+ c=z(h,c,d,a,b,X[11],16,t[35])
+ b=z(h,b,c,d,a,X[14],23,t[36])
+ a=z(h,a,b,c,d,X[ 1], 4,t[37])
+ d=z(h,d,a,b,c,X[ 4],11,t[38])
+ c=z(h,c,d,a,b,X[ 7],16,t[39])
+ b=z(h,b,c,d,a,X[10],23,t[40])
+ a=z(h,a,b,c,d,X[13], 4,t[41])
+ d=z(h,d,a,b,c,X[ 0],11,t[42])
+ c=z(h,c,d,a,b,X[ 3],16,t[43])
+ b=z(h,b,c,d,a,X[ 6],23,t[44])
+ a=z(h,a,b,c,d,X[ 9], 4,t[45])
+ d=z(h,d,a,b,c,X[12],11,t[46])
+ c=z(h,c,d,a,b,X[15],16,t[47])
+ b=z(h,b,c,d,a,X[ 2],23,t[48])
+
+ a=z(i,a,b,c,d,X[ 0], 6,t[49])
+ d=z(i,d,a,b,c,X[ 7],10,t[50])
+ c=z(i,c,d,a,b,X[14],15,t[51])
+ b=z(i,b,c,d,a,X[ 5],21,t[52])
+ a=z(i,a,b,c,d,X[12], 6,t[53])
+ d=z(i,d,a,b,c,X[ 3],10,t[54])
+ c=z(i,c,d,a,b,X[10],15,t[55])
+ b=z(i,b,c,d,a,X[ 1],21,t[56])
+ a=z(i,a,b,c,d,X[ 8], 6,t[57])
+ d=z(i,d,a,b,c,X[15],10,t[58])
+ c=z(i,c,d,a,b,X[ 6],15,t[59])
+ b=z(i,b,c,d,a,X[13],21,t[60])
+ a=z(i,a,b,c,d,X[ 4], 6,t[61])
+ d=z(i,d,a,b,c,X[11],10,t[62])
+ c=z(i,c,d,a,b,X[ 2],15,t[63])
+ b=z(i,b,c,d,a,X[ 9],21,t[64])
+
+ return bit_and(A+a,0xFFFFFFFF),bit_and(B+b,0xFFFFFFFF),
+ bit_and(C+c,0xFFFFFFFF),bit_and(D+d,0xFFFFFFFF)
+end
+
+----------------------------------------------------------------
+
+local function md5_update(self, s)
+ self.pos = self.pos + #s
+ s = self.buf .. s
+ for ii = 1, #s - 63, 64 do
+ local X = cut_le_str(sub(s,ii,ii+63),4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4)
+ assert(#X == 16)
+ X[0] = table.remove(X,1) -- zero based!
+ self.a,self.b,self.c,self.d = transform(self.a,self.b,self.c,self.d,X)
+ end
+ self.buf = sub(s, math.floor(#s/64)*64 + 1, #s)
+ return self
+end
+
+local function md5_finish(self)
+ local msgLen = self.pos
+ local padLen = 56 - msgLen % 64
+
+ if msgLen % 64 > 56 then padLen = padLen + 64 end
+
+ if padLen == 0 then padLen = 64 end
+
+ local s = char(128) .. rep(char(0),padLen-1) .. lei2str(bit_and(8*msgLen, 0xFFFFFFFF)) .. lei2str(math.floor(msgLen/0x20000000))
+ md5_update(self, s)
+
+ assert(self.pos % 64 == 0)
+ return lei2str(self.a) .. lei2str(self.b) .. lei2str(self.c) .. lei2str(self.d)
+end
+
+----------------------------------------------------------------
+
+function md5.new()
+ return { a = CONSTS[65], b = CONSTS[66], c = CONSTS[67], d = CONSTS[68],
+ pos = 0,
+ buf = '',
+ update = md5_update,
+ finish = md5_finish }
+end
+
+function md5.tohex(s)
+ return format("%08x%08x%08x%08x", str2bei(sub(s, 1, 4)), str2bei(sub(s, 5, 8)), str2bei(sub(s, 9, 12)), str2bei(sub(s, 13, 16)))
+end
+
+function md5.sum(s)
+ return md5.new():update(s):finish()
+end
+
+function md5.sumhexa(s)
+ return md5.tohex(md5.sum(s))
+end
+
+return md5
diff --git a/Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.0-0.rockspec b/Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.0-0.rockspec
new file mode 100644
index 0000000..4103148
--- /dev/null
+++ b/Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.0-0.rockspec
@@ -0,0 +1,21 @@
+package = "md5"
+version = "1.0-0"
+source = {
+ url = "https://github.com/kikito/md5.lua/archive/v1.0.0.tar.gz",
+ dir = "md5.lua-1.0.0"
+}
+description = {
+ summary = "MD5 sum in pure Lua, with no C and no external dependencies",
+ detailed = "This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1",
+ homepage = "https://github.com/kikito/md5.lua",
+ license = "MIT"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ md5 = "md5.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.0-1.rockspec b/Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.0-1.rockspec
new file mode 100644
index 0000000..f9f5203
--- /dev/null
+++ b/Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.0-1.rockspec
@@ -0,0 +1,21 @@
+package = "md5"
+version = "1.0-1"
+source = {
+ url = "https://github.com/kikito/md5.lua/archive/v1.0.1.tar.gz",
+ dir = "md5.lua-1.0.1"
+}
+description = {
+ summary = "MD5 sum in pure Lua, with no C and no external dependencies",
+ detailed = "This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1",
+ homepage = "https://github.com/kikito/md5.lua",
+ license = "MIT"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ md5 = "md5.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.0-2.rockspec b/Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.0-2.rockspec
new file mode 100644
index 0000000..c8034f9
--- /dev/null
+++ b/Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.0-2.rockspec
@@ -0,0 +1,21 @@
+package = "md5"
+version = "1.0-2"
+source = {
+ url = "https://github.com/kikito/md5.lua/archive/v1.0.2.tar.gz",
+ dir = "md5.lua-1.0.2"
+}
+description = {
+ summary = "MD5 sum in pure Lua, with no C and no external dependencies",
+ detailed = "This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1",
+ homepage = "https://github.com/kikito/md5.lua",
+ license = "MIT"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ md5 = "md5.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.1-0.rockspec b/Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.1-0.rockspec
new file mode 100644
index 0000000..ef1b392
--- /dev/null
+++ b/Data/DefaultContent/Libraries/md5.lua/rockspecs/md5-1.1-0.rockspec
@@ -0,0 +1,21 @@
+package = "md5"
+version = "1.1-0"
+source = {
+ url = "https://github.com/kikito/md5.lua/archive/v1.1.0.tar.gz",
+ dir = "md5.lua-1.1.0"
+}
+description = {
+ summary = "MD5 sum in pure Lua, with no C and no external dependencies",
+ detailed = "This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1",
+ homepage = "https://github.com/kikito/md5.lua",
+ license = "MIT"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ md5 = "md5.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/md5.lua/spec/md5_spec.lua b/Data/DefaultContent/Libraries/md5.lua/spec/md5_spec.lua
new file mode 100644
index 0000000..69dde39
--- /dev/null
+++ b/Data/DefaultContent/Libraries/md5.lua/spec/md5_spec.lua
@@ -0,0 +1,40 @@
+local md5 = require('md5')
+
+local function hex2bin(hex)
+ local result, _ = hex:gsub('..', function(hexval)
+ return string.char(tonumber(hexval, 16))
+ end)
+ return result
+end
+
+describe('md5', function()
+ describe('md5.sumhexa', function()
+ it('works', function()
+ assert.equal(md5.sumhexa("asdf"), '912ec803b2ce49e4a541068d495ab570')
+ assert.equal(md5.sumhexa('The quick brown fox jumps over the lazy dog'), '9e107d9d372bb6826bd81d3542a419d6')
+ assert.equal(md5.sumhexa('The quick brown fox jumps over the lazy dog.'), 'e4d909c290d0fb1ca068ffaddf22cbd0')
+ assert.equal(md5.sumhexa(''), 'd41d8cd98f00b204e9800998ecf8427e')
+ assert.equal(md5.sumhexa(('1'):rep(824)), 'a126fd3611ab8d9b7e8a3384e2fa78a0')
+ assert.equal(md5.sumhexa(('1'):rep(1528)), '3750b6a29d923b633e05d6ae76895664')
+ local state = md5.new()
+ state:update('Hello')
+ state:update(', World!')
+ assert.equal(md5.tohex(state:finish()), '65a8e27d8879283831b664bd8b7f0ad4')
+ end)
+ end)
+
+ describe('md5.sum', function()
+ it('works', function()
+ assert.equal(md5.sum("asdf"), hex2bin '912ec803b2ce49e4a541068d495ab570')
+ assert.equal(md5.sum('The quick brown fox jumps over the lazy dog'), hex2bin '9e107d9d372bb6826bd81d3542a419d6')
+ assert.equal(md5.sum('The quick brown fox jumps over the lazy dog.'), hex2bin 'e4d909c290d0fb1ca068ffaddf22cbd0')
+ assert.equal(md5.sum(''), hex2bin 'd41d8cd98f00b204e9800998ecf8427e')
+ assert.equal(md5.sum(('1'):rep(824)), hex2bin 'a126fd3611ab8d9b7e8a3384e2fa78a0')
+ assert.equal(md5.sum(('1'):rep(1528)), hex2bin '3750b6a29d923b633e05d6ae76895664')
+ local state = md5.new()
+ state:update('Hello')
+ state:update(', World!')
+ assert.equal(state:finish(), hex2bin '65a8e27d8879283831b664bd8b7f0ad4')
+ end)
+ end)
+end)
diff --git a/Data/DefaultContent/Libraries/middleclass/.travis.yml b/Data/DefaultContent/Libraries/middleclass/.travis.yml
new file mode 100644
index 0000000..53998d6
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/.travis.yml
@@ -0,0 +1,36 @@
+language: python
+sudo: false
+
+env:
+ - LUA="lua=5.1"
+ - LUA="lua=5.2"
+ - LUA="lua=5.3"
+ - LUA="luajit=2.0"
+ - LUA="luajit=2.1"
+
+before_install:
+ - pip install hererocks
+ - hererocks lua_install -r^ --$LUA
+ - export PATH=$PATH:$PWD/lua_install/bin # Add directory with all installed binaries to PATH
+
+install:
+ - luarocks install luacheck
+ - luarocks install busted
+ - luarocks install luacov
+ - luarocks install luacov-coveralls
+
+script:
+ - luacheck --no-unused-args --std max+busted *.lua spec
+ - busted --verbose --coverage
+
+after_success:
+ - luacov-coveralls --exclude $TRAVIS_BUILD_DIR/lua_install
+
+branches:
+ except:
+ - gh-pages
+
+notifications:
+ email:
+ on_success: change
+ on_failure: always
diff --git a/Data/DefaultContent/Libraries/middleclass/CHANGELOG.md b/Data/DefaultContent/Libraries/middleclass/CHANGELOG.md
new file mode 100644
index 0000000..5f8b93a
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/CHANGELOG.md
@@ -0,0 +1,55 @@
+middleclass changelog
+====================
+
+# Version 4.1.1
+
+* Fixed a bug in which `static` values which evaluated to `false` were not available
+ in subclasses (#51, thanks @qaisjp for the patch!)
+* `isInstanceOf` does not throw an error any more when its first parameter is a
+ primitive (#55) (This effectively undoes the change introduced in 4.1.0)
+
+
+# Version 4.1.0
+
+* Simplifies implementation of `isInstanceOf` and `isSubclassOf`. They will now raise an error if their first
+ parameter (the `self`) isn't an instance or a class respectively.
+
+# Version 4.0.0
+
+* Unified the method and metamethod lookup into a single algorithm
+* Added the capacity of setting up the `__index` metamethod in classes
+* Removed global `Object` (classes created with `class(<name>)` have no superclass now)
+* Removed default method `Class:implements(<mixin>)`
+* Renamed several internal functions
+
+# Version 3.2.0
+
+* Changed the way metamethods were handled to fix certain bugs (un-stubbed metamethods could not be inherited)
+
+# Version 3.1.0
+
+* Added Lua 5.3 metamethod support (`__band`, `__bor`, `__bxor`, `__shl`, `__bnot`)
+
+# Version 3.0.1
+
+* Added `__len`, `__ipairs` and `__pairs` metamethods for Lua 5.2
+
+# Version 3.0
+
+* Anything that behaves reasonably like a class can be a class (no internal list of classes)
+* The `class` global function is now just the return value of `require
+'middleclass'`. It is a callable table, but works exactly as before.
+* The global variable `Object` becomes `class.Object`
+* The global function `instanceOf` becomes `class.Object.isInstanceOf`. Parameter order is reversed.
+* The global function `subclassOf` becomes `class.Object.static.isSubclassOf`. Parameter order is reversed.
+* The global function `implements` becomes `class.Object.static.implements`. Parameter order is reversed.
+* Specs have been translated from telescope to busted
+
+# Version 2.0
+
+* Static methods are now separated from instance methods
+* class.superclass has now become class.super
+* It's now possible to do class.subclasses
+* middleclass is now a single file; init.lua has dissapeared
+* license is changed from BSD to MIT. License included in source FTW
+
diff --git a/Data/DefaultContent/Libraries/middleclass/MIT-LICENSE.txt b/Data/DefaultContent/Libraries/middleclass/MIT-LICENSE.txt
new file mode 100644
index 0000000..525287a
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/MIT-LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright (c) 2011 Enrique García Cota
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Data/DefaultContent/Libraries/middleclass/README.md b/Data/DefaultContent/Libraries/middleclass/README.md
new file mode 100644
index 0000000..fc1153b
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/README.md
@@ -0,0 +1,80 @@
+middleclass
+===========
+
+[![Build Status](https://travis-ci.org/kikito/middleclass.png?branch=master)](https://travis-ci.org/kikito/middleclass)
+[![Coverage Status](https://coveralls.io/repos/kikito/middleclass/badge.svg?branch=master&service=github)](https://coveralls.io/github/kikito/middleclass?branch=master)
+
+A simple OOP library for Lua. It has inheritance, metamethods (operators), class variables and weak mixin support.
+
+Quick Look
+==========
+
+```lua
+local class = require 'middleclass'
+
+local Fruit = class('Fruit') -- 'Fruit' is the class' name
+
+function Fruit:initialize(sweetness)
+ self.sweetness = sweetness
+end
+
+Fruit.static.sweetness_threshold = 5 -- class variable (also admits methods)
+
+function Fruit:isSweet()
+ return self.sweetness > Fruit.sweetness_threshold
+end
+
+local Lemon = class('Lemon', Fruit) -- subclassing
+
+function Lemon:initialize()
+ Fruit.initialize(self, 1) -- invoking the superclass' initializer
+end
+
+local lemon = Lemon:new()
+
+print(lemon:isSweet()) -- false
+```
+
+Documentation
+=============
+
+See the [github wiki page](https://github.com/kikito/middleclass/wiki) for examples & documentation.
+
+You can read the `CHANGELOG.md` file to see what has changed on each version of this library.
+
+If you need help updating to a new middleclass version, read `UPDATING.md`.
+
+Installation
+============
+
+Just copy the middleclass.lua file wherever you want it (for example on a lib/ folder). Then write this in any Lua file where you want to use it:
+
+```lua
+local class = require 'middleclass'
+```
+
+Specs
+=====
+
+This project uses [busted](http://olivinelabs.com/busted/) for its specs. If you want to run the specs, you will have to install it first. Then just execute the following:
+
+```bash
+cd /folder/where/the/spec/folder/is
+busted
+```
+
+Performance tests
+=================
+
+Middleclass also comes with a small performance test suite. Just run the following command:
+
+```bash
+lua performance/run.lua
+```
+
+License
+=======
+
+Middleclass is distributed under the MIT license.
+
+
diff --git a/Data/DefaultContent/Libraries/middleclass/UPDATING.md b/Data/DefaultContent/Libraries/middleclass/UPDATING.md
new file mode 100644
index 0000000..83855c9
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/UPDATING.md
@@ -0,0 +1,69 @@
+Updating from 3.x to 4.x
+========================
+
+In middleclass 4.0 there is no global `Object` class any more. Classes created with `class(<name>)` don't have a superclass any more.
+If you need a global `Object` class, you must create it explicitly and then use it when creating new classes:
+
+```lua
+local Object = class('Object')
+
+...
+
+local MyClass = class('MyClass', Object)
+```
+
+If you are using a library which depends on the internal implementation of middleclass they might not work with middleclass 4.0. You might need to update those other libraries.
+
+Middleclass 4.0 comes with support for `__index` metamethod support. If your library manipulated the classes' `__instanceDict` internal attribute, you might do the same thing now using `__index` instead.
+
+Also note that the class method `:implements` has been removed.
+
+Updating from 2.x to 3.x
+========================
+
+Middleclass used to expose several global variables on the main scope. It does not do that anymore.
+
+`class` is now returned by `require 'middleclass'`, and it is not set globally. So you can do this:
+
+```lua
+local class = require 'middleclass'
+local MyClass = class('MyClass') -- works as before
+```
+
+`Object` is not a global variable any more. But you can get it from `class.Object`
+
+```lua
+local class = require 'middleclass'
+local Object = class.Object
+
+print(Object) -- prints 'class Object'
+```
+
+The public functions `instanceOf`, `subclassOf` and `includes` have been replaced by `Object.isInstanceOf`, `Object.static.isSubclassOf` and `Object.static.includes`.
+
+Prior to 3.x:
+
+```lua
+instanceOf(MyClass, obj)
+subclassOf(Object, aClass)
+includes(aMixin, aClass)
+```
+
+Since 3.x:
+
+```lua
+obj:isInstanceOf(MyClass)
+aClass:isSubclassOf(Object)
+aClass:includes(aMixin)
+```
+
+The 3.x code snippet will throw an error if `obj` is not an object, or if `aClass` is not a class (since they will not implement `isInstanceOf`, `isSubclassOf` or `includes`).
+If you are unsure of whether `obj` and `aClass` are an object or a class, you can use the methods in `Object`. They are prepared to work with random types, not just classes and instances:
+
+```lua
+Object.isInstanceOf(obj, MyClass)
+Object.isSubclassOf(aClass, Object)
+Object.includes(aClass, aMixin)
+```
+
+Notice that the parameter order is not the same now as it was in 2.x. Also note the change in naming: `isInstanceOf` instead of `instanceOf`, and `isSubclassOf` instead of `subclassOf`.
diff --git a/Data/DefaultContent/Libraries/middleclass/middleclass.lua b/Data/DefaultContent/Libraries/middleclass/middleclass.lua
new file mode 100644
index 0000000..7e36bcd
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/middleclass.lua
@@ -0,0 +1,183 @@
+local middleclass = {
+ _VERSION = 'middleclass v4.1.1',
+ _DESCRIPTION = 'Object Orientation for Lua',
+ _URL = 'https://github.com/kikito/middleclass',
+ _LICENSE = [[
+ MIT LICENSE
+
+ Copyright (c) 2011 Enrique García Cota
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ ]]
+}
+
+local function _createIndexWrapper(aClass, f)
+ if f == nil then
+ return aClass.__instanceDict
+ else
+ return function(self, name)
+ local value = aClass.__instanceDict[name]
+
+ if value ~= nil then
+ return value
+ elseif type(f) == "function" then
+ return (f(self, name))
+ else
+ return f[name]
+ end
+ end
+ end
+end
+
+local function _propagateInstanceMethod(aClass, name, f)
+ f = name == "__index" and _createIndexWrapper(aClass, f) or f
+ aClass.__instanceDict[name] = f
+
+ for subclass in pairs(aClass.subclasses) do
+ if rawget(subclass.__declaredMethods, name) == nil then
+ _propagateInstanceMethod(subclass, name, f)
+ end
+ end
+end
+
+local function _declareInstanceMethod(aClass, name, f)
+ aClass.__declaredMethods[name] = f
+
+ if f == nil and aClass.super then
+ f = aClass.super.__instanceDict[name]
+ end
+
+ _propagateInstanceMethod(aClass, name, f)
+end
+
+local function _tostring(self) return "class " .. self.name end
+local function _call(self, ...) return self:new(...) end
+
+local function _createClass(name, super)
+ local dict = {}
+ dict.__index = dict
+
+ local aClass = { name = name, super = super, static = {},
+ __instanceDict = dict, __declaredMethods = {},
+ subclasses = setmetatable({}, {__mode='k'}) }
+
+ if super then
+ setmetatable(aClass.static, {
+ __index = function(_,k)
+ local result = rawget(dict,k)
+ if result == nil then
+ return super.static[k]
+ end
+ return result
+ end
+ })
+ else
+ setmetatable(aClass.static, { __index = function(_,k) return rawget(dict,k) end })
+ end
+
+ setmetatable(aClass, { __index = aClass.static, __tostring = _tostring,
+ __call = _call, __newindex = _declareInstanceMethod })
+
+ return aClass
+end
+
+local function _includeMixin(aClass, mixin)
+ assert(type(mixin) == 'table', "mixin must be a table")
+
+ for name,method in pairs(mixin) do
+ if name ~= "included" and name ~= "static" then aClass[name] = method end
+ end
+
+ for name,method in pairs(mixin.static or {}) do
+ aClass.static[name] = method
+ end
+
+ if type(mixin.included)=="function" then mixin:included(aClass) end
+ return aClass
+end
+
+local DefaultMixin = {
+ __tostring = function(self) return "instance of " .. tostring(self.class) end,
+
+ initialize = function(self, ...) end,
+
+ isInstanceOf = function(self, aClass)
+ return type(aClass) == 'table'
+ and type(self) == 'table'
+ and (self.class == aClass
+ or type(self.class) == 'table'
+ and type(self.class.isSubclassOf) == 'function'
+ and self.class:isSubclassOf(aClass))
+ end,
+
+ static = {
+ allocate = function(self)
+ assert(type(self) == 'table', "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'")
+ return setmetatable({ class = self }, self.__instanceDict)
+ end,
+
+ new = function(self, ...)
+ assert(type(self) == 'table', "Make sure that you are using 'Class:new' instead of 'Class.new'")
+ local instance = self:allocate()
+ instance:initialize(...)
+ return instance
+ end,
+
+ subclass = function(self, name)
+ assert(type(self) == 'table', "Make sure that you are using 'Class:subclass' instead of 'Class.subclass'")
+ assert(type(name) == "string", "You must provide a name(string) for your class")
+
+ local subclass = _createClass(name, self)
+
+ for methodName, f in pairs(self.__instanceDict) do
+ _propagateInstanceMethod(subclass, methodName, f)
+ end
+ subclass.initialize = function(instance, ...) return self.initialize(instance, ...) end
+
+ self.subclasses[subclass] = true
+ self:subclassed(subclass)
+
+ return subclass
+ end,
+
+ subclassed = function(self, other) end,
+
+ isSubclassOf = function(self, other)
+ return type(other) == 'table' and
+ type(self.super) == 'table' and
+ ( self.super == other or self.super:isSubclassOf(other) )
+ end,
+
+ include = function(self, ...)
+ assert(type(self) == 'table', "Make sure you that you are using 'Class:include' instead of 'Class.include'")
+ for _,mixin in ipairs({...}) do _includeMixin(self, mixin) end
+ return self
+ end
+ }
+}
+
+function middleclass.class(name, super)
+ assert(type(name) == 'string', "A name (string) is needed for the new class")
+ return super and super:subclass(name) or _includeMixin(_createClass(name), DefaultMixin)
+end
+
+setmetatable(middleclass, { __call = function(_, ...) return middleclass.class(...) end })
+
+return middleclass
diff --git a/Data/DefaultContent/Libraries/middleclass/performance/run.lua b/Data/DefaultContent/Libraries/middleclass/performance/run.lua
new file mode 100644
index 0000000..8d8ba47
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/performance/run.lua
@@ -0,0 +1,43 @@
+local class = require 'middleclass'
+
+time = require 'performance/time'
+
+time('class creation', function()
+ local A = class('A')
+end)
+
+local A = class('A')
+
+time('instance creation', function()
+ local a = A:new()
+end)
+
+function A:foo()
+ return 1
+end
+
+local a = A:new()
+
+time('instance method invocation', function()
+ a:foo()
+end)
+
+local B = class('B', A)
+
+local b = B:new()
+
+time('inherited method invocation', function()
+ b:foo()
+end)
+
+function A.static:bar()
+ return 2
+end
+
+time('class method invocation', function()
+ A:bar()
+end)
+
+time('inherited class method invocation', function()
+ B:bar()
+end)
diff --git a/Data/DefaultContent/Libraries/middleclass/performance/time.lua b/Data/DefaultContent/Libraries/middleclass/performance/time.lua
new file mode 100644
index 0000000..dd02455
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/performance/time.lua
@@ -0,0 +1,13 @@
+return function(title, f)
+
+ collectgarbage()
+
+ local startTime = os.clock()
+
+ for i=0,10000 do f() end
+
+ local endTime = os.clock()
+
+ print( title, endTime - startTime )
+
+end
diff --git a/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-3.0-0.rockspec b/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-3.0-0.rockspec
new file mode 100644
index 0000000..f9ec58c
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-3.0-0.rockspec
@@ -0,0 +1,21 @@
+package = "middleclass"
+version = "3.0-0"
+source = {
+ url = "https://github.com/kikito/middleclass/archive/v3.0.0.tar.gz",
+ dir = "middleclass-3.0.0"
+}
+description = {
+ summary = "A simple OOP library for Lua",
+ detailed = "It has inheritance, metamethods (operators), class variables and weak mixin support",
+ homepage = "https://github.com/kikito/middleclass",
+ license = "MIT"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ middleclass = "middleclass.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-3.1-0.rockspec b/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-3.1-0.rockspec
new file mode 100644
index 0000000..24a233e
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-3.1-0.rockspec
@@ -0,0 +1,21 @@
+package = "middleclass"
+version = "3.1-0"
+source = {
+ url = "https://github.com/kikito/middleclass/archive/v3.1.0.tar.gz",
+ dir = "middleclass-3.1.0"
+}
+description = {
+ summary = "A simple OOP library for Lua",
+ detailed = "It has inheritance, metamethods (operators), class variables and weak mixin support",
+ homepage = "https://github.com/kikito/middleclass",
+ license = "MIT"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ middleclass = "middleclass.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-3.2-0.rockspec b/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-3.2-0.rockspec
new file mode 100644
index 0000000..03e3b30
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-3.2-0.rockspec
@@ -0,0 +1,21 @@
+package = "middleclass"
+version = "3.2-0"
+source = {
+ url = "https://github.com/kikito/middleclass/archive/v3.2.0.tar.gz",
+ dir = "middleclass-3.2.0"
+}
+description = {
+ summary = "A simple OOP library for Lua",
+ detailed = "It has inheritance, metamethods (operators), class variables and weak mixin support",
+ homepage = "https://github.com/kikito/middleclass",
+ license = "MIT"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ middleclass = "middleclass.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-4.0-0.rockspec b/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-4.0-0.rockspec
new file mode 100644
index 0000000..517984e
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-4.0-0.rockspec
@@ -0,0 +1,21 @@
+package = "middleclass"
+version = "4.0-0"
+source = {
+ url = "https://github.com/kikito/middleclass/archive/v4.0.0.tar.gz",
+ dir = "middleclass-4.0.0"
+}
+description = {
+ summary = "A simple OOP library for Lua",
+ detailed = "It has inheritance, metamethods (operators), class variables and weak mixin support",
+ homepage = "https://github.com/kikito/middleclass",
+ license = "MIT"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ middleclass = "middleclass.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-4.1-0.rockspec b/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-4.1-0.rockspec
new file mode 100644
index 0000000..dc710e9
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-4.1-0.rockspec
@@ -0,0 +1,21 @@
+package = "middleclass"
+version = "4.1-0"
+source = {
+ url = "https://github.com/kikito/middleclass/archive/v4.1.0.tar.gz",
+ dir = "middleclass-4.1.0"
+}
+description = {
+ summary = "A simple OOP library for Lua",
+ detailed = "It has inheritance, metamethods (operators), class variables and weak mixin support",
+ homepage = "https://github.com/kikito/middleclass",
+ license = "MIT"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ middleclass = "middleclass.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-4.1.1-0.rockspec b/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-4.1.1-0.rockspec
new file mode 100644
index 0000000..ddaacd9
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/rockspecs/middleclass-4.1.1-0.rockspec
@@ -0,0 +1,21 @@
+package = "middleclass"
+version = "4.1.1-0"
+source = {
+ url = "https://github.com/kikito/middleclass/archive/v4.1.1.tar.gz",
+ dir = "middleclass-4.1.1"
+}
+description = {
+ summary = "A simple OOP library for Lua",
+ detailed = "It has inheritance, metamethods (operators), class variables and weak mixin support",
+ homepage = "https://github.com/kikito/middleclass",
+ license = "MIT"
+}
+dependencies = {
+ "lua >= 5.1"
+}
+build = {
+ type = "builtin",
+ modules = {
+ middleclass = "middleclass.lua"
+ }
+}
diff --git a/Data/DefaultContent/Libraries/middleclass/spec/class_spec.lua b/Data/DefaultContent/Libraries/middleclass/spec/class_spec.lua
new file mode 100644
index 0000000..144cb9f
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/spec/class_spec.lua
@@ -0,0 +1,28 @@
+local class = require 'middleclass'
+
+describe('class()', function()
+
+ describe('when given no params', function()
+ it('it throws an error', function()
+ assert.error(class)
+ end)
+ end)
+
+ describe('when given a name', function()
+ it('the resulting class has the correct name and Object as its superclass', function()
+ local TheClass = class('TheClass')
+ assert.equal(TheClass.name, 'TheClass')
+ assert.is_nil(TheClass.super)
+ end)
+ end)
+
+ describe('when given a name and a superclass', function()
+ it('the resulting class has the correct name and superclass', function()
+ local TheSuperClass = class('TheSuperClass')
+ local TheSubClass = class('TheSubClass', TheSuperClass)
+ assert.equal(TheSubClass.name, 'TheSubClass')
+ assert.equal(TheSubClass.super, TheSuperClass)
+ end)
+ end)
+
+end)
diff --git a/Data/DefaultContent/Libraries/middleclass/spec/classes_spec.lua b/Data/DefaultContent/Libraries/middleclass/spec/classes_spec.lua
new file mode 100644
index 0000000..7942f18
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/spec/classes_spec.lua
@@ -0,0 +1,138 @@
+local class = require 'middleclass'
+
+describe('A Class', function()
+
+ describe('Default stuff', function()
+
+ local AClass
+
+ before_each(function()
+ AClass = class('AClass')
+ end)
+
+ describe('name', function()
+ it('is correctly set', function()
+ assert.equal(AClass.name, 'AClass')
+ end)
+ end)
+
+ describe('tostring', function()
+ it('returns "class *name*"', function()
+ assert.equal(tostring(AClass), 'class AClass')
+ end)
+ end)
+
+ describe('()', function()
+ it('returns an object, like Class:new()', function()
+ local obj = AClass()
+ assert.equal(obj.class, AClass)
+ end)
+ end)
+
+ describe('include', function()
+ it('throws an error when used without the :', function()
+ assert.error(function() AClass.include() end)
+ end)
+ it('throws an error when passed a non-table:', function()
+ assert.error(function() AClass:include(1) end)
+ end)
+ end)
+
+ describe('subclass', function()
+
+ it('throws an error when used without the :', function()
+ assert.error(function() AClass.subclass() end)
+ end)
+
+ it('throws an error when no name is given', function()
+ assert.error( function() AClass:subclass() end)
+ end)
+
+ describe('when given a subclass name', function()
+
+ local SubClass
+
+ before_each(function()
+ function AClass.static:subclassed(other) self.static.child = other end
+ SubClass = AClass:subclass('SubClass')
+ end)
+
+ it('it returns a class with the correct name', function()
+ assert.equal(SubClass.name, 'SubClass')
+ end)
+
+ it('it returns a class with the correct superclass', function()
+ assert.equal(SubClass.super, AClass)
+ end)
+
+ it('it invokes the subclassed hook method', function()
+ assert.equal(SubClass, AClass.child)
+ end)
+
+ it('it includes the subclass in the list of subclasses', function()
+ assert.is_true(AClass.subclasses[SubClass])
+ end)
+
+ end)
+
+ end)
+
+ end)
+
+
+
+ describe('attributes', function()
+
+ local A, B
+
+ before_each(function()
+ A = class('A')
+ A.static.foo = 'foo'
+
+ B = class('B', A)
+ end)
+
+ it('are available after being initialized', function()
+ assert.equal(A.foo, 'foo')
+ end)
+
+ it('are available for subclasses', function()
+ assert.equal(B.foo, 'foo')
+ end)
+
+ it('are overridable by subclasses, without affecting the superclasses', function()
+ B.static.foo = 'chunky bacon'
+ assert.equal(B.foo, 'chunky bacon')
+ assert.equal(A.foo, 'foo')
+ end)
+
+ end)
+
+ describe('methods', function()
+
+ local A, B
+
+ before_each(function()
+ A = class('A')
+ function A.static:foo() return 'foo' end
+
+ B = class('B', A)
+ end)
+
+ it('are available after being initialized', function()
+ assert.equal(A:foo(), 'foo')
+ end)
+
+ it('are available for subclasses', function()
+ assert.equal(B:foo(), 'foo')
+ end)
+
+ it('are overridable by subclasses, without affecting the superclasses', function()
+ function B.static:foo() return 'chunky bacon' end
+ assert.equal(B:foo(), 'chunky bacon')
+ assert.equal(A:foo(), 'foo')
+ end)
+
+ end)
+
+end)
diff --git a/Data/DefaultContent/Libraries/middleclass/spec/default_methods_spec.lua b/Data/DefaultContent/Libraries/middleclass/spec/default_methods_spec.lua
new file mode 100644
index 0000000..91fd9b8
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/spec/default_methods_spec.lua
@@ -0,0 +1,236 @@
+local class = require 'middleclass'
+
+describe('Default methods', function()
+ local Object
+ before_each(function()
+ Object = class('Object')
+ end)
+
+ describe('name', function()
+ it('is correctly set', function()
+ assert.equal(Object.name, 'Object')
+ end)
+ end)
+
+ describe('tostring', function()
+ it('returns "class Object"', function()
+ assert.equal(tostring(Object), 'class Object')
+ end)
+ end)
+
+ describe('()', function()
+ it('returns an object, like Object:new()', function()
+ local obj = Object()
+ assert.is_true(obj:isInstanceOf(Object))
+ end)
+ end)
+
+ describe('subclass', function()
+
+ it('throws an error when used without the :', function()
+ assert.error(function() Object.subclass() end)
+ end)
+
+ it('throws an error when no name is given', function()
+ assert.error( function() Object:subclass() end)
+ end)
+
+ describe('when given a class name', function()
+
+ local SubClass
+
+ before_each(function()
+ SubClass = Object:subclass('SubClass')
+ end)
+
+ it('it returns a class with the correct name', function()
+ assert.equal(SubClass.name, 'SubClass')
+ end)
+
+ it('it returns a class with the correct superclass', function()
+ assert.equal(SubClass.super, Object)
+ end)
+
+ it('it includes the subclass in the list of subclasses', function()
+ assert.is_true(Object.subclasses[SubClass])
+ end)
+
+ end)
+
+ end)
+
+ describe('instance creation', function()
+
+ local SubClass
+
+ before_each(function()
+ SubClass = class('SubClass')
+ function SubClass:initialize() self.mark=true end
+ end)
+
+ describe('allocate', function()
+
+ it('allocates instances properly', function()
+ local instance = SubClass:allocate()
+ assert.equal(instance.class, SubClass)
+ assert.equal(tostring(instance), "instance of " .. tostring(SubClass))
+ end)
+
+ it('throws an error when used without the :', function()
+ assert.error(Object.allocate)
+ end)
+
+ it('does not call the initializer', function()
+ local allocated = SubClass:allocate()
+ assert.is_nil(allocated.mark)
+ end)
+
+ it('can be overriden', function()
+
+ local previousAllocate = SubClass.static.allocate
+
+ function SubClass.static:allocate()
+ local instance = previousAllocate(SubClass)
+ instance.mark = true
+ return instance
+ end
+
+ local allocated = SubClass:allocate()
+ assert.is_true(allocated.mark)
+ end)
+
+ end)
+
+ describe('new', function()
+
+ it('initializes instances properly', function()
+ local instance = SubClass:new()
+ assert.equal(instance.class, SubClass)
+ end)
+
+ it('throws an error when used without the :', function()
+ assert.error(SubClass.new)
+ end)
+
+ it('calls the initializer', function()
+ local initialized = SubClass:new()
+ assert.is_true(initialized.mark)
+ end)
+
+ end)
+
+ describe('isInstanceOf', function()
+
+ describe('primitives', function()
+ local o = Object:new()
+ local primitives = {nil, 1, 'hello', {}, function() end, Object:new()}
+
+ describe('used as classes', function()
+ for _,primitive in pairs(primitives) do
+ local theType = type(primitive)
+ it('object:isInstanceOf(, '.. theType ..') returns false', function()
+ assert.is_falsy(o:isInstanceOf(primitive))
+ end)
+ end
+ end)
+
+ describe('used as instances', function()
+ for _,primitive in pairs(primitives) do
+ local theType = type(primitive)
+ it('Object.isInstanceOf('.. theType ..', Object) returns false without error', function()
+ assert.is_falsy(Object.isInstanceOf(primitive, Object))
+ end)
+ end
+ end)
+
+
+ end)
+
+ describe('An instance', function()
+ local Class1 = class('Class1')
+ local Class2 = class('Class2', Class1)
+ local Class3 = class('Class3', Class2)
+ local UnrelatedClass = class('Unrelated')
+
+ local o1, o2, o3 = Class1:new(), Class2:new(), Class3:new()
+
+ it('isInstanceOf its class', function()
+ assert.is_true(o1:isInstanceOf(Class1))
+ assert.is_true(o2:isInstanceOf(Class2))
+ assert.is_true(o3:isInstanceOf(Class3))
+ end)
+
+ it('is instanceOf its class\' superclasses', function()
+ assert.is_true(o2:isInstanceOf(Class1))
+ assert.is_true(o3:isInstanceOf(Class1))
+ assert.is_true(o3:isInstanceOf(Class2))
+ end)
+
+ it('is not instanceOf its class\' subclasses', function()
+ assert.is_false(o1:isInstanceOf(Class2))
+ assert.is_false(o1:isInstanceOf(Class3))
+ assert.is_false(o2:isInstanceOf(Class3))
+ end)
+
+ it('is not instanceOf an unrelated class', function()
+ assert.is_false(o1:isInstanceOf(UnrelatedClass))
+ assert.is_false(o2:isInstanceOf(UnrelatedClass))
+ assert.is_false(o3:isInstanceOf(UnrelatedClass))
+ end)
+
+ end)
+
+ end)
+
+ end)
+
+ describe('isSubclassOf', function()
+
+ it('returns false for instances', function()
+ assert.is_false(Object:isSubclassOf(Object:new()))
+ end)
+
+ describe('on primitives', function()
+ local primitives = {nil, 1, 'hello', {}, function() end}
+
+ for _,primitive in pairs(primitives) do
+ local theType = type(primitive)
+ it('returns false for ' .. theType, function()
+ assert.is_false(Object:isSubclassOf(primitive))
+ end)
+ end
+
+ end)
+
+ describe('Any class (except Object)', function()
+ local Class1 = class('Class1')
+ local Class2 = class('Class2', Class1)
+ local Class3 = class('Class3', Class2)
+ local UnrelatedClass = class('Unrelated')
+
+ it('is subclassOf its direct superclass', function()
+ assert.is_true(Class2:isSubclassOf(Class1))
+ assert.is_true(Class3:isSubclassOf(Class2))
+ end)
+
+ it('is subclassOf its ancestors', function()
+ assert.is_true(Class3:isSubclassOf(Class1))
+ end)
+
+ it('is a subclassOf its class\' subclasses', function()
+ assert.is_true(Class2:isSubclassOf(Class1))
+ assert.is_true(Class3:isSubclassOf(Class1))
+ assert.is_true(Class3:isSubclassOf(Class2))
+ end)
+
+ it('is not a subclassOf an unrelated class', function()
+ assert.is_false(Class1:isSubclassOf(UnrelatedClass))
+ assert.is_false(Class2:isSubclassOf(UnrelatedClass))
+ assert.is_false(Class3:isSubclassOf(UnrelatedClass))
+ end)
+
+ end)
+ end)
+end)
+
+
diff --git a/Data/DefaultContent/Libraries/middleclass/spec/instances_spec.lua b/Data/DefaultContent/Libraries/middleclass/spec/instances_spec.lua
new file mode 100644
index 0000000..d9ac52c
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/spec/instances_spec.lua
@@ -0,0 +1,65 @@
+local class = require 'middleclass'
+
+describe('An instance', function()
+
+ describe('attributes', function()
+
+ local Person
+
+ before_each(function()
+ Person = class('Person')
+ function Person:initialize(name)
+ self.name = name
+ end
+ end)
+
+ it('are available in the instance after being initialized', function()
+ local bob = Person:new('bob')
+ assert.equal(bob.name, 'bob')
+ end)
+
+ it('are available in the instance after being initialized by a superclass', function()
+ local AgedPerson = class('AgedPerson', Person)
+ function AgedPerson:initialize(name, age)
+ Person.initialize(self, name)
+ self.age = age
+ end
+
+ local pete = AgedPerson:new('pete', 31)
+ assert.equal(pete.name, 'pete')
+ assert.equal(pete.age, 31)
+ end)
+
+ end)
+
+ describe('methods', function()
+
+ local A, B, a, b
+
+ before_each(function()
+ A = class('A')
+ function A:overridden() return 'foo' end
+ function A:regular() return 'regular' end
+
+ B = class('B', A)
+ function B:overridden() return 'bar' end
+
+ a = A:new()
+ b = B:new()
+ end)
+
+ it('are available for any instance', function()
+ assert.equal(a:overridden(), 'foo')
+ end)
+
+ it('are inheritable', function()
+ assert.equal(b:regular(), 'regular')
+ end)
+
+ it('are overridable', function()
+ assert.equal(b:overridden(), 'bar')
+ end)
+
+ end)
+
+end)
diff --git a/Data/DefaultContent/Libraries/middleclass/spec/metamethods_lua_5_2.lua b/Data/DefaultContent/Libraries/middleclass/spec/metamethods_lua_5_2.lua
new file mode 100644
index 0000000..2ea6c9b
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/spec/metamethods_lua_5_2.lua
@@ -0,0 +1,85 @@
+local class = require 'middleclass'
+
+local it = require('busted').it
+local describe = require('busted').describe
+local before_each = require('busted').before_each
+local assert = require('busted').assert
+
+describe('Lua 5.2 Metamethods', function()
+ local Vector, v
+ before_each(function()
+ Vector= class('Vector')
+ function Vector.initialize(a,x,y,z) a.x, a.y, a.z = x,y,z end
+ function Vector.__eq(a,b) return a.x==b.x and a.y==b.y and a.z==b.z end
+
+ function Vector.__len(a) return 3 end
+ function Vector.__pairs(a)
+ local t = {x=a.x,y=a.y,z=a.z}
+ return coroutine.wrap(function()
+ for k,val in pairs(t) do
+ coroutine.yield(k,val)
+ end
+ end)
+ end
+ function Vector.__ipairs(a)
+ local t = {a.x,a.y,a.z}
+ return coroutine.wrap(function()
+ for k,val in ipairs(t) do
+ coroutine.yield(k,val)
+ end
+ end)
+ end
+
+ v = Vector:new(1,2,3)
+ end)
+
+ it('implements __len', function()
+ assert.equal(#v, 3)
+ end)
+
+ it('implements __pairs',function()
+ local output = {}
+ for k,val in pairs(v) do
+ output[k] = val
+ end
+ assert.are.same(output,{x=1,y=2,z=3})
+ end)
+
+ it('implements __ipairs',function()
+ local output = {}
+ for _,i in ipairs(v) do
+ output[#output+1] = i
+ end
+ assert.are.same(output,{1,2,3})
+ end)
+
+ describe('Inherited Metamethods', function()
+ local Vector2, v2
+ before_each(function()
+ Vector2= class('Vector2', Vector)
+ function Vector2:initialize(x,y,z) Vector.initialize(self,x,y,z) end
+
+ v2 = Vector2:new(1,2,3)
+ end)
+
+ it('implements __len', function()
+ assert.equal(#v2, 3)
+ end)
+
+ it('implements __pairs',function()
+ local output = {}
+ for k,val in pairs(v2) do
+ output[k] = val
+ end
+ assert.are.same(output,{x=1,y=2,z=3})
+ end)
+
+ it('implements __ipairs',function()
+ local output = {}
+ for _,i in ipairs(v2) do
+ output[#output+1] = i
+ end
+ assert.are.same(output,{1,2,3})
+ end)
+ end)
+end)
diff --git a/Data/DefaultContent/Libraries/middleclass/spec/metamethods_lua_5_3.lua b/Data/DefaultContent/Libraries/middleclass/spec/metamethods_lua_5_3.lua
new file mode 100644
index 0000000..e74f6d7
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/spec/metamethods_lua_5_3.lua
@@ -0,0 +1,106 @@
+local class = require 'middleclass'
+
+local it = require('busted').it
+local describe = require('busted').describe
+local before_each = require('busted').before_each
+local assert = require('busted').assert
+
+describe('Lua 5.3 Metamethods', function()
+ local Vector, v, last_gc
+ before_each(function()
+ Vector= class('Vector')
+ function Vector.initialize(a,x,y,z) a.x, a.y, a.z = x,y,z end
+ function Vector.__eq(a,b) return a.x==b.x and a.y==b.y and a.z==b.z end
+ function Vector.__pairs(a)
+ local t = {x=a.x,y=a.y,z=a.z}
+ return coroutine.wrap(function()
+ for k,val in pairs(t) do
+ coroutine.yield(k,val)
+ end
+ end)
+ end
+ function Vector.__len(a) return 3 end
+
+ function Vector.__gc(a) last_gc = {a.class.name, a.x, a.y, a.z} end
+ function Vector.__band(a,n) return a.class:new(a.x & n, a.y & n, a.z & n) end
+ function Vector.__bor(a,n) return a.class:new(a.x | n, a.y | n, a.z | n) end
+ function Vector.__bxor(a,n) return a.class:new(a.x ~ n, a.y ~ n, a.z ~ n) end
+ function Vector.__shl(a,n) return a.class:new(a.x << n, a.y << n, a.z << n) end
+ function Vector.__shr(a,n) return a.class:new(a.x >> n, a.y >> n, a.z >> n) end
+ function Vector.__bnot(a) return a.class:new(~a.x, ~a.y, ~a.z) end
+
+ v = Vector:new(1,2,3)
+ end)
+
+ it('implements __gc', function()
+ collectgarbage()
+ v = nil
+ collectgarbage()
+ assert.are.same(last_gc, {"Vector",1,2,3})
+ end)
+
+ it('implements __band', function()
+ assert.equal(v & 1, Vector(1,0,1))
+ end)
+
+ it('implements __bor', function()
+ assert.equal(v | 0, Vector(1,2,3))
+ end)
+
+ it('implements __bxor', function()
+ assert.equal(v | 1, Vector(1,3,3))
+ end)
+
+ it('implements __shl', function()
+ assert.equal(v << 1, Vector(2,4,6))
+ end)
+
+ it('implements __shr', function()
+ assert.equal(v >> 1, Vector(0,1,1))
+ end)
+
+ it('implements __bnot', function()
+ assert.equal(~v, Vector(-2,-3,-4))
+ end)
+
+ describe('Inherited Metamethods', function()
+ local Vector2, v2
+ before_each(function()
+ Vector2= class('Vector2', Vector)
+ function Vector2:initialize(x,y,z) Vector.initialize(self,x,y,z) end
+
+ v2 = Vector2:new(1,2,3)
+ end)
+
+ it('implements __gc', function()
+ collectgarbage()
+ v2 = nil
+ collectgarbage()
+ assert.are.same(last_gc, {"Vector2",1,2,3})
+ end)
+
+ it('implements __band', function()
+ assert.equal(v2 & 1, Vector2(1,0,1))
+ end)
+
+ it('implements __bor', function()
+ assert.equal(v2 | 0, Vector2(1,2,3))
+ end)
+
+ it('implements __bxor', function()
+ assert.equal(v2 | 1, Vector2(1,3,3))
+ end)
+
+ it('implements __shl', function()
+ assert.equal(v2 << 1, Vector2(2,4,6))
+ end)
+
+ it('implements __shr', function()
+ assert.equal(v2 >> 1, Vector2(0,1,1))
+ end)
+
+ it('implements __bnot', function()
+ assert.equal(~v2, Vector2(-2,-3,-4))
+ end)
+ end)
+end)
diff --git a/Data/DefaultContent/Libraries/middleclass/spec/metamethods_spec.lua b/Data/DefaultContent/Libraries/middleclass/spec/metamethods_spec.lua
new file mode 100644
index 0000000..73bf883
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/spec/metamethods_spec.lua
@@ -0,0 +1,317 @@
+local class = require 'middleclass'
+
+local function is_lua_5_2_compatible()
+ return type(rawlen) == 'function'
+end
+
+local function is_lua_5_3_compatible()
+ return type(string.unpack) == 'function'
+end
+
+if is_lua_5_2_compatible() then
+ require 'spec/metamethods_lua_5_2'
+end
+
+if is_lua_5_3_compatible() then
+ require 'spec.metamethods_lua_5_3'
+end
+
+describe('Metamethods', function()
+ describe('Custom Metamethods', function()
+ local Vector, v, w
+ before_each(function()
+ Vector= class('Vector')
+ function Vector.initialize(a,x,y,z) a.x, a.y, a.z = x,y,z end
+ function Vector.__tostring(a) return a.class.name .. '[' .. a.x .. ',' .. a.y .. ',' .. a.z .. ']' end
+ function Vector.__eq(a,b) return a.x==b.x and a.y==b.y and a.z==b.z end
+ function Vector.__lt(a,b) return a() < b() end
+ function Vector.__le(a,b) return a() <= b() end
+ function Vector.__add(a,b) return a.class:new(a.x+b.x, a.y+b.y ,a.z+b.z) end
+ function Vector.__sub(a,b) return a.class:new(a.x-b.x, a.y-b.y, a.z-b.z) end
+ function Vector.__div(a,s) return a.class:new(a.x/s, a.y/s, a.z/s) end
+ function Vector.__unm(a) return a.class:new(-a.x, -a.y, -a.z) end
+ function Vector.__concat(a,b) return a.x*b.x+a.y*b.y+a.z*b.z end
+ function Vector.__call(a) return math.sqrt(a.x*a.x+a.y*a.y+a.z*a.z) end
+ function Vector.__pow(a,b)
+ return a.class:new(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x)
+ end
+ function Vector.__mul(a,b)
+ if type(b)=="number" then return a.class:new(a.x*b, a.y*b, a.z*b) end
+ if type(a)=="number" then return b.class:new(a*b.x, a*b.y, a*b.z) end
+ end
+ Vector.__metatable = "metatable of a vector"
+ Vector.__mode = "k"
+
+ v = Vector:new(1,2,3)
+ w = Vector:new(2,4,6)
+ end)
+
+ it('implements __tostring', function()
+ assert.equal(tostring(v), "Vector[1,2,3]")
+ end)
+
+ it('implements __eq', function()
+ assert.equal(v, v)
+ end)
+
+ it('implements __lt', function()
+ assert.is_true(v < w)
+ end)
+
+ it('implements __le', function()
+ assert.is_true(v <= w)
+ end)
+
+ it('implements __add', function()
+ assert.equal(v+w, Vector(3,6,9))
+ end)
+
+ it('implements __sub', function()
+ assert.equal(w-v, Vector(1,2,3))
+ end)
+
+ it('implements __div', function()
+ assert.equal(w/2, Vector(1,2,3))
+ end)
+
+ it('implements __concat', function()
+ assert.equal(v..w, 28)
+ end)
+
+ it('implements __call', function()
+ assert.equal(v(), math.sqrt(14))
+ end)
+
+ it('implements __pow', function()
+ assert.equal(v^w, Vector(0,0,0))
+ end)
+
+ it('implements __mul', function()
+ assert.equal(4*v, Vector(4,8,12))
+ end)
+
+ it('implements __metatable', function()
+ assert.equal("metatable of a vector", getmetatable(v))
+ end)
+
+ it('implements __mode', function()
+ v[{}] = true
+ collectgarbage()
+ for k in pairs(v) do assert.not_table(k) end
+ end)
+
+ --[[
+ it('implements __index', function()
+ assert.equal(b[1], 3)
+ end)
+ --]]
+
+ describe('Inherited Metamethods', function()
+ local Vector2, v2, w2
+ before_each(function()
+ Vector2= class('Vector2', Vector)
+ function Vector2:initialize(x,y,z) Vector.initialize(self,x,y,z) end
+
+ v2 = Vector2:new(1,2,3)
+ w2 = Vector2:new(2,4,6)
+ end)
+
+ it('implements __tostring', function()
+ assert.equal(tostring(v2), "Vector2[1,2,3]")
+ end)
+
+ it('implements __eq', function()
+ assert.equal(v2, v2)
+ end)
+
+ it('implements __lt', function()
+ assert.is_true(v2 < w2)
+ end)
+
+ it('implements __le', function()
+ assert.is_true(v2 <= w2)
+ end)
+
+ it('implements __add', function()
+ assert.equal(v2+w2, Vector2(3,6,9))
+ end)
+
+ it('implements __sub', function()
+ assert.equal(w2-v2, Vector2(1,2,3))
+ end)
+
+ it('implements __div', function()
+ assert.equal(w2/2, Vector2(1,2,3))
+ end)
+
+ it('implements __concat', function()
+ assert.equal(v2..w2, 28)
+ end)
+
+ it('implements __call', function()
+ assert.equal(v2(), math.sqrt(14))
+ end)
+
+ it('implements __pow', function()
+ assert.equal(v2^w2, Vector2(0,0,0))
+ end)
+
+ it('implements __mul', function()
+ assert.equal(4*v2, Vector2(4,8,12))
+ end)
+
+ it('implements __metatable', function()
+ assert.equal("metatable of a vector", getmetatable(v2))
+ end)
+
+ it('implements __mode', function()
+ v2[{}] = true
+ collectgarbage()
+ for k in pairs(v2) do assert.not_table(k) end
+ end)
+
+ it('allows inheriting further', function()
+ local Vector3 = class('Vector3', Vector2)
+ local v3 = Vector3(1,2,3)
+ local w3 = Vector3(3,4,5)
+ assert.equal(v3+w3, Vector3(4,6,8))
+ end)
+
+ describe('Updates', function()
+ it('overrides __add', function()
+ Vector2.__add = function(a, b) return Vector.__add(a, b)/2 end
+ assert.equal(v2+w2, Vector2(1.5,3,4.5))
+ end)
+
+ it('updates __add', function()
+ Vector.__add = Vector.__sub
+ assert.equal(v2+w2, Vector2(-1,-2,-3))
+ end)
+
+ it('does not update __add after overriding', function()
+ Vector2.__add = function(a, b) return Vector.__add(a, b)/2 end
+ Vector.__add = Vector.__sub
+ assert.equal(v2+w2, Vector2(-0.5,-1,-1.5))
+ end)
+
+ it('reverts __add override', function()
+ Vector2.__add = function(a, b) return Vector.__add(a, b)/2 end
+ Vector2.__add = nil
+ assert.equal(v2+w2, Vector2(3,6,9))
+ end)
+ end)
+ end)
+ end)
+
+ describe('Custom __index and __newindex', function()
+ describe('Tables', function()
+ local Proxy, fallback, p
+ before_each(function()
+ Proxy = class('Proxy')
+ fallback = {foo = 'bar', common = 'fallback'}
+ Proxy.__index = fallback
+ Proxy.__newindex = fallback
+ Proxy.common = 'class'
+ p = Proxy()
+ end)
+
+ it('uses __index', function()
+ assert.equal(p.foo, 'bar')
+ end)
+
+ it('does not use __index when field exists in class', function()
+ assert.equal(p.common, 'class')
+ end)
+
+ it('uses __newindex', function()
+ p.key = 'value'
+ assert.equal(fallback.key, 'value')
+ end)
+
+ it('uses __newindex when field exists in class', function()
+ p.common = 'value'
+ assert.equal(p.common, 'class')
+ assert.equal(Proxy.common, 'class')
+ assert.equal(fallback.common, 'value')
+ end)
+ end)
+
+ describe('Functions', function()
+ local Namespace, Rectangle, r
+ before_each(function()
+ Namespace = class('Namespace')
+ function Namespace:__index(name)
+ local getter = self.class[name.."Getter"]
+ if getter then return getter(self) end
+ end
+ function Namespace:__newindex(name, value)
+ local setter = self.class[name.."Setter"]
+ if setter then setter(self, value) else rawset(self, name, value) end
+ end
+ Rectangle = class('Rectangle', Namespace)
+ function Rectangle:initialize(x, y, scale)
+ self._scale, self.x, self.y = 1, x, y
+ self.scale = scale
+ end
+ function Rectangle:scaleGetter() return self._scale end
+ function Rectangle:scaleSetter(v)
+ self.x = self.x*v/self._scale
+ self.y = self.y*v/self._scale
+ self._scale = v
+ end
+ function Rectangle:areaGetter() return self.x * self.y end
+ r = Rectangle(3, 4, 2)
+ end)
+
+ it('uses setter', function()
+ assert.equal(r.x, 6)
+ assert.equal(r.y, 8)
+ r.scale = 3
+ assert.equal(r.x, 9)
+ assert.equal(r.y, 12)
+ end)
+
+ it('uses getters', function()
+ assert.equal(r.scale, 2)
+ assert.equal(r.area, 48)
+ end)
+
+ it('updates inherited __index', function()
+ function Namespace.__index() return 42 end
+ assert.equal(r.area, 42)
+ function Rectangle.__index() return 24 end
+ assert.equal(r.area, 24)
+ function Namespace.__index() return 96 end
+ assert.equal(r.area, 24)
+ Rectangle.__index = nil
+ assert.equal(r.area, 96)
+ end)
+ end)
+ end)
+
+ describe('Default Metamethods', function()
+
+ local Peter, peter
+
+ before_each(function()
+ Peter = class('Peter')
+ peter = Peter()
+ end)
+
+ describe('A Class', function()
+ it('has a call metamethod properly set', function()
+ assert.is_true(peter:isInstanceOf(Peter))
+ end)
+ it('has a tostring metamethod properly set', function()
+ assert.equal(tostring(Peter), 'class Peter')
+ end)
+ end)
+
+ describe('An instance', function()
+ it('has a tostring metamethod, returning a different result from Object.__tostring', function()
+ assert.equal(tostring(peter), 'instance of class Peter')
+ end)
+ end)
+ end)
+
+end)
diff --git a/Data/DefaultContent/Libraries/middleclass/spec/mixins_spec.lua b/Data/DefaultContent/Libraries/middleclass/spec/mixins_spec.lua
new file mode 100644
index 0000000..ef592a1
--- /dev/null
+++ b/Data/DefaultContent/Libraries/middleclass/spec/mixins_spec.lua
@@ -0,0 +1,53 @@
+local class = require 'middleclass'
+
+describe('A Mixin', function()
+
+ local Mixin1, Mixin2, Class1, Class2
+
+ before_each(function()
+ Mixin1, Mixin2 = {},{}
+
+ function Mixin1:included(theClass) theClass.includesMixin1 = true end
+ function Mixin1:foo() return 'foo' end
+ function Mixin1:bar() return 'bar' end
+ Mixin1.static = {}
+ Mixin1.static.bazzz = function() return 'bazzz' end
+
+
+ function Mixin2:baz() return 'baz' end
+
+ Class1 = class('Class1'):include(Mixin1, Mixin2)
+ function Class1:foo() return 'foo1' end
+
+ Class2 = class('Class2', Class1)
+ function Class2:bar2() return 'bar2' end
+ end)
+
+ it('invokes the "included" method when included', function()
+ assert.is_true(Class1.includesMixin1)
+ end)
+
+ it('has all its functions (except "included") copied to its target class', function()
+ assert.equal(Class1:bar(), 'bar')
+ assert.is_nil(Class1.included)
+ end)
+
+ it('makes its functions available to subclasses', function()
+ assert.equal(Class2:baz(), 'baz')
+ end)
+
+ it('allows overriding of methods in the same class', function()
+ assert.equal(Class2:foo(), 'foo1')
+ end)
+
+ it('allows overriding of methods on subclasses', function()
+ assert.equal(Class2:bar2(), 'bar2')
+ end)
+
+ it('makes new static methods available in classes', function()
+ assert.equal(Class1:bazzz(), 'bazzz')
+ assert.equal(Class2:bazzz(), 'bazzz')
+ end)
+
+end)
+
diff --git a/Data/DefaultContent/Libraries/socket/README.txt b/Data/DefaultContent/Libraries/socket/README.txt
new file mode 100644
index 0000000..7f61184
--- /dev/null
+++ b/Data/DefaultContent/Libraries/socket/README.txt
@@ -0,0 +1 @@
+https://github.com/diegonehab/luasocket \ No newline at end of file
diff --git a/Data/DefaultContent/Libraries/socket/core.dll b/Data/DefaultContent/Libraries/socket/core.dll
new file mode 100644
index 0000000..9febf20
--- /dev/null
+++ b/Data/DefaultContent/Libraries/socket/core.dll
Binary files differ