From d42244ba35d1bd3b4efbaef4fef3acd80bc39c91 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Mon, 16 Dec 2013 16:35:06 +0100 Subject: [PATCH 01/50] [Gamestate] Undo last commit. Add all 0.9 callbacks. --- gamestate.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gamestate.lua b/gamestate.lua index 9a9fc09..46f6ff8 100644 --- a/gamestate.lua +++ b/gamestate.lua @@ -65,9 +65,11 @@ function GS.current() end local all_callbacks = { - 'update', 'draw', 'focus', 'keypressed', 'keyreleased', - 'mousepressed', 'mousereleased', 'joystickpressed', - 'joystickreleased', 'textinput', 'quit', 'textinput' + 'draw', 'errhand', 'focus', 'keypressed', 'keyreleased', 'mousefocus', + 'mousepressed', 'mousereleased', 'quit', 'resize', 'textinput', + 'threaderror', 'update', 'visible', 'gamepadaxis', 'gamepadpressed', + 'joystickadded', 'joystickaxis', 'joystickhat', 'joystickpressed', + 'joystickreleased', 'joystickremoved' } function GS.registerEvents(callbacks) From 21d87e51196ccaeb9c52544722a2d43aa6412000 Mon Sep 17 00:00:00 2001 From: Kevin Bradshaw Date: Sat, 8 Feb 2014 16:49:34 +0100 Subject: [PATCH 02/50] Added gamepadreleased to all_callbacks --- gamestate.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gamestate.lua b/gamestate.lua index 46f6ff8..854100c 100644 --- a/gamestate.lua +++ b/gamestate.lua @@ -68,8 +68,8 @@ local all_callbacks = { 'draw', 'errhand', 'focus', 'keypressed', 'keyreleased', 'mousefocus', 'mousepressed', 'mousereleased', 'quit', 'resize', 'textinput', 'threaderror', 'update', 'visible', 'gamepadaxis', 'gamepadpressed', - 'joystickadded', 'joystickaxis', 'joystickhat', 'joystickpressed', - 'joystickreleased', 'joystickremoved' + 'gamepadreleased', 'joystickadded', 'joystickaxis', 'joystickhat', + 'joystickpressed', 'joystickreleased', 'joystickremoved' } function GS.registerEvents(callbacks) From e9e20195173bd9e147f17599b3189a8778c32bf0 Mon Sep 17 00:00:00 2001 From: headchant Date: Thu, 13 Feb 2014 22:36:45 +0100 Subject: [PATCH 03/50] Update signal.lua register does not return function handle --- signal.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signal.lua b/signal.lua index 7cb246e..52b4d63 100644 --- a/signal.lua +++ b/signal.lua @@ -83,7 +83,7 @@ local default = new() return setmetatable({ new = new, - register = function(...) default:register(...) end, + register = function(...) return default:register(...) end, emit = function(...) default:emit(...) end, remove = function(...) default:remove(...) end, clear = function(...) default:clear(...) end, From 157ec82cd58d3d5c91c18c84485a50294bcfcc72 Mon Sep 17 00:00:00 2001 From: Mifuyne Date: Mon, 17 Feb 2014 12:32:42 -0500 Subject: [PATCH 04/50] ln 179 & 181: second self.y changed to self.x For vector:angleTo() --- vector.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector.lua b/vector.lua index 0762ce5..0d19181 100644 --- a/vector.lua +++ b/vector.lua @@ -176,9 +176,9 @@ end function vector:angleTo(other) if other then - return atan2(self.y, self.y) - atan2(other.y, other.x) + return atan2(self.y, self.x) - atan2(other.y, other.x) end - return atan2(self.y, self.y) + return atan2(self.y, self.x) end function vector:trimmed(maxLen) From 65cef0e3dc079cc204b75487ecc879047df80530 Mon Sep 17 00:00:00 2001 From: stfan Date: Mon, 3 Mar 2014 20:28:40 +0100 Subject: [PATCH 05/50] Update vector.lua Changed vector:trim_inplace so it actually trims the vector when it is longer than the maxLen --- vector.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector.lua b/vector.lua index 0762ce5..556981d 100644 --- a/vector.lua +++ b/vector.lua @@ -169,7 +169,7 @@ end -- ref.: http://blog.signalsondisplay.com/?p=336 function vector:trim_inplace(maxLen) local s = maxLen * maxLen / self:len2() - s = s < 1 and 1 or math.sqrt(s) + s = (s > 1 and 1) or math.sqrt(s) self.x, self.y = self.x * s, self.y * s return self end From e10fa66e60c5984a8d92801163d23811b7ac509f Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Mon, 3 Mar 2014 23:00:23 +0100 Subject: [PATCH 06/50] Fix vector-light.trim() (see 2abe666ce9) --- vector-light.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector-light.lua b/vector-light.lua index c352ebc..962c2c4 100644 --- a/vector-light.lua +++ b/vector-light.lua @@ -116,7 +116,7 @@ end -- ref.: http://blog.signalsondisplay.com/?p=336 local function trim(maxLen, x, y) local s = maxLen * maxLen / len2(x, y) - s = s < 1 and 1 or math.sqrt(s) + s = s > 1 and 1 or math.sqrt(s) return x * s, y * s end From ed2b38952ab1b226a5d2b1cc8adf82793baa7b9b Mon Sep 17 00:00:00 2001 From: Jesse van Herk Date: Tue, 1 Jul 2014 11:38:07 -0600 Subject: [PATCH 07/50] Add assertions for : calls, avoid bad recursion --- gamestate.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gamestate.lua b/gamestate.lua index 854100c..0b3d6ec 100644 --- a/gamestate.lua +++ b/gamestate.lua @@ -36,6 +36,7 @@ function GS.new(t) return t or {} end -- constructor - deprecated! function GS.switch(to, ...) assert(to, "Missing argument: Gamestate to switch to") + assert( to ~= GS, "Can't call switch with colon operator" ) local pre = stack[#stack] ;(pre.leave or __NULL__)(pre) ;(to.init or __NULL__)(to) @@ -46,6 +47,7 @@ end function GS.push(to, ...) assert(to, "Missing argument: Gamestate to switch to") + assert( to ~= GS, "Can't call push with colon operator" ) local pre = stack[#stack] ;(to.init or __NULL__)(to) to.init = nil From db9a576aa7caaa6ac3d273785b84568b44a34295 Mon Sep 17 00:00:00 2001 From: Jesse van Herk Date: Tue, 1 Jul 2014 11:42:42 -0600 Subject: [PATCH 08/50] cleanup indenting to match origin style --- gamestate.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gamestate.lua b/gamestate.lua index 0b3d6ec..b097555 100644 --- a/gamestate.lua +++ b/gamestate.lua @@ -36,7 +36,7 @@ function GS.new(t) return t or {} end -- constructor - deprecated! function GS.switch(to, ...) assert(to, "Missing argument: Gamestate to switch to") - assert( to ~= GS, "Can't call switch with colon operator" ) + assert(to ~= GS, "Can't call switch with colon operator") local pre = stack[#stack] ;(pre.leave or __NULL__)(pre) ;(to.init or __NULL__)(to) @@ -47,7 +47,7 @@ end function GS.push(to, ...) assert(to, "Missing argument: Gamestate to switch to") - assert( to ~= GS, "Can't call push with colon operator" ) + assert(to ~= GS, "Can't call push with colon operator") local pre = stack[#stack] ;(to.init or __NULL__)(to) to.init = nil From bd10ec4caff5675c04c17ec0f7714cb5c3ff44ec Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Fri, 22 Aug 2014 13:42:17 +0200 Subject: [PATCH 09/50] (Fix #34) Add callback for returning from push()/pop() state:resume() will be called on the state that issued a GS.push() after the pushed state is popped from the stack. --- gamestate.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gamestate.lua b/gamestate.lua index 854100c..f424fad 100644 --- a/gamestate.lua +++ b/gamestate.lua @@ -57,7 +57,8 @@ function GS.pop() assert(#stack > 1, "No more states to pop!") local pre = stack[#stack] stack[#stack] = nil - return (pre.leave or __NULL__)(pre) + ;(pre.leave or __NULL__)(pre) + return (stack[#stack].resume or __NULL__)(pre) end function GS.current() From e8af2a6ec2ceb8e0729ddf2660c565d0794b7d20 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Fri, 22 Aug 2014 13:47:55 +0200 Subject: [PATCH 10/50] (Fix #33, #35) A more flexible definition of isvector(v) Now returns true if `v' is a table and both `v.x' and `v.y' are numbers. --- vector.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector.lua b/vector.lua index 24c471a..9abdf34 100644 --- a/vector.lua +++ b/vector.lua @@ -36,7 +36,7 @@ end local zero = new(0,0) local function isvector(v) - return getmetatable(v) == vector + return type(v) == 'table' and type(v.x) == 'number' and type(v.y) == 'number' end function vector:clone() From 4f53485fb76190727af3f583f684740dadf875d7 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Fri, 22 Aug 2014 13:51:25 +0200 Subject: [PATCH 11/50] (Fix #37) Copy metatable in class:clone() --- class.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/class.lua b/class.lua index d578ae4..20319f0 100644 --- a/class.lua +++ b/class.lua @@ -51,7 +51,7 @@ end -- returns a deep copy of `other' local function clone(other) - return include({}, other) + return setmetatable(include({}, other), getmetatable(other)) end local function new(class) From af8f19a48ee940864f3454bdb5451a48a35fd089 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Fri, 22 Aug 2014 13:57:02 +0200 Subject: [PATCH 12/50] Forward arguments from GS.pop() to state:resume() --- gamestate.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gamestate.lua b/gamestate.lua index f424fad..a73d319 100644 --- a/gamestate.lua +++ b/gamestate.lua @@ -53,12 +53,12 @@ function GS.push(to, ...) return (to.enter or __NULL__)(to, pre, ...) end -function GS.pop() +function GS.pop(...) assert(#stack > 1, "No more states to pop!") local pre = stack[#stack] stack[#stack] = nil ;(pre.leave or __NULL__)(pre) - return (stack[#stack].resume or __NULL__)(pre) + return (stack[#stack].resume or __NULL__)(pre, ...) end function GS.current() From 95f07233b9e1b26aeccf34e9da7cf6823dc5630b Mon Sep 17 00:00:00 2001 From: headchant Date: Thu, 13 Nov 2014 16:00:20 +0100 Subject: [PATCH 13/50] Punctation change Unifies instance and default timer object access of functions to '.' for example: timer.clear(). For instances you had to use ':' until now. --- timer.lua | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/timer.lua b/timer.lua index 7cb8ff6..915818a 100644 --- a/timer.lua +++ b/timer.lua @@ -30,7 +30,21 @@ Timer.__index = Timer local function _nothing_() end local function new() - return setmetatable({functions = {}, tween = Timer.tween}, Timer) + local timer = setmetatable({functions = {}, tween = Timer.tween}, Timer) + return setmetatable({ + new = new, + update = function(...) return timer:update(...) end, + do_for = function(...) return timer:do_for(...) end, + add = function(...) return timer:add(...) end, + addPeriodic = function(...) return timer:addPeriodic(...) end, + cancel = function(...) return timer:cancel(...) end, + clear = function(...) return timer:clear(...) end, + tween = setmetatable({}, { + __index = Timer.tween, + __newindex = function(_,k,v) Timer.tween[k] = v end, + __call = function(t,...) return timer:tween(...) end, + }) + }, {__call = new}) end function Timer:update(dt) @@ -174,17 +188,4 @@ end}) local default = new() -- the module -return setmetatable({ - new = new, - update = function(...) return default:update(...) end, - do_for = function(...) return default:do_for(...) end, - add = function(...) return default:add(...) end, - addPeriodic = function(...) return default:addPeriodic(...) end, - cancel = function(...) return default:cancel(...) end, - clear = function(...) return default:clear(...) end, - tween = setmetatable({}, { - __index = Timer.tween, - __newindex = function(_,k,v) Timer.tween[k] = v end, - __call = function(t,...) return default:tween(...) end, - }) -}, {__call = new}) +return default From a9061c68f06ab118b4e830737cc5f2fe1f9f47f1 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sun, 23 Nov 2014 18:00:50 +0100 Subject: [PATCH 14/50] [timer] Place new() at the end of the module. --- timer.lua | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/timer.lua b/timer.lua index 915818a..a8b3e34 100644 --- a/timer.lua +++ b/timer.lua @@ -29,24 +29,6 @@ Timer.__index = Timer local function _nothing_() end -local function new() - local timer = setmetatable({functions = {}, tween = Timer.tween}, Timer) - return setmetatable({ - new = new, - update = function(...) return timer:update(...) end, - do_for = function(...) return timer:do_for(...) end, - add = function(...) return timer:add(...) end, - addPeriodic = function(...) return timer:addPeriodic(...) end, - cancel = function(...) return timer:cancel(...) end, - clear = function(...) return timer:clear(...) end, - tween = setmetatable({}, { - __index = Timer.tween, - __newindex = function(_,k,v) Timer.tween[k] = v end, - __call = function(t,...) return timer:tween(...) end, - }) - }, {__call = new}) -end - function Timer:update(dt) local to_remove = {} for handle, delay in pairs(self.functions) do @@ -184,8 +166,23 @@ __index = function(tweens, key) or error('Unknown interpolation method: ' .. key) end}) --- default timer -local default = new() - -- the module -return default +local function new() + local timer = setmetatable({functions = {}, tween = Timer.tween}, Timer) + return setmetatable({ + new = new, + update = function(...) return timer:update(...) end, + do_for = function(...) return timer:do_for(...) end, + add = function(...) return timer:add(...) end, + addPeriodic = function(...) return timer:addPeriodic(...) end, + cancel = function(...) return timer:cancel(...) end, + clear = function(...) return timer:clear(...) end, + tween = setmetatable({}, { + __index = Timer.tween, + __newindex = function(_,k,v) Timer.tween[k] = v end, + __call = function(t,...) return timer:tween(...) end, + }) + }, {__call = new}) +end + +return new() From 537ca76264ecefb1a3f8c1646ecafdc4d2c77fd9 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sun, 23 Nov 2014 18:02:38 +0100 Subject: [PATCH 15/50] [signal] Use . instead of : in registry instances. Mirrors behavior of the timer.lua --- signal.lua | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/signal.lua b/signal.lua index 52b4d63..8d039a8 100644 --- a/signal.lua +++ b/signal.lua @@ -76,18 +76,20 @@ function Registry:clear_pattern(p) end end +-- the module local function new() - return setmetatable({}, Registry) -end -local default = new() + local registry = setmetatable({}, Registry) -return setmetatable({ - new = new, - register = function(...) return default:register(...) end, - emit = function(...) default:emit(...) end, - remove = function(...) default:remove(...) end, - clear = function(...) default:clear(...) end, - emit_pattern = function(...) default:emit_pattern(...) end, - remove_pattern = function(...) default:remove_pattern(...) end, - clear_pattern = function(...) default:clear_pattern(...) end, -}, {__call = new}) + return setmetatable({ + new = new, + register = function(...) return registry:register(...) end, + emit = function(...) registry:emit(...) end, + remove = function(...) registry:remove(...) end, + clear = function(...) registry:clear(...) end, + emit_pattern = function(...) registry:emit_pattern(...) end, + remove_pattern = function(...) registry:remove_pattern(...) end, + clear_pattern = function(...) registry:clear_pattern(...) end, + }, {__call = new}) +end + +return new() From bdd9ad5c049d34d75e4deabc17392faef4acb58f Mon Sep 17 00:00:00 2001 From: xpol Date: Mon, 15 Dec 2014 15:06:05 +0800 Subject: [PATCH 16/50] Fixes wrong arg #1 for resume(). --- gamestate.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gamestate.lua b/gamestate.lua index c440180..4d8e9fa 100644 --- a/gamestate.lua +++ b/gamestate.lua @@ -57,10 +57,10 @@ end function GS.pop(...) assert(#stack > 1, "No more states to pop!") - local pre = stack[#stack] + local pre, to = stack[#stack], stack[#stack-1] stack[#stack] = nil ;(pre.leave or __NULL__)(pre) - return (stack[#stack].resume or __NULL__)(pre, ...) + return (to.resume or __NULL__)(to, ...) end function GS.current() From b18c399defaa52ae61499ad56ced8c311b82c191 Mon Sep 17 00:00:00 2001 From: vrld Date: Tue, 16 Dec 2014 18:07:32 +0100 Subject: [PATCH 17/50] Add missing argument to gs:resume(pre, ...) --- gamestate.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gamestate.lua b/gamestate.lua index 4d8e9fa..99f6c22 100644 --- a/gamestate.lua +++ b/gamestate.lua @@ -60,7 +60,7 @@ function GS.pop(...) local pre, to = stack[#stack], stack[#stack-1] stack[#stack] = nil ;(pre.leave or __NULL__)(pre) - return (to.resume or __NULL__)(to, ...) + return (to.resume or __NULL__)(to, pre, ...) end function GS.current() From f984cc87e6dfa58d751be4bd55f219c9fc1b53a5 Mon Sep 17 00:00:00 2001 From: Harris Munir Date: Wed, 18 Mar 2015 20:08:38 -0500 Subject: [PATCH 18/50] add mousemoved callback to gamestate callbacks (added in LOVE 0.9.2) --- gamestate.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gamestate.lua b/gamestate.lua index 99f6c22..8a299ca 100644 --- a/gamestate.lua +++ b/gamestate.lua @@ -69,10 +69,10 @@ end local all_callbacks = { 'draw', 'errhand', 'focus', 'keypressed', 'keyreleased', 'mousefocus', - 'mousepressed', 'mousereleased', 'quit', 'resize', 'textinput', - 'threaderror', 'update', 'visible', 'gamepadaxis', 'gamepadpressed', - 'gamepadreleased', 'joystickadded', 'joystickaxis', 'joystickhat', - 'joystickpressed', 'joystickreleased', 'joystickremoved' + 'mousemoved', 'mousepressed', 'mousereleased', 'quit', 'resize', + 'textinput', 'threaderror', 'update', 'visible', 'gamepadaxis', + 'gamepadpressed', 'gamepadreleased', 'joystickadded', 'joystickaxis', + 'joystickhat', 'joystickpressed', 'joystickreleased', 'joystickremoved' } function GS.registerEvents(callbacks) From dbf60e3dc5bf4192dd5a3a9858544a1f14043521 Mon Sep 17 00:00:00 2001 From: Nico Prins Date: Tue, 5 May 2015 09:26:52 -0700 Subject: [PATCH 19/50] Fixed include helper skipping falsy values. --- class.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/class.lua b/class.lua index 20319f0..184c925 100644 --- a/class.lua +++ b/class.lua @@ -36,7 +36,7 @@ local function include_helper(to, from, seen) seen[from] = to for k,v in pairs(from) do k = include_helper({}, k, seen) -- keys might also be tables - if not to[k] then + if to[k] == nil then to[k] = include_helper({}, v, seen) end end From 656fd17dc48972aaaedbada94113ccf4f4996139 Mon Sep 17 00:00:00 2001 From: Nico Prins Date: Wed, 6 May 2015 18:05:19 -0700 Subject: [PATCH 20/50] Added string includes using import method. --- class.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/class.lua b/class.lua index 184c925..9a21943 100644 --- a/class.lua +++ b/class.lua @@ -60,6 +60,9 @@ local function new(class) if getmetatable(inc) then inc = {inc} end for _, other in ipairs(inc) do + if type(other) == "string" then + other = import(other) + end include(class, other) end From 038bc9025f1cb850355f4b073357b087b8122da9 Mon Sep 17 00:00:00 2001 From: Nico Prins Date: Fri, 8 May 2015 15:41:38 -0700 Subject: [PATCH 21/50] Changed how includes are referenced. --- class.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/class.lua b/class.lua index 9a21943..92fd64b 100644 --- a/class.lua +++ b/class.lua @@ -61,7 +61,7 @@ local function new(class) for _, other in ipairs(inc) do if type(other) == "string" then - other = import(other) + other = _G[other] end include(class, other) end From 5c9d51d3561a258e366d9d781ed30bb0bd4f84b8 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sat, 30 May 2015 16:19:26 +0200 Subject: [PATCH 22/50] Fetch event callbacks from love instead of hardcoding it --- gamestate.lua | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/gamestate.lua b/gamestate.lua index 8a299ca..9830c11 100644 --- a/gamestate.lua +++ b/gamestate.lua @@ -57,7 +57,7 @@ end function GS.pop(...) assert(#stack > 1, "No more states to pop!") - local pre, to = stack[#stack], stack[#stack-1] + local pre, to = stack[#stack], stack[#stack-1] stack[#stack] = nil ;(pre.leave or __NULL__)(pre) return (to.resume or __NULL__)(to, pre, ...) @@ -67,13 +67,11 @@ function GS.current() return stack[#stack] end -local all_callbacks = { - 'draw', 'errhand', 'focus', 'keypressed', 'keyreleased', 'mousefocus', - 'mousemoved', 'mousepressed', 'mousereleased', 'quit', 'resize', - 'textinput', 'threaderror', 'update', 'visible', 'gamepadaxis', - 'gamepadpressed', 'gamepadreleased', 'joystickadded', 'joystickaxis', - 'joystickhat', 'joystickpressed', 'joystickreleased', 'joystickremoved' -} +-- fetch event callbacks from love.handlers +local all_callbacks = { 'draw', 'errhand', 'update' } +for k in pairs(love.handlers) do + all_callbacks[#all_callbacks+1] = k +end function GS.registerEvents(callbacks) local registry = {} From 3c666c558b9b0f3565f3e0b37beda4ff58ca6b9b Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sat, 30 May 2015 16:41:37 +0200 Subject: [PATCH 23/50] Fix #46: GS.switch should halt current state cycle `switch`, `push` and `pop` now set a flag marking the new state as dirty. Dirty states will not receive any callbacks except `update`. Before executing `update` the state is marked as clean, so it will receive callbacks from thereon. --- gamestate.lua | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/gamestate.lua b/gamestate.lua index 9830c11..dda39d5 100644 --- a/gamestate.lua +++ b/gamestate.lua @@ -30,29 +30,31 @@ local function __NULL__() end local state_init = setmetatable({leave = __NULL__}, {__index = function() error("Gamestate not initialized. Use Gamestate.switch()") end}) local stack = {state_init} +local state_is_dirty = true local GS = {} function GS.new(t) return t or {} end -- constructor - deprecated! +local function change_state(stack_offset, to, ...) + local pre = stack[#stack] + ;(to.init or __NULL__)(to) + to.init = nil + stack[#stack+stack_offset] = to + state_is_dirty = true + return (to.enter or __NULL__)(to, pre, ...) +end + function GS.switch(to, ...) assert(to, "Missing argument: Gamestate to switch to") assert(to ~= GS, "Can't call switch with colon operator") - local pre = stack[#stack] - ;(pre.leave or __NULL__)(pre) - ;(to.init or __NULL__)(to) - to.init = nil - stack[#stack] = to - return (to.enter or __NULL__)(to, pre, ...) + ;(stack[#stack].leave or __NULL__)(stack[#stack]) + return change_state(0, to, ...) end function GS.push(to, ...) assert(to, "Missing argument: Gamestate to switch to") assert(to ~= GS, "Can't call push with colon operator") - local pre = stack[#stack] - ;(to.init or __NULL__)(to) - to.init = nil - stack[#stack+1] = to - return (to.enter or __NULL__)(to, pre, ...) + return change_state(1, to, ...) end function GS.pop(...) @@ -60,6 +62,7 @@ function GS.pop(...) local pre, to = stack[#stack], stack[#stack-1] stack[#stack] = nil ;(pre.leave or __NULL__)(pre) + state_is_dirty = true return (to.resume or __NULL__)(to, pre, ...) end @@ -87,9 +90,15 @@ end -- forward any undefined functions setmetatable(GS, {__index = function(_, func) - return function(...) - return (stack[#stack][func] or __NULL__)(stack[#stack], ...) + -- call function only if at least one 'update' was called beforehand + -- (see issue #46) + if not state_is_dirty or func == 'update' then + state_is_dirty = false + return function(...) + return (stack[#stack][func] or __NULL__)(stack[#stack], ...) + end end + return __NULL__ end}) return GS From eb05aee86fb5907d19dfb9621336c155da67aa5b Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sat, 30 May 2015 20:21:48 +0200 Subject: [PATCH 24/50] Add support for camera locking. Currently supports: - Position locking (lock camera at target) - Window locking (constrain target to be inside rectangular region) - Position smoothing (none, linear, damped) With these you can also implement horizontal/vertical camera windows, target focus, projected focus, etc. See the great article "Scroll Back: The Theory and Practice of Cameras in Side-Scrollers" by Itay Keren [1] for details. [1] http://gamasutra.com/blogs/ItayKeren/20150511/243083/Scroll_Back_The_Theory_and_Practice_of_Cameras_in_SideScrollers.php#h.949uhirhz51j --- camera.lua | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/camera.lua b/camera.lua index d40b823..f17e457 100644 --- a/camera.lua +++ b/camera.lua @@ -30,11 +30,12 @@ local cos, sin = math.cos, math.sin local camera = {} camera.__index = camera -local function new(x,y, zoom, rot) +local function new(x,y, zoom, rot, smoother) x,y = x or love.graphics.getWidth()/2, y or love.graphics.getHeight()/2 zoom = zoom or 1 rot = rot or 0 - return setmetatable({x = x, y = y, scale = zoom, rot = rot}, camera) + smoother = smoother or camera.smoothNone() -- for locking, see below + return setmetatable({x = x, y = y, scale = zoom, rot = rot, smoother = smoother}, camera) end function camera:lookAt(x,y) @@ -112,6 +113,77 @@ function camera:mousepos() return self:worldCoords(love.mouse.getPosition()) end +-- camera scrolling utilities - adapted from http://gamasutra.com/blogs/ItayKeren/20150511/243083/Scroll_Back_The_Theory_and_Practice_of_Cameras_in_SideScrollers.php + +-- movement interpolators +function camera.smoothNone() + return function(dx,dy) return dx,dy end +end + +function camera.smoothLinear(speed) + assert(type(speed) == "number", "Invalid parameter: speed = "..tostring(speed)) + return function(dx,dy, s) + -- normalize direction + local d = math.sqrt(dx*dx+dy*dy) + dts = math.min((s or speed) * love.timer.getDelta(), d) -- prevent overshooting the goal + if d > 0 then + dx,dy = dx/d, dy/d + end + + return dx*dts, dy*dts + end +end + +function camera.smoothDamped(speed) + assert(type(speed) == "number", "Invalid parameter: speed = "..tostring(speed)) + return function(dx,dy, s) + local dts = love.timer.getDelta() * (s or speed) + return dx*dts, dy*dts + end +end + +-- position locking +function camera:lockX(x, smoother, ...) + local dx, dy = (smoother or self.smoother)(x - self.x, self.y, ...) + self.x = self.x + dx +end + +function camera:lockY(y, smoother, ...) + local dx, dy = (smoother or self.smoother)(self.x, y - self.y, ...) + self.y = self.y + dy +end + +function camera:lockPos(x,y, smoother, ...) + self:move((smoother or self.smoother)(x - self.x, y - self.y, ...)) +end + +-- (possibly) move camera to keep x,y (in world coordinates) inside camera window (in camera coordinates) +function camera:lockWindow(x, y, x_min, x_max, y_min, y_max, smoother, ...) + -- figure out displacement in camera coordinates + x,y = self:cameraCoords(x,y) + local dx, dy = 0,0 + if x < x_min then + dx = x - x_min + elseif x > x_max then + dx = x - x_max + end + if y < y_min then + dy = y - y_min + elseif y > y_max then + dy = y - y_max + end + + -- transform displacement to movement in world coordinates + local c,s = cos(-self.rot), sin(-self.rot) + dx,dy = (c*dx - s*dy) * self.scale, (s*dx + c*dy) * self.scale + + -- move + self:move((smoother or self.smoother)(dx,dy,...)) +end + -- the module -return setmetatable({new = new}, - {__call = function(_, ...) return new(...) end}) +return setmetatable({new = new, + smoothNone = camera.smoothNone, + smoothLinear = camera.smoothLinear, + smoothDamped = camera.smoothDamped + }, {__call = function(_, ...) return new(...) end}) From ca7fa8acb302522660e77483d63f06ffd2066204 Mon Sep 17 00:00:00 2001 From: vrld Date: Wed, 7 Oct 2015 21:48:20 +0200 Subject: [PATCH 25/50] (Issue #49) Don't overwrite state.init on gamestate.switch --- gamestate.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gamestate.lua b/gamestate.lua index dda39d5..61517f9 100644 --- a/gamestate.lua +++ b/gamestate.lua @@ -30,6 +30,7 @@ local function __NULL__() end local state_init = setmetatable({leave = __NULL__}, {__index = function() error("Gamestate not initialized. Use Gamestate.switch()") end}) local stack = {state_init} +local initialized_states = setmetatable({}, {__mode = "k"}) local state_is_dirty = true local GS = {} @@ -37,8 +38,11 @@ function GS.new(t) return t or {} end -- constructor - deprecated! local function change_state(stack_offset, to, ...) local pre = stack[#stack] - ;(to.init or __NULL__)(to) - to.init = nil + + -- initialize only on first call + ;(initialized_states[to] or to.init)(to) + initialized_states[to] = __NULL__ + stack[#stack+stack_offset] = to state_is_dirty = true return (to.enter or __NULL__)(to, pre, ...) From f6c5f621e73c94e5c89284e3690c6a5e31b07453 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Mon, 12 Oct 2015 08:21:16 +0200 Subject: [PATCH 26/50] Code cleanup --- camera.lua | 89 ++++++++++++++++++++++++++++-------------------------- signal.lua | 22 +++++++------- timer.lua | 28 ++++++++--------- vector.lua | 12 ++++---- 4 files changed, 78 insertions(+), 73 deletions(-) diff --git a/camera.lua b/camera.lua index f17e457..74e2c98 100644 --- a/camera.lua +++ b/camera.lua @@ -1,5 +1,5 @@ --[[ -Copyright (c) 2010-2013 Matthias Richter +Copyright (c) 2010-2015 Matthias Richter Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,21 +30,51 @@ local cos, sin = math.cos, math.sin local camera = {} camera.__index = camera +-- Movement interpolators (for camera locking/windowing) +smooth.smooth = {} + +function camera.smooth.none() + return function(dx,dy) return dx,dy end +end + +function camera.smooth.linear(speed) + assert(type(speed) == "number", "Invalid parameter: speed = "..tostring(speed)) + return function(dx,dy, s) + -- normalize direction + local d = math.sqrt(dx*dx+dy*dy) + dts = math.min((s or speed) * love.timer.getDelta(), d) -- prevent overshooting the goal + if d > 0 then + dx,dy = dx/d, dy/d + end + + return dx*dts, dy*dts + end +end + +function camera.smooth.damped(stiffness) + assert(type(stiffness) == "number", "Invalid parameter: stiffness = "..tostring(stiffness)) + return function(dx,dy, s) + local dts = love.timer.getDelta() * (s or stiffness) + return dx*dts, dy*dts + end +end + + local function new(x,y, zoom, rot, smoother) x,y = x or love.graphics.getWidth()/2, y or love.graphics.getHeight()/2 zoom = zoom or 1 rot = rot or 0 - smoother = smoother or camera.smoothNone() -- for locking, see below + smoother = smoother or camera.smooth.none() -- for locking, see below return setmetatable({x = x, y = y, scale = zoom, rot = rot, smoother = smoother}, camera) end function camera:lookAt(x,y) - self.x, self.y = x,y + self.x, self.y = x, y return self end -function camera:move(x,y) - self.x, self.y = self.x + x, self.y + y +function camera:move(dx,dy) + self.x, self.y = self.x + dx, self.y + dy return self end @@ -109,55 +139,33 @@ function camera:worldCoords(x,y) return x+self.x, y+self.y end -function camera:mousepos() +function camera:mousePos() return self:worldCoords(love.mouse.getPosition()) end --- camera scrolling utilities - adapted from http://gamasutra.com/blogs/ItayKeren/20150511/243083/Scroll_Back_The_Theory_and_Practice_of_Cameras_in_SideScrollers.php +-- camera scrolling utilities - adapted from --- movement interpolators -function camera.smoothNone() - return function(dx,dy) return dx,dy end -end - -function camera.smoothLinear(speed) - assert(type(speed) == "number", "Invalid parameter: speed = "..tostring(speed)) - return function(dx,dy, s) - -- normalize direction - local d = math.sqrt(dx*dx+dy*dy) - dts = math.min((s or speed) * love.timer.getDelta(), d) -- prevent overshooting the goal - if d > 0 then - dx,dy = dx/d, dy/d - end - - return dx*dts, dy*dts - end -end - -function camera.smoothDamped(speed) - assert(type(speed) == "number", "Invalid parameter: speed = "..tostring(speed)) - return function(dx,dy, s) - local dts = love.timer.getDelta() * (s or speed) - return dx*dts, dy*dts - end -end - --- position locking +--- Lock camera's x coordinate. +-- @param x X coordinate (in world coordinates) to lock to. +-- @param smoother Overriding smoothing function (optional). +-- @param ... Additional parameters to the smoothing function (optional). +-- @return The camera. function camera:lockX(x, smoother, ...) local dx, dy = (smoother or self.smoother)(x - self.x, self.y, ...) self.x = self.x + dx + return self end function camera:lockY(y, smoother, ...) local dx, dy = (smoother or self.smoother)(self.x, y - self.y, ...) self.y = self.y + dy + return self end function camera:lockPos(x,y, smoother, ...) - self:move((smoother or self.smoother)(x - self.x, y - self.y, ...)) + return self:move((smoother or self.smoother)(x - self.x, y - self.y, ...)) end --- (possibly) move camera to keep x,y (in world coordinates) inside camera window (in camera coordinates) function camera:lockWindow(x, y, x_min, x_max, y_min, y_max, smoother, ...) -- figure out displacement in camera coordinates x,y = self:cameraCoords(x,y) @@ -182,8 +190,5 @@ function camera:lockWindow(x, y, x_min, x_max, y_min, y_max, smoother, ...) end -- the module -return setmetatable({new = new, - smoothNone = camera.smoothNone, - smoothLinear = camera.smoothLinear, - smoothDamped = camera.smoothDamped - }, {__call = function(_, ...) return new(...) end}) +return setmetatable({new = new, smooth = camera.smooth}, + {__call = function(_, ...) return new(...) end}) diff --git a/signal.lua b/signal.lua index 8d039a8..975d4c8 100644 --- a/signal.lua +++ b/signal.lua @@ -58,19 +58,19 @@ function Registry:clear(...) end end -function Registry:emit_pattern(p, ...) +function Registry:emitPattern(p, ...) for s in pairs(self) do if s:match(p) then self:emit(s, ...) end end end -function Registry:remove_pattern(p, ...) +function Registry:removePattern(p, ...) for s in pairs(self) do if s:match(p) then self:remove(s, ...) end end end -function Registry:clear_pattern(p) +function Registry:clearPattern(p) for s in pairs(self) do if s:match(p) then self[s] = {} end end @@ -81,14 +81,14 @@ local function new() local registry = setmetatable({}, Registry) return setmetatable({ - new = new, - register = function(...) return registry:register(...) end, - emit = function(...) registry:emit(...) end, - remove = function(...) registry:remove(...) end, - clear = function(...) registry:clear(...) end, - emit_pattern = function(...) registry:emit_pattern(...) end, - remove_pattern = function(...) registry:remove_pattern(...) end, - clear_pattern = function(...) registry:clear_pattern(...) end, + new = new, + register = function(...) return registry:register(...) end, + emit = function(...) registry:emit(...) end, + remove = function(...) registry:remove(...) end, + clear = function(...) registry:clear(...) end, + emitPattern = function(...) registry:emitPattern(...) end, + removePattern = function(...) registry:removePattern(...) end, + clearPattern = function(...) registry:clearPattern(...) end, }, {__call = new}) end diff --git a/timer.lua b/timer.lua index a8b3e34..dc19d49 100644 --- a/timer.lua +++ b/timer.lua @@ -45,20 +45,20 @@ function Timer:update(dt) end end -function Timer:do_for(delay, func, after) +function Timer:during(delay, func, after) local handle = {func = func, after = after or _nothing_} self.functions[handle] = delay return handle end -function Timer:add(delay, func) - return self:do_for(delay, _nothing_, func) +function Timer:after(delay, func) + return self:during(delay, _nothing_, func) end -function Timer:addPeriodic(delay, func, count) +function Timer:every(delay, func, count) local count, handle = count or math.huge -- exploit below: math.huge - 1 = math.huge - handle = self:add(delay, function(f) + handle = self:after(delay, function(f) if func(func) == false then return end count = count - 1 if count > 0 then @@ -133,7 +133,7 @@ __call = function(tween, self, len, subject, target, method, after, ...) local payload, t, args = tween_collect_payload(subject, target, {}), 0, {...} local last_s = 0 - return self:do_for(len, function(dt) + return self:during(len, function(dt) t = t + dt local s = method(math.min(1, t/len), unpack(args)) local ds = s - last_s @@ -170,14 +170,14 @@ end}) local function new() local timer = setmetatable({functions = {}, tween = Timer.tween}, Timer) return setmetatable({ - new = new, - update = function(...) return timer:update(...) end, - do_for = function(...) return timer:do_for(...) end, - add = function(...) return timer:add(...) end, - addPeriodic = function(...) return timer:addPeriodic(...) end, - cancel = function(...) return timer:cancel(...) end, - clear = function(...) return timer:clear(...) end, - tween = setmetatable({}, { + new = new, + update = function(...) return timer:update(...) end, + during = function(...) return timer:during(...) end, + after = function(...) return timer:after(...) end, + every = function(...) return timer:every(...) end, + cancel = function(...) return timer:cancel(...) end, + clear = function(...) return timer:clear(...) end, + tween = setmetatable({}, { __index = Timer.tween, __newindex = function(_,k,v) Timer.tween[k] = v end, __call = function(t,...) return timer:tween(...) end, diff --git a/vector.lua b/vector.lua index 9abdf34..55f65e5 100644 --- a/vector.lua +++ b/vector.lua @@ -120,7 +120,7 @@ function vector.dist2(a, b) return (dx * dx + dy * dy) end -function vector:normalize_inplace() +function vector:normalizeInplace() local l = self:len() if l > 0 then self.x, self.y = self.x / l, self.y / l @@ -129,10 +129,10 @@ function vector:normalize_inplace() end function vector:normalized() - return self:clone():normalize_inplace() + return self:clone():normalizeInplace() end -function vector:rotate_inplace(phi) +function vector:rotateInplace(phi) local c, s = cos(phi), sin(phi) self.x, self.y = c * self.x - s * self.y, s * self.x + c * self.y return self @@ -167,7 +167,7 @@ function vector:cross(v) end -- ref.: http://blog.signalsondisplay.com/?p=336 -function vector:trim_inplace(maxLen) +function vector:trimInplace(maxLen) local s = maxLen * maxLen / self:len2() s = (s > 1 and 1) or math.sqrt(s) self.x, self.y = self.x * s, self.y * s @@ -182,10 +182,10 @@ function vector:angleTo(other) end function vector:trimmed(maxLen) - return self:clone():trim_inplace(maxLen) + return self:clone():trimInplace(maxLen) end -- the module return setmetatable({new = new, isvector = isvector, zero = zero}, -{__call = function(_, ...) return new(...) end}) + {__call = function(_, ...) return new(...) end}) From 52324d53688a276fc30aec92b573b439798a5b4f Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Mon, 12 Oct 2015 08:21:31 +0200 Subject: [PATCH 27/50] Documentation with sphinx --- docs/3 | 391 +++++++++++++++++++ docs/Makefile | 192 +++++++++ docs/_static/graph-tweens.js | 218 +++++++++++ docs/_static/in-out-interpolators.png | Bin 0 -> 102836 bytes docs/_static/interpolators.png | Bin 0 -> 96764 bytes docs/_static/inv-interpolators.png | Bin 0 -> 55476 bytes docs/_static/tween-example.svg | 225 +++++++++++ docs/_static/vector-cross.png | Bin 0 -> 13425 bytes docs/_static/vector-mirrorOn.png | Bin 0 -> 13106 bytes docs/_static/vector-perpendicular.png | Bin 0 -> 13768 bytes docs/_static/vector-projectOn.png | Bin 0 -> 29907 bytes docs/_static/vector-rotated.png | Bin 0 -> 12682 bytes docs/camera.rst | 537 ++++++++++++++++++++++++++ docs/class.rst | 344 +++++++++++++++++ docs/conf.py | 293 ++++++++++++++ docs/gamestate.rst | 349 +++++++++++++++++ docs/index.rst | 52 +++ docs/license.rst | 26 ++ docs/signal.rst | 180 +++++++++ docs/timer.rst | 396 +++++++++++++++++++ docs/vector-light.rst | 398 +++++++++++++++++++ docs/vector.rst | 422 ++++++++++++++++++++ 22 files changed, 4023 insertions(+) create mode 100644 docs/3 create mode 100644 docs/Makefile create mode 100644 docs/_static/graph-tweens.js create mode 100644 docs/_static/in-out-interpolators.png create mode 100644 docs/_static/interpolators.png create mode 100644 docs/_static/inv-interpolators.png create mode 100644 docs/_static/tween-example.svg create mode 100644 docs/_static/vector-cross.png create mode 100644 docs/_static/vector-mirrorOn.png create mode 100644 docs/_static/vector-perpendicular.png create mode 100644 docs/_static/vector-projectOn.png create mode 100644 docs/_static/vector-rotated.png create mode 100644 docs/camera.rst create mode 100644 docs/class.rst create mode 100644 docs/conf.py create mode 100644 docs/gamestate.rst create mode 100644 docs/index.rst create mode 100644 docs/license.rst create mode 100644 docs/signal.rst create mode 100644 docs/timer.rst create mode 100644 docs/vector-light.rst create mode 100644 docs/vector.rst diff --git a/docs/3 b/docs/3 new file mode 100644 index 0000000..0cfffe0 --- /dev/null +++ b/docs/3 @@ -0,0 +1,391 @@ +hump.vector +=========== + +:: + + vector = require "hump.vector" + +A handy 2D vector class providing most of the things you do with vectors. + +You can access the individual coordinates by ``vec.x`` and ``vec.y``. + +.. note:: + + The vectors are stored as tables. Most operations create new vectors and + thus new tables, which *may* put + +**Example**:: + + function player:update(dt) + local delta = vector(0,0) + if love.keyboard.isDown('left') then + delta.x = -1 + elseif love.keyboard.isDown('right') then + delta.x = 1 + end + if love.keyboard.isDown('up') then + delta.y = -1 + elseif love.keyboard.isDown('down') then + delta.y = 1 + end + delta:normalize_inplace() + + player.velocity = player.velocity + delta * player.acceleration * dt + + if player.velocity:len() > player.max_velocity then + player.velocity = player.velocity:normalized() * player.max_velocity + end + + player.position = player.position + player.velocity * dt + end + + +Vector arithmetic +----------------- + +**hump** provides vector arithmetic by implement the corresponding metamethods +(``__add``, ``__mul``, etc.). Here are the semantics: + +``vector + vector = vector`` + Component wise sum: \((a,b) + (x,y) = (a+x, b+y)\) +``vector - vector = vector`` + Component wise difference: \((a,b) - (x,y) = (a-x, b-y)\) +``vector * vector = number`` + Dot product: \((a,b) * (x,y) = a*x + b*y\) +``number * vector = vector`` + Scalar multiplication/scaling: \((a,b) * s = (s*a, s*b)\) +``vector * number = vector`` + Scalar multiplication/scaling: \(s * (x,y) = (s*x, s*y)\) +``vector / number = vector`` + Scalar multiplication/scaling: \((a,b) / s = (a/s, b/s)\). + +Common relations are also defined: + +``a == b`` + Same as ``a.x == b.x and a.y == b.y``. +``a <= b`` + Same as ``a.x <= b.x and a.y <= b.y``. +``a < b`` + Lexicographical order: ``a.x < b.x or (a.x == b.x and a.y < b.y)``. + +**Example**:: + + -- acceleration, player.velocity and player.position are vectors + acceleration = vector(0,-9) + player.velocity = player.velocity + acceleration * dt + player.position = player.position + player.velocity * dt + + +Function Reference +------------------ + +.. function:: vector.new(x,y) + + :param numbers x,y: Coordinates. + :returns: The vector. + + +Create a new vector. + +**Examples**:: + + a = vector.new(10,10) + +:: + + -- as a shortcut, you can call the module like a function: + vector = require "hump.vector" + a = vector(10,10) + + +.. function:: vector.isvector(v) + + :param mixed v: The variable to test. + :returns: ``true`` if ``v`` is a vector, ``false`` otherwise. + +Test whether a variable is a vector. + +**Example**:: + + if not vector.isvector(v) then + v = vector(v,0) + end + + +.. function:: vector.vector:clone() + + :returns: Copy of the vector. + +Copy a vector. Assigning a vector to a variable will create a *reference*, so +when modifying the vector referenced by the new variable would also change the +old one:: + + a = vector(1,1) -- create vector + b = a -- b references a + c = a:clone() -- c is a copy of a + b.x = 0 -- changes a,b and c + print(a,b,c) -- prints '(1,0), (1,0), (1,1)' + +**Example**:: + + copy = original:clone() + + +.. function:: vector.vector:unpack() + + :returns: The coordinates ``x,y``. + + +Extract coordinates. + +**Examples**:: + + x,y = pos:unpack() + +:: + + love.graphics.draw(self.image, self.pos:unpack()) + + +.. function:: vector.vector:permul(other) + + :param vector other: The second source vector. + :returns: Vector whose components are products of the source vectors. + + +Multiplies vectors coordinate wise, i.e. ``result = vector(a.x * b.x, a.y * +b.y)``. + +This does not change either argument vectors, but creates a new one. + +**Example**:: + + -- scale with different magnitudes + scaled = original:permul(vector(1,1.5)) + + +.. function:: vector.vector:len() + + :returns: ``number`` Length of the vector. + + +Get length of a vector, i.e. ``math.sqrt(vec.x * vec.x + vec.y * vec.y)``. + +**Example**:: + + distance = (a - b):len() + + +.. function:: vector.vector:len2() + + :returns: ``number`` Squared length of the vector. + + +Get squared length of a vector, i.e. ``vec.x * vec.x + vec.y * vec.y``. + +**Example**:: + + -- get closest vertex to a given vector + closest, dsq = vertices[1], (pos - vertices[1]):len2() + for i = 2,#vertices do + local temp = (pos - vertices[i]):len2() + if temp < dsq then + closest, dsq = vertices[i], temp + end + end + + +.. function:: vector.vector:dist(other) + + :param vector other: Other vector to measure the distance to. + :returns: ``number`` The distance of the vectors. + + +Get distance of two vectors. The same as ``(a - b):len()``. + +**Example**:: + + -- get closest vertex to a given vector + -- slightly slower than the example using len2() + closest, dist = vertices[1], pos:dist(vertices[1]) + for i = 2,#vertices do + local temp = pos:dist(vertices[i]) + if temp < dist then + closest, dist = vertices[i], temp + end + end + + +.. function:: vector.vector:dist2(other) + + :param vector other: Other vector to measure the distance to. + :returns: ``number`` The squared distance of the vectors. + + +Get squared distance of two vectors. The same as ``(a - b):len2()``. + +**Example**:: + + -- get closest vertex to a given vector + -- slightly faster than the example using len2() + closest, dsq = vertices[1], pos:dist2(vertices[1]) + for i = 2,#vertices do + local temp = pos:dist2(vertices[i]) + if temp < dsq then + closest, dsq = vertices[i], temp + end + end + + +.. function:: vector.vector:normalized() + + :returns: ``vector`` Vector with same direction as the input vector, but length 1. + + +Get normalized vector, i.e. a vector with the same direction as the input +vector, but with length 1. + +This does not change the input vector, but creates a new vector. + +**Example**:: + + direction = velocity:normalized() + + +.. function:: vector.vector:normalize_inplace() + + :returns: ``vector`` Itself - the normalized vector + + +Normalize a vector, i.e. make the vector unit length. Great to use on +intermediate results. + +**This modifies the vector. If in doubt, use +[``vector:normalized()``](#hump.vectornormalized).** + +**Example**:: + + normal = (b - a):perpendicular():normalize_inplace() + + +.. function:: vector.vector:rotated(angle) + + :param number angle: Rotation angle in radians. + :returns: ``vector`` The rotated vector + + +Get a rotated vector. + +This does not change the input vector, but creates a new vector. + +**Example**:: + + -- approximate a circle + circle = {} + for i = 1,30 do + local phi = 2 * math.pi * i / 30 + circle[#circle+1] = vector(0,1):rotated(phi) + end + +**Sketch**:: + +![Rotated vector sketch](vector-rotated.png) + + +.. function:: vector.vector:rotate_inplace(angle) + + :param number angle: Rotation angle in radians. + :returns: ``vector`` Itself - the rotated vector + + +Rotate a vector in-place. Great to use on intermediate results. + +**This modifies the vector. If in doubt, use +[``vector:rotated()``](#hump.vectorvector:rotated).** + +**Example**:: + + -- ongoing rotation + spawner.direction:rotate_inplace(dt) + + +.. function:: vector.vector:perpendicular() + + :returns: ``vector`` A vector perpendicular to the input vector + + +Quick rotation by 90°. Creates a new vector. The same (but faster) as +``vec:rotate(math.pi/2)``. + +**Example**:: + + normal = (b - a):perpendicular():normalize_inplace() + +**Sketch**:: + +![Perpendiculat vector sketch](vector-perpendicular.png) + + +.. function:: vector.vector:projectOn(v) + + :param vector v: The vector to project on. + :returns: ``vector`` The projected vector. + + +Project vector onto another vector (see sketch). + +**Example**:: + + velocity_component = velocity:projectOn(axis) + +**Sketch**:: + +![Projected vector sketch](vector-projectOn.png) + + +.. function:: vector.vector:mirrorOn(v) + + :param vector v: The vector to mirror on. + :returns: ``vector`` The mirrored vector. + + +Mirrors vector on the axis defined by the other vector. + +**Example**:: + + deflected_velocity = ball.velocity:mirrorOn(surface_normal) + +**Sketch**:: + +![Mirrored vector sketch](vector-mirrorOn.png) + + +.. function:: vector.vector:cross(other) + + :param vector other: Vector to compute the cross product with. + :returns: ``number`` Cross product of both vectors. + + +Get cross product of both vectors. Equals the area of the parallelogram spanned +by both vectors. + +**Example**:: + + parallelogram_area = a:cross(b) + + +.. function:: vector.vector:angleTo(other) + + :param vector other (optional): Vector to measure the angle to. + :returns: ``number`` Angle in radians. + + +Measures the angle between two vectors. If ``other`` is omitted it defaults +to the vector ``(0,0)``, i.e. the function returns the angle to the coordinate +system. + +**Example**:: + + lean = self.upvector:angleTo(vector(0,1)) + if lean > .1 then self:fallOver() end + diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..2ce17ef --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,192 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# 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 coverage gettext + +help: + @echo "Please use \`make ' where 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 " applehelp to make an Apple Help Book" + @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 " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @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 " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " coverage to run coverage check of 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/hump.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/hump.qhc" + +applehelp: + $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp + @echo + @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." + @echo "N.B. You won't be able to view it unless you put it in" \ + "~/Library/Documentation/Help or install it in your application" \ + "bundle." + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/hump" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/hump" + @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." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @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." + +coverage: + $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage + @echo "Testing of coverage in the sources finished, look at the " \ + "results in $(BUILDDIR)/coverage/python.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docs/_static/graph-tweens.js b/docs/_static/graph-tweens.js new file mode 100644 index 0000000..046b55a --- /dev/null +++ b/docs/_static/graph-tweens.js @@ -0,0 +1,218 @@ +(function() { +"use strict"; + +// DISCLAIMER: I just started learning d3, so this is certainly not good +// idiomatic d3 code. But hey, it works (kinda). + +var tweens = { + 'out': function(f) { return function(s) { return 1-f(1-s) } }, + 'chain': function(f1, f2) { return function(s) { return ((s<.5) ? f1(2*s) : 1+f2(2*s-1)) * .5 } }, + 'linear': function(s) { return s }, + 'quad': function(s) { return s*s }, + 'cubic': function(s) { return s*s*s }, + 'quart': function(s) { return s*s*s*s }, + 'quint': function(s) { return s*s*s*s*s }, + 'sine': function(s) { return 1 - Math.cos(s*Math.PI/2) }, + 'expo': function(s) { return Math.pow(2, 10*(s-1)) }, + 'circ': function(s) { return 1 - Math.sqrt(Math.max(0,1-s*s)) }, + 'back': function(s) { var b = 1.70158; return s*s*((b+1)*s - b) }, + 'bounce': function(s) { + return Math.min( + 7.5625 * Math.pow(s, 2), + 7.5625 * Math.pow((s - .545455), 2) + .75, + 7.5625 * Math.pow((s - .818182), 2) + .90375, + 7.5625 * Math.pow((s - .954546), 2) + .984375) + }, + 'elastic': function(s) { + return -Math.sin(2/0.3 * Math.PI * (s-1) - Math.asin(1)) * Math.pow(2, 10*(s-1)) + }, +}; +var tweenfunc = tweens.linear; + + +var width_graph = 320, + width_anim_move = 110, + width_anim_rotate = 110, + width_anim_size = 110, + height = 250; + +// "UI" +var graph_ui = d3.select("#tween-graph").append("div") + .attr("id", "tween-graph-ui"); +// rest see below + +// the graph +var graph = d3.select("#tween-graph").append("svg") + .attr("width", width_graph).attr("height", height); + +// background +graph.append("rect") + .attr("width", "100%").attr("height", "100%") + .attr("style", "fill:rgb(240,240,240);stroke-width:1;stroke:rgb(100,100,100);"); + +var y_zero = height * .78, y_one = height * .22; +graph.append("rect") + .attr("y", y_one) + .attr("width", "100%").attr("height", y_zero - y_one) + .attr("style", "fill:steelblue;fill-opacity:.3;stroke-width:1;stroke:rgba(100,100,100,.7)"); + +// time arrow +graph.append("defs") + .append("marker") + .attr("id", "triangle") + .attr("viewBox", "0 0 10 10") + .attr("refX", 1).attr("refY", 5) + .attr("markerWidth", 4) + .attr("markerHeight", 4) + .attr("orient", "auto") + .attr("style", "fill:rgba(0,0,0,.5)") + .append("path").attr("d", "M 0 0 L 10 5 L 0 10 z"); + +graph.append("line") + .attr("x1", width_graph/2-80) + .attr("x2", width_graph/2+80) + .attr("y1", y_zero + 40).attr("y2", y_zero + 40) + .attr("style", "stroke-width:2;stroke:rgba(0,0,0,.5)") + .attr("marker-end", "url(#triangle)"); + +graph.append("text") + .text("Time") + .attr("x", width_graph/2).attr("y", y_zero + 55) + .attr("style", "text-anchor:middle;fill:rgba(0,0,0,.5);font-size:15px"); + +// the actual graph +var curve = d3.svg.line() + .x(function(x) { return x*width_graph; }) + .y(function(x) { return tweenfunc(x) * (y_one - y_zero) + y_zero; }) + +var graph_curve = graph.append("path").attr("d", curve(d3.range(0,1.05,.005))) + .attr("style", "fill:none;stroke-width:2;stroke:seagreen;"); + +var graph_marker = graph.append("circle") + .attr("r", 5) + .attr("style", "stroke:goldenrod;fill:none;stroke-width:3"); + +// finally, a label +var graph_label = graph.append("text") + .text("linear") + .attr("x", width_graph/2).attr("y", 20) + .attr("style", "text-anchor:middle;font-weight:bold;font-size:15px;"); + + +// animation examples - moving ball +var anim_move = d3.select("#tween-graph").append("svg") + .attr("width", width_anim_move).attr("height", height); + +anim_move.append("rect") + .attr("width", "100%").attr("height", "100%") + .attr("style", "fill:rgb(240,240,240);stroke-width:1;stroke:rgb(100,100,100);"); + +anim_move.append("rect") + .attr("width", 10).attr("height", (y_zero - y_one)) + .attr("x", width_anim_move/2-5).attr("y", y_one) + .attr("style", "fill:black;opacity:.1"); + +var anim_move_ball = anim_move.append("circle") + .attr("cx", width_anim_move/2).attr("cy", y_one) + .attr("r", 17) + .attr("style", "fill:steelblue;stroke:rgb(90,90,90);stroke-width:5;"); + +// animation examples - rotating square +var anim_rotate = d3.select("#tween-graph").append("svg") + .attr("width", width_anim_size).attr("height", height); + +anim_rotate.append("rect") + .attr("width", "100%").attr("height", "100%") + .attr("style", "fill:rgb(240,240,240);stroke-width:1;stroke:rgb(100,100,100);"); + +var w = width_anim_size/2; +var anim_rotate_square = anim_rotate.append("rect") + .attr("x", -w/2).attr("y", -w/4) + .attr("width", w).attr("height", w/2) + .attr("style", "fill:steelblue;stroke:rgb(90,90,90);stroke-width:5;"); + +// animation examples - resizing ellipse +var anim_size = d3.select("#tween-graph").append("svg") + .attr("width", width_anim_size).attr("height", height); + +anim_size.append("rect") + .attr("width", "100%").attr("height", "100%") + .attr("style", "fill:rgb(240,240,240);stroke-width:1;stroke:rgb(100,100,100);"); + +anim_size.append("ellipse") + .attr("cx", width_anim_size/2).attr("cy", height/2) + .attr("rx", 40).attr("ry", 120) + .attr("style", "fill:rgb(150,150,150);stroke:black;stroke-width:2;opacity:.1"); + +var anim_size_ellipse = anim_size.append("ellipse") + .attr("cx", width_anim_size/2).attr("cy", height/2) + .attr("rx", 40).attr("ry", 40) + .attr("style", "fill:steelblue;stroke:rgb(90,90,90);stroke-width:5;"); + + +// make it move! +var t = 0; +window.setInterval(function() { + t = (t + .025 / 3); + if (t > 1.3) { t = -.3; } + var tt = Math.max(Math.min(t, 1), 0); + + var s = tweenfunc(tt) + var yy = s * (y_one - y_zero) + y_zero; + var translate = "translate("+(width_anim_size/2)+" "+(height/2)+")"; + var rotate = "rotate(" + (s * 360) + ")"; + + graph_marker.attr("cx", tt*width_graph).attr("cy", yy); + anim_move_ball.attr("cy", y_one + y_zero - yy); + anim_rotate_square.attr("transform", translate + " " + rotate); + anim_size_ellipse.attr("ry", s * 80 + 40); +}, 25); + + +// ui continued +graph_ui.append("strong").text("Function: "); +var select_modifier = graph_ui.append("select"); +select_modifier.append("option").text("in"); +select_modifier.append("option").text("out"); +select_modifier.append("option").text("in-out"); +select_modifier.append("option").text("out-in"); +graph_ui.append("strong").text("-") + +var select_func = graph_ui.append("select") +var funcs = []; +for (var k in tweens) +{ + if (k != "out" && k != "chain") + { + select_func.append("option").text(k); + funcs.push(k); + } +} + +var change_tweenfunc = function() +{ + var fname = funcs[select_func.node().selectedIndex]; + var mod = select_modifier.node().selectedIndex; + + tweenfunc = tweens[fname]; + if (mod == 1) // out + tweenfunc = tweens.out(tweenfunc); + else if (mod == 2) // in-out + tweenfunc = tweens.chain(tweenfunc, tweens.out(tweenfunc)); + else if (mod == 3) // out-in + tweenfunc = tweens.chain(tweens.out(tweenfunc), tweenfunc); + + // update curve + graph_curve.attr("d", curve(d3.range(0,1.05,.005))) + + // update label + if (mod != 0) + graph_label.text((['in','out','in-out','out-in'])[mod] + "-" + fname); + else + graph_label.text(fname); +} + +select_func.on("change", change_tweenfunc); +select_modifier.on("change", change_tweenfunc); + +})(); diff --git a/docs/_static/in-out-interpolators.png b/docs/_static/in-out-interpolators.png new file mode 100644 index 0000000000000000000000000000000000000000..f401f56a23b98457e02e987819ffc4928833b5e7 GIT binary patch literal 102836 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

nxFUpsm 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�tzee*WV-$AQW1MB z@%?2<=zd{ayeWCjT^4f!z$VtPC7IsfM|~`r83H&EKFZwv*XrbiDA|gf+Azea`R_u8BU~(j5%!%i20ZhTi?@>6 zfKy94RY^Q?4OYRRZ~}z^hKMwSmAZxY-2Ty?c#Iz@tjwJJ8<9B)Gi+pK(n5+mH0UUr z=@{|9i&vNOguflNwS|??@djc@Bxx}$%2Z6|k4Gw(iW-(EYt#nVlRr3jfk_vznjjH- ze{WY+QVL%q-P@Y1%9qJ?IUXr$fqk-N$MR7!4cNA#p_zE)i~ScX3G$Rd;9(kpmduodTpFP%q| zhDXrwo}b}c!MZ|2dYFTe>5~9b<*q(kv9Wm)bw6^AmD$9bGr1N_B0fTy(QUqz z-j^}sQ7tpcW{7}{^@(h_;~NW1U{=njS)YPR6ZPO7WBjf)R>g_B6ui1qj(Fui3#moa zRr@dc)#fLs(yn{^HwwB3OiGzwl~;>5-0$631pyUpZ#N`_Xo); z{$t;H6{HPjiJqK*8Ukz2>L&@yWHCmi=Acz^&*#LpYg2sfdkVgl^@1mt+ck*kFwV;8 z)gPOhQ)_}1dKc6eu5h|TH7c6v8cF3P=R(#VOMakggN6S9B5JuT=<@M_^s z^uDnK02mbYoDLtEXOxgcIv66pus|aB;cu zpH;*A7KCCQ8y$DlgC2D0w*wPa6T+22@>kS7_WV!p!UwwLF7uT

`TY`d7Lw`-LX3yt~WSbmF6%;Fp09Pe(rxx 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 literal 0 HcmV?d00001 diff --git a/docs/_static/interpolators.png b/docs/_static/interpolators.png new file mode 100644 index 0000000000000000000000000000000000000000..e2c9ded649728e1ec22aa2367cb63a336ee48bd8 GIT binary patch literal 96764 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

yDU<$tr6>2X(~{xhIKv|&{WvM zX=QwM%tTw{$Ys!QYuIXR0xR&s{n>x0bnBpl`7n z{*xmWuNdFMjN#+2!#H_@EhEz(yq%Way;t9Qz2LjXa2Sx2t?)36oejM>!8_y9{)2&) zm7JIF-m3`L=gYz}?&9F4)8$nQiw`oT!w0tntENrc{Yo-BdyIR0E^f9Q4;~ZqB+LC9 z1kBzeHWNX*WL^2BX0vqvYZG{M7$`A&^qqOe>NU^$jz%xS{3x zyBtBQYg*PyzJE!BACzj0E0e^%A+n*A#ZL3VNQ5?GLt2sHf5V|FtTozYKcaE6WGdnJ zwNY>cWYrm7f4DTScbMB{7^>RL4}M?HUJ2;B7t-r2zL|F3=@to8382@TdpTztIY5zV z9fi%V5k?smz7!yU(3qO2whs>JC-1VX!uYVFh*_WwT}`r^woxW{mN;E3*;Ux z+M+Q`sKJx$c@0RkWO`w4&and$U|rUz+iA|p&+V9|$G9A8zJ|J}aZ9`ZED@33+!v&A zU71JI^VJ;&xM-koymutJ2dc!fx4qjE586y3IX+|9*kZ_^k$)`N^1c@qZ;}{5)@2bN zHob-dNlVq9)7rjtrEBN^q2@x$0_iXT7go7i5kwE4mUhE`C3md2ZW7!zl40+7i z8Fof6XT*I4-*r8@mR&3@IBrTSR>H=PoKYHX!y7MJya@E}GW1rOhYlkQZSLthyIWljGEWUW?&8 zlkK@kMT`~fKim@Cgx$WduQhacbNipf>i&K1fRQv!y3hs&qPE44>q9igh|3ciVP~TW zs4MH6?9T{4)Wb=;hX|*l&XArL!(IL9x!o`n(%F>~Pn#@8sQNi8Z{ceG)unf0%x#D9 z3+Bf!S2~bx2g%QxL0n96qjTZiTyU-DmvC9FdMqj;Zgw!!15eC!^md#9gCv4iLiodX zd~9XK+qV;a5GMGR#JI22O;R+6?ibDlQ%{k6-(!)%K3gOke)^^PoWy(Yo{0)gLG}C# zn)^k*n24QUjhCTqD|pn+ID2%~CLRITxwfNN?X7S*Z+xv@S7!)4XVU0ey}#dDzNsTf zHyLa+|2&i z!-JO+NK{p2vb@q9`QciWD?NqiPwQYsR44`@xX`lTB;m>ReM-m5LRb4KQPfxNJTugK z$-2mIZqMJI??ej;pC=dx9=5fGaUnu+U~V}yTrctv_K8b-Cpl>-C zk9k@7_}Cc!DTnrel~f>#duUASAgq$Or*KM)+z>_0`vPzL8RDrm@%;A+f+1%g=D^Gg zo&M4cvPp-QrB3{8chZ#PlpLQA6qdGxAM;;cIwoBG-zEU|O43fnMod>Rjh|ckiI$b1 zh)&BU%4oP#hQf-p8RD5TQfcJ0G$`Sj&biO!Pel;x;i|1BXd&lvm)Nho!%yt@#}2&M z8cH(|p-D|_Xf!s&D-`xNUsr3a*_4=-+jG*qo`K1_My&zZf-AVrv$WMz+?m*@0ZCRV zDS9Ip;cRSJG?J)8p-Ktu2VT&fvH#4^&wo#e+hAx>sSjlqyEar)Oe?r?sRgkEj@atS zy?>_v;>rXmm{!4hqqCv@&9XHNO`-GzgMvAF61f_`8{ej5P70~blIG&4e6f3El$Zu6 z-@eZ=#RG;rywo6Vgg5&xEn}a@M9Hs?!1NADgy<25^oJoo;S%DqThznge`8Kj?&TcnLDt_=dnHJPO)`Fcp&V{YXW+jR1% zq)8h5ACAFbEO=-!LG$e&e*(Typxr;9lXE`@$ci}KKfhH>eOPp7#rBwgd{|k0IhNQ$_p5;~ z76d9_58Vv_`mM(Ozu}2W!jv8E3|XO5=3UDLH%XKK)+X(?c2&#%wdVh3m-hybh#Fz0 zg#T^L=K}#fjM6Kwh+ta~is9h_Runa_3+FFay-yuYHYT&y%T0D$=gG>>dfaYGTwags zxp*RSwm%W1O*FATvCL3_CAQYVW746KohkAy(P!4AtkK{)XN1McmoR0;g4isC#)si3 z#V@>>+X|T|DOl9j%n$yCc*srmvhYwo3-+|09`IlFCoj+;%_3`HXqCR~2ZM z>O_Msd_{5UiPn|ubhZlZ9Jdbb9(_tY?0sU#1EjEDwk<_B5VOoJ4!C#jQk7(*C4cA_ z7mBL9W-}lq1!;Adp%Oa<>Wy>m(n3Up&9g+`t>1p?LXzgfkpsnVcKai&U1q9gTz>9| z<%L_h|Gfe$O<7(A<-V5G&n;>t2`-X9b``RZu!3I;r;+M_n2+9U1{iRRgg6g%tXt&{ z5k7JN?^JZ2O}nLu-|(zK_?-*;V>LX~Gt4}-Ysq}%Fqe3Bd%$aYr7%{6-(I)0uB#qr zkS8-ZQY!#mM_O~A{MO1zJP$8?_k>&m1J^=pnV?_Sd`|a5U zm&di{3m@)cRMPdwOPPI|i!fytiP*G$;d+ZJtm4PQ=3TUT!(>DQ6t?X=JL3kHlTAQM ze`<1eG(T4BQ!H(FBgVbU5Yc+U@leFX((-ZKYZZ{!$*!)EotA&{pn{Jq^3HezEBR)( z00uVFYDr?!c{UMGM=mO+pYZJiZ{^ZyM*cRGwl&|@#jz9m{Lo-Ek5gW@{P@6|9DHak zqyjWouAb1_g4vKrd* zXYd%8L52uw_P;@FOi>L`W~6$}W@AH(3n=}RfYzg}tzVvAb5PB!CWU%0L_v+lF1~9%8P)t z_|+|uR}Kp#S8PC$z9G2!^C#TST~5j$D=QSM86Ynb|NnAz{F2*l@hZ8|m^4Bui=PVI zAY{Sc-Wp!iimNw1rd&mw9w4Z=)xvRZ*FcqucyMTldmcpKg|a0L9t~`;byRL8@L!sq zLM9jVw-XT=1&N_L{Q0&+=bY~&?`4?H#KmPvI0d^P?w1DA8%)=rK2#dD?QAU0xqa9r z1w9IH8)`nmfEerS$ow(pU|6lGEiqJOrY+_~FCWCpxYFJ&pf> z%ki_E*TQL^!#sdX#nytx_ZC4_Q?bQjuP|}4GoNK;kL&q{7;4HoxM9o8wH3!9@oS3= z78*}C7vYMt{L+#P5g!ln4jtLDdLokx!CA-(lkz4@IklBI<=Z~n?qkoo-5+o9G`fxR zH5z}BdYv{N{&Vl}yHgs$a`k5EV%|B+;_uO{uCFWHhm%gCQ$_P`67+dSf!0}cmAfBD zG3e+Nh1_IG=>F-91B#&C1)>}Dq0f615KBUG0;XkiP6bO9iuK09-oaOEPntF=Y$BRE zV}m1^F=e6;rUbx7c_6;sip9s$^7ShB^8L|^D+7246|Y?Y|NB&~mv(E_GN@x3z5VbX zs~JAqy7(W{2f)pmMc70^p_vc&k<~!Aml_+NdPwx=B*woM;zx|Hifa2YJ!;SO@HJ0uSMJriGxHXxRW$ zT3qP$R?xB#=(nLpjKWm!U_*~J#w8J~s<;zq|3R-)KS7a0jm^g8<%LxJ$;IhHaFb`< z1FnwsNF%&U?zipzr{ z`dppsD)@Is??doTi?E>0m3Ecnw(#(WPZdL0Jt@mhGrE&Zz`#HYu142jkLbGXaV|5%hD6b`YklxZ395et4v@#`f?a1fI}=JbhM$bSEF zf$5yIbSvO0+1p*j&nNw{m))Uw!9xmo7f0$jW#kL#1LV=z(s~@B##D;qzcaVfzWveL zCIQhX7}RCad}d&MpuN{Y9~o2ur30AZL;$sTrfDWsVg379HUFcXouHbHi1>w>^PV$9 z<;Bbq2#NidddrAwY8*S$&RlzHyz}S?tp{>{md-MOz-_zfloY5ssz5jbS{Dv${X-p) z(4o!hO-)U=iacJ;hAXoX5)!`Bre%x?+qt_Zl%_9!bt^Y%Q1*Z%77&+xr?rsTapWft3S}&CB`93f0`#HMibT8A zC?4WYKnn@}Bzd;`;2(uNC#{0zJ|M&b918SO+u1YUzO|(4@l%5~v`MpYtPR|Lw8Wk~ zvBiaBcHk&jDjBsAZ&YCNT9~W=6L(X;Q?1v>zGD(eaY!fw6Y-H~i4&MMplu4EpH&xW z)ZwY@>uYYAfE9rVn?4Z60;dR=Fh@_U9Q3RK;sg~P5R3w9?aaL+#dXu;$xqLQnw$P;cnj zl;W`XWB*u{YFpiFU2)r$^#%$Nya6EdoJ*+|uQpNdBfa_e{Fb!Xp{AkafvC8IL@UUI z7oX);ez2LsI3Y=3PG zH2GL50x)X4f6M|riRsHuq=icH|#13ID5GG#j`6y}XOjL_htZ{Ntho}Si2L;|>Ygv99M{q&wb zeHtlRA_rz3?zQDLdg2JAXoTreg^P55s%^DCXc9nfJHPdN|HP>eS-;sQZD1pszU1(z zh-tIG#?#}eudKd~&P1`JqqBNLWw9Y0U@i{I0sAvQ-<48b+Bc;v*lNsBn+Mus0Uu$$#dcc?>~c- zQ%8n`JsPkME(K}E1g%X&2f6}`nXrJR4}U0h+G?LKlHDGGdH$e&2D zd}wSuwEhDrx+POMHf>HhK`vC5dp=tBem&JRwc}er*o0?J8GuPPZ+P;6*-s>7cSs8d~!%}jLje-Skhr=okd6AF^>=?6y4D(1_j6JrzYR@LmUGvfz9 z={=Ak0m{eqDbg}*0FF(nv-rO*E-W+$x0I?U$U%!*O-v?=4Z7vQ4dVb57JvjERzRl| z^e7tu4jh6y>G+CUIdGgT^-^F%?I6u)MHgWTRr*xRR+F+((bT?9D6IbVe(Kx{a$aBX zqyg)f(l(KA&-%Vif*$)Pl?_2IMGgFe)3%gGPW8(#oK_yFwiA*en{kuw$+@L2A(!rm5(7Q!PtaQ-J z$FcGLHihRH*8rYBrn^@Qg$`*rP_rEo&eTYI>YN8JWfJ>fJJ6xoR$4Rb|(D`udm zzkSdWjD=-}M;l=Zd1#iNU_Rdfk@Vz!`QtDM5^;c;-xsv9oW-WdN`%->hxAbsU$sT}a28KPC{9ZSVd zC+9q1lRaiv?ZC-s%1}hI@gdu=SNn@$XF$bjlHjJ>{Ti4dDc z(x)4h<$lL*kfex4?ZKSWS)^C#0&Z3Qr}bCRDm`Fh!Eyp(PmqDVjrx!OBA&4J);B;x zig-Ds!@ktwHX~c%Rar{7rc3MWB66kX5nP%>_1eqRPFsv3}A9r0nwkz&^~Zqphpk zb7{ctA;%1Q9L~vd4&J?V@lVShXr$LHE9GLvf6Y|spB>^LTx6<=1i7WJD5$Q_eU=~r zQ#o2N2nb&?aM+-Id+0PI@GlX;UaGSoJ0J#x?YrBb(6Gzz@AzaV-c;zyD(1=|n5H+J zeVlvh?XA|cC*wvv*&mst9Vcy%jz$t)7h+Cb=4vMv7wgEDN6J(G zlt=?L2o+eXGJW^GCU0_xDP56`Zm_zx0_MvHVTVFK3WCHo&fAdXaujgQ(jfQuA zkg{6;xxtYEwW}c@lFHl zOR#ofJVViKNVSB$%KnXz_SVpr%X1dUA#z#pZ`q%~x?}m+BpEW`R(o#o>-r%NZ~1wm z#L#DJ>32KWfb>JoZ7m>6^r)VkG@eW5JX(zE4y`7|yLk9C992N7(PyFYX7bCn_;2UW zLTSRLn1F$5Z#Y9I0m2AEZq=`Y$Njl1I-8;+3p|G3?5aCBLcxgwFi{0ImKhZQ-+<*V zTD=UQiE7{tRK{vibO*B__}}K#@P4C@+Hq1G z&;H+MGN3Yz?Hnltqdc91(_GwcIMqx4_atR{!FBG@^7eru4wJ&OKI_F`v4F2LKNM)= zV=J-V4zN2mz;XnMq~Lg>kkZ=}0)5+NoeY*1T02!4k&RP_+&;)xSRO~7xq4sb9_}vv zq}fIF;+2=!GHqpfNU2#QD8d@h%hwxS|Axs)Hcm&XImTIHVJU7+Y^P^d{lUvA1p_L= zaDe;6Ur>6@M-!9zUX6DcE;MMnIgty09iX+sDxEQ3;&im0%?Nwu_7`j6U@FaG2Jvx_ zz|q>GmsT^D@3&;|uM)Z6Pwm5%hYLFOd9eAP(%(CK^7u;p;0<@Hn-drOm=hAk?F!?U zSb;LT_mAd&Enq}tW$iA6j}m}2OdPdcdfePB`sU>|3UlVi!X@8X*Ngb0M)90do28=8 zpUTdBh*1T86*_@K)DaYl}BR zO6wd;_b*ivAPXo;mVN%>%;{Uk_h0<_#7qMf2wfyEM8U(N7$Rx%JvV#Ba-wy>}lm9N| z3T+2z;oUrBEVCehQ?kq9oZ_i-xdNT;dhtHetMiL=-I>L#>j)EwTK(SmHD7E8w!FJF z{3J>f*IYQt(n?J5dQa$Qt}tpx#1v7Fx()qj>G@4XQLqOOb1AMKn$hN~&-4lpZ!8Km z(UM$)GxaY?1{Y(8aS-xNVtT&iDa0K2!!~p=5}&srbOl$njYCXl!rU8uDYpNzqCxv` zGR8$9%SsvJvK8enQtVAXKX)#8(XiKi^lYL)SK5OObgUSkD?U@kOf4|e7vRE285oSKB{uk^xK@|8kmC z%lV053kxOBXSFf0%8H`mfExz?DtJLU>SP#6mrT!q8V57_FjF7ICZ+Zz3s3B?1K=@1 zZOrG`64geOC+M*WEh7Lm4BMA@HZvWTHnNDmB)&fo$ScUE3$z0Wdl*@Xabken17S-- zgvo~iTy^QVST{G*^F-!9yf;R=$Oe?MA{c@IZ{cG|rsAFjYe_B@B7yHWwikGBD5Jx8 z&`F5lh2S<*VP{*bS25>D%;-AQdmNX=pYwTL-w^C-09b9-`3 zJG_KT?1PFEi;`be45|XSA}(N@A)-b_suNykMjcqa9&mk@=eAJ;na*Zbzct^AY!E{$FvQG5WaPaqIlm>*D2TOUe^2&N@jYFmS#S!`+Vor#VhR|WcWT$8(4o!?#d;2Om+Aa|r zPkZ{s;pxq&$DvY6y2b!G5RP|FsdB`~b)pa#of)wKqUuB2)QFh`L&1VSzWdJ%o6S_k ziFVq;hl^UG<2t`E)q*sa!9dc??Sj*yWSW?`5VtGg+C@<}JrMXt|Ap(78%hY0kkXSa z4L?sju#J?X7O!AP>}QC!7JQBy=z4*}$DqB`khic1oksSKuotN*krjVMuY4wam-2}% z2$A&y54RS>aZr+W7PrhqMAVw|LV7<@+Wjbc8E6D-&xgf6>Tbz@j=9izoq>!IH#mF+=xv9k~_o-b1 z3b$KKvJcL-8iobhji1QRywzfKX>h&2LVF}tPf-yTQN%}1A`A1<+tgHb@rUI1OkDu0 zH=N1ayg-I#ycB{L8-}k;8EkBU5Vb@FN*1y@!}(9b-hC+_<@Cx}ed^O}CJsGkMUf;Q zs~Ow;(0RI$lwo&N+cPO@*8^au}4@@FT;( zwtb}C(vxp8)gML1P&vO@*Btl1)mQE4${`Tpy1^i2A7l*R>RO3!M>e|h^zp2t_MEHr z(P7?ebrBiD-sdO3A}$-BXP)IPuz1)4fOh{2-Uero_({g|a_%hHz;%Qx0w{)X0$2m+ zKKGOql+Y4B2}?8LHXU=-BYOJdPByvdA8<%X)#@0c7aywitQLV$r`GN6i>6Wg*OUbB zvjYe%EWj&=g^wLo#xE~PD=a8L!hL=8-Ej?bugD!9^&~k7dQE7Vxp+CT`eO)S*h9g~ zwFCma?=*Aq)@%ys(4S`{Cy!m9I6n;rVRo7{#nGxl@O(d+udEZ3ICEGcftg(>i;GNd zVFFvw|GK==C17N}H%cGZOBenp?n1}}{?}`mP}B%Xi_TZ!QBt+S;T7d`If(j*Dc`0- zZq<%p7`qY`F6Ry~zz+XSD1k$6kGKzgt@68%eBb{5RxCKhVZQ&p^BtLFM$tZ#;WEs4p<+Ug(5CXR2W0tdOqi<)r`w$6@M!(1yi zC}>|)6oww7OzcF6ug)w{_2c-0p9(nDRk2K1r8L1b#$kJ5RM67LLzE$!#M560P@5}h zxvM_@ia-P*ZmTFgmULiXH1Q*@(Bhy`@D~n&-hnv4vmo>AkxTWI12|n&W`2N18|<2Z zjE}Cl{l5hP9OjpoHIk^Izy#9X%VV-{G&CFYF8kqrlSNZ8NsZ|bHcK!B>yQ)dEvHta=RHwg=M)Nh4&COczm z+l!0qu~1_`4VUaDuyB4{!S(&}Fg2UT2*GtPW@{v#WuexSibD6eJ>ceXUy`)hjgUm4 z3)*YH=QwqsGW@aDIr5~P?732iBzcPt7gfo1enmk(wap2ukNKZ-Xw?Ss{L9#`5vM#_ z%z$PI4K73c@U5GL5*cJUx2h7bhu^psejN@|^Tpbld_!ho<*~^4_O0}Mc&p`#<&k%L zH;)EiOWLf6$}~XXoU&hLUeVwp`XT%{tTiC;8I}9itdpd$K*}#Cm4=Pwf2=&4qCwc? zM(sH`IB+&${o3^g82X)XzTZrWV9o-A^uJFVf@9dH^MTcDRH|fdE}q^cHlz~Xyxll@ zh=U-%s_Rkv$66QHdDD;Ru6^oK`e=6R>s+TRCu$r!fBIYo-{3j+_b(d6;wYtbUOPU< z7e7JGuBmK=*O6=dQqiI%&bdbHWM{`dSPh0XC==O0N=gv@#3YkFC72^&=g&1bW+L2T zS54_Sy1Msp@$IhOSDv z!5^h`Dlb4Zd16AdPv`$b_i{0v=&Fg_7c_P$qcc%C64}xtr`xGF4`!D!O(iZ}+3vX`p zLd)UK@|*lrnzYsA+0O@$u?>9%vgandg}seSyBqs8H8t*r`ZnXu(+jx?^@J-*Kl41P z$0U(L&?|dJwk!FW(M79##MiZTA&G2%d;+Xaa<9tVR*5T^Mt;Nbhx2>OAj5Vax;Exy zwmcqiS779jrSp^aRhRuXHV*usispO0kfRnZEPaJwu>ecK)NRoMHeAtYWMuwuDS!i+ z6S=P=eZCkiwG!9U6CG?|=ONpk}Std2N|;)ilj zpa!IZYv+5xjErIENq3_pIsvQ+QmDpa!5^A8h|(ltz0u*u=*>|i=&O86nLRX_whEib z*fDN+8KHmWIhuSG3&InZ)AAt8yt??$g?X*_>Q#jC(*|08eD!zp|A!e&*K9*YL_{pB z(aw%g#t%X;L(7;B7K1U8ALWN0toW9xl#`VPDJF0M=k7U?}r z#PHLM{2IwdYhjZL{rL3XbohG8Wfvx@gLOB^tx0=M&eC8JLzb7nlt%Z!r6eRCg7yq0 zGa25>&rmG@BgoLVn3?9O1=iPDtLQj`EeN99Tz3hm#D+SFeDo!*Y=X7v&R|U@env=| zo=lQW1L(A&ebZfyuK2Xuh=ZuJ(zVY9Te~FgC+@FZSc84cL-L2 z_noSW3zc-Dnt$89f4uy)u;3>qQ%X%3tf3M;YxpPNFZcs*PT(`N=5EIBSPrCm?{Dac z;Yxl6Ru%lEKTG`B#>7dp$%_U(M_k+;~cv{ihKcyS}_t-Ei!D^D~`P@3ko zCBQMd(}ikNcI&=mgoy-HMz$^xj>L5hc>#LkVf8$^VCQBz2Dcki{*@|S#a8wlUFTH{ zD|z>^2N~(m~1uV(m9PQNIiFOclBl6G^{WXP+BP7J-;A zp075qs>Ng-q`^S3NhiSV&cUh@#snxQpv1~4&znCe91Wj<_-bXeD{zQ4KM*@Q0HsZ;Hp zoo^2lXC@~z)xDCxz|L($x$wk61#=hm8P9dUqtJEl^_zx7>?_x>8;{Jyvkpn5I*!+w zs%CaW)k4<+FGC%Ta^7h#Zw+p|`-k;4NqY73#GG=Q56O!e5yH}X=zHYFz=Zav>%=um z!-=BkdIlpGjGdkKAVX%4WzK=>0#`mpf;{ivLp;T4h_fx_+(TwGY|#bIDOqSqu2mvk zk{Gx8Xcv`=4u-%9mj3zL;c0ZNBYKA&l}@b#rf*1`ZrKh zUa?T$jR~d^h>`tlj__M^d)N38-}d=FE%yU_{1aM0Gj9NUzgiN{5rI)TP8I96yY00RU=@?dgsEs-VNY+*?`!>F^Z^WKVEeZh7YWiCdWYZ^N! z|Aq$3U3zVAvGAvr;WbJ&b#|qWtHICH>86M(*!bArys#_dfUQ+-n*{JWoejMI%Qe{|M}BcZXuI~9+YBz)9@fl4vRWjlscu^!ukp`pRSh!++% ztbc`_n4}R4)-2|$S4Umc^sfHj-JtZ{1*YFRN}C_i@$m4oUN{X?;<9W5YL+PUa03IN zBu)WbfA6FX3@`V}`=k=ntuDjnE`fDNmnih9Ac!DyFD{=vdAPeBPIJ(RK=crW);-91 zlOeUZB4*r`Hj7>PY-^UFagWsHbhD-BrR(MQUwfv}U&H#`-QVFNaD@YG!`!MUc?oZj zCP=}pz)A|Gz?U4uIEqe!J8OlC*7jl}x$q0&rNN!|rZT|RM-Iv{-C5lAP}ab#+CY5r zGI1Q$|8ad!m@NzV-7Tw_VwA&qu|J>&tF~Y6LtnxS!oT&_Th8#>tC~$II$AE0Bh+m z3%9gn$iNV6;2h69DWH%2?3#a0Yjt0_$sRQ_)jwfqbrn+7Z>VhFpj9#-zH{r!ojbG} zM8{l?U zDB6XAo`i*_I{l}00|#J6Po7vLvV*W3*qN?bKF%f2AcZSeO~02m z;bvUgu#ywJ_<}kjKKE)Q3bl=LL}O3GTOA!+9BWl86Pr(+{{AiJ1KGJ3ZEd3wDmif3 zw;Jc9&e}xtpr=V9O9j%6#nZxD)r-_!zWZG98fYY9e;E}skP8WcXr5?FPE{4Lu^+{p z`c2t~1mx|2KX-GZ{L8c!MOuvxY1^2>iZF%lK$-JGQyBe{_WWj|G4jQu^4xmxJSL0i z0$F|Cqtztpq-oCI>#@S=?*e}V1mZ_nYaf|V_hs?9!mQ_#BhvH_$v3;I=uBZonJXS# zO}lES_eV)s)Ggh(Se(jiB@n+g`dg*%9d%l>CYhNtt?<0=%R0iB7)C;^xR=xw;}KUESX zY~Nx7RShJpz&%6Pr3_Zg~}#eyaHsO&9mR36#S@mVdfb|j7-96!EB z(S4IXu@ol_jsD669C4k4lqp0^-cRAWIMW=N_*5R4&on_7(Br@%2TNN#0!z;@*#eua?r9_kl6CXkm zt`Q3g3TmO#2wc6@SZ=v`0zDkF;S0X3r^>1_!BFT~K+EDU_ZpL&q)+NVfYnkse+F2U zJjm1#vmV?ir+^v&346-uIi-74W!r_}B!4C+)8Ookj<{OjiiUt1<}L{s~Lx*%@-39g5z>xcGY1sjDly?5vxs`aE5HIWkIP+Y9lhSsL41 z`)GYCWPP=%(mV|V9=yX;1r7qL9stAAW(7DPB)K*|OjsG%cRpQRcceRPa`XJ4u<5$M zOFl=CxVgR6w5`&oo3hfZN4e=5h>IC4y#+KN>q?F4?(@vb8O~F{{&i0k9j)u84G?cN zQb~KiXk~CNOB20Tz8zO7B=>Y;Vmrl>w(Rm;h+UE|K;HVwoytNHNiWUPX$XnNa>9d8 z87>8#mWReV+E0|=Aawbup~ou)a6eSuR`qsd$%bO?IlV#ZYo;iH<>`(4z9coc-)Ze# zewK-0P&YEMwhGl0ePLo9#w&NvZJHb|K`U!qWxvh6{itwg<7}+qlAzKCQR0Y-3flhk z(b#$;A=*T|o`LuVK}J$;ev_>-d=SQ=GvYyz0Fe$MfD2`2Sj3G4W~YVK1(%x$eLR|5 z2n0cp17QO@2cGDgfe66knL=IyI`taNyHM?hpgS17iCuqv{0-^)DnL>Joh7DTsH{NB zT;N&z)9yMvptWXd;k_9cH&2ILX(0DO5Gr6cX(JZUI z?@0Kqmi61ail^`sd*fQbodI(MF4xskFqLnMM`5@E7(9RqgD;?}ahC8OAmw%|sE_=Z z8KqI3PjsqLoiuY0CMVPQWAKuoG|Rg`d`*ppv5sRbd5ttP_G<*-%NZzKK(ooD$!O`0bYPyGK?m#`PQbs!EX9=YV*!K zHev#(56e!DPl^u8L)*n+vJAt1yhzF3e*J%fKtM$UaRrSK-ot=#3_Mh5Yxte-Prx+> zfpG;cABddg@DVsHG<~@{Lt`*LIXT(N>}ClGBrxzm{NieMAPVx{F;yzgC*-lai>2gnDp_&je|d_{`c>(0xKT?;M*Y%)%x!yKn4g#1N3_W zNDAT8QMVCYX^M6!h|X3Zl46dG~{qhJ?ymbO_scvZEy} zu1sb^;NXE|F*Fu0ZwW ztr78iPjjj|i;-7(9#yq;3c3mTxE=z6#fvZCWiAfk73X)4bG9fC-L+mV%ZM$oG_1Z5 z_tX--Met)~F?efmLvJcw&tTkV!obL=1kKX!g|Oh)^Pnb9ZrG~7t5(Yp z`{?1rcQB^4fsE<<8tC@drDk2w`MkLhr?vv*{YQ|KLWz(4+C=yxPfV`HtM?kOu9Uwk zkkm`Ld;#A$hMX71$2DjtS z@~D4teO6W_1rUkaSpg@u zmKSHocb-45d!(oL2`xYAg^0@JH%|4pKYjlED5N#VZN0db7j#|z2Uwww=k~E<3R_2V z2L;Uv)7f7u-d9zB?Nz1u+8af|wsN|yIx~1s{8F;uznAyrp1e%Fsef#B9NGJ=`);!8 zlUTDYA#!{kNGwU0uurLgT+4vKQU756zFr8s%0uh@dl{S?-vOgm{ko8l4!rEi22ORV zQ&qM}ZmXGIyda*{zM}dN^1|gUK?q8rkds`xeb?Y<)%J30dlH`OT=ns-fR(V?`ws+< zjxbeUeNYHziK;F>5A>=L2#k=F7|((v$VYeXUR|kOF#CTjopn@|Ti3-232AAO6r@`a zq(P99?(X)`-6`D)DkY)hp*eJeNP~2j2m*(0IPh)m`~Bg#dWQqyIs4gr?X`Y$&eMFw zbkI=cx@jehm&6k~V+8_w8$9po_!=m@|IXTw zC-b9Z8PBXWIfI(yPV5G!dn+fu`ApmW%?EeipQIJ(ueI68h>2A*laPd{=oF*ACOWA8 zVC&iH%g?{af!4nQq04jcwM8rVNWl=|!RijI2w5OEO=VKC2F9?Ux^(GzA}g)_C?+N* z$?7RE#07?TH8k5L9R6Js>3)9prBG<^?peun4zLnFxX{qj`mP_e1_NHnz~wdP*47Im zmcvD8q|sgfq5TT%+klzZJc|GWGZ4~<2jNW5HgFt28Ws@B4xI0h#0XI)TX+dp1AXDV z{V)djTP0s9PH6(d_tQ;Qe?0rL0*f=V`@Wabt~i8<*qX}vhXFnVkoQ>#Kyr{~(1}3< zV8{%)ckljyOzA&22kkZ>KRC{@ugCEK!~873sE%bpWuQA~-yvu%hiOsU#3XUz-`-i% z{``Q!px#8whkRM8c;mu8Q*OXy2_@}M9ixIY?FK_mtpKxGZ5cK2jRPzswl}YY>mvh; zdFfXRVA)$W_dXeRcip9mDR!%B{<{E+@m6HVHn;aZbf>kZlE`&hy{K zn^&~vl_rXrbv**Xkpx#KPh=^_*V^H^Bs{v1b^XupOVPk@&W6R=c)b6qH^5&N6+hWL z0dLsk#`(<@6GyKCjwhPo;`tJU9cnVLw_)>=$H_c>X7le~Pl$sS$)Z<|DW8|xgrYXF zv7;^RlI@?5o;_J<75d!s@o||v>Qg!5UvZnKnc3JtrY8IGR(^frATkDJ2lz!`hrh*& zM{MpK7}&P+$cF<$#oS{G)%0Fi*l~SK!{?N(N^@YY5Q7EGUB429on$F{Z_|DDA%*(I zZQazDZx&QBCBLU`SPzMah4bLD-EV%t*B^*xN$H zkL-ZT4m%Yx1*==|DWw^UAus!cRiOm~Lu^sq}BKO91$wHUUmI=k1Ti4onAH03*PcY9;& zNN?CkmfJ=QkXbs?4caXa)?52k?gCOvrWTaI-EFcsyw>XwxA2(+nV(xV?EPtaSk$Q zhMr#pufz{Tyw9{|J!TSSz`C9izqW0I9j&;HL(|szrf3%!`pQ$$}Gj6zvKxREV>93)^^bYkx zttb%d12}XLUGx$%U#pCjV=pl-$0JDb>6b1XCw)zw2(GAG0x2bp=^QV5RuAhEz3BL! z-u0*daM|zq1x$E_nzOf%aXx)+&oORU_YD2w-d%hK?nkwyEJD^=ei7l_z)nMZoVnku z5`Iw8_+v0}lxt8#OQ$cqfFWUIAf~o?rpfLmH~!Y`*hQXGYcd`~s1`HCA-PKzlo`?H zm83gAQRR6A4TV&c1SyTn8-Jt-tPo!ZFl7}ex38%Olyq!__#O0GaI1O@u$b~4yPc_c zhZ*Cs3BQ{M}s=qN>XwkG4~lm#z1MJi=T6R!@vq!Vk~ z3UqUG)2ioZVTrz^rWUb5P&(e+z2clh5Z=}GwR3Oh`vn>sFCW0#PVoE@bxBX*e=Sd& zVXsJM;Vpc=eEn-T#J0Z8kKIDP#C7wIz1WEo=#xFWZRf3xdSvTjZltREO^63f*EDo> z1x?>ity}W2u_;b@b?io9(8Pgc0_@9!Ael;K=spNPnW{M(7FcUOhzh#0Ixc)i#}IjG zxxoZLFYGG^u%409n-@45li0W%*-K>Ow#u~ z-FN`}w{Qn3^i^_jrBLQPX6XiE4x%;Ba)nTXT_c{a+{e9?W*rkg=(yUtXhSBrxaRLS z*ypslm{7`bMa;~&otN9V!P{ocUrFb@**dvOB1W4o3&Efc#^wxugAYH}mu2qRsH>y= zm^~s1m&$BYpn)~MI=236HpESc^?{F$1F=LmSiQq^E`cGV!Vj71vcY9A=tgm~@7N^~ zDVVFVa%`RIvnwpFM@Cw!(TuL;G+>k>29E!H9<0a}iO18fX_Fjl;XF*HyhY6+&oIYA znTmS-XJ>qN7h;^`Uom+ppkdwb>Cf(*TxsT5)K%BDQq<4GO5!Vcu-3Yf7t(-n!pt6-(Gyh%YC3B3Hv-fs$!Wv~9l`XpU`9f#?E68>kZlF{=sW zCgza^ibkZe*35Q03$aY+KX>~SPs-hvP3)^n^FcC7Rac}&`NpOBl2;YY#zm zxXIa@50y~;_vP0P4sTHXuUUpZ166wfrB1qH0m-==(HP5U@B3FZz>GJa8S5dG5Y!1E zm7zo^3YCM(_FK~Dx=IgO^UA!A`jwbG!A@F{lepENKPfyW^L8|KdRA%Jg8o$dq`T?H4!p zkn|!aWoEu}6(8_LXmP9l4ylz}7-yy0K6nepOKW#Gz38j=clgTUqIg-#2p6~j*sQc0 z%9WFTfS_&+sW0;Wy!S+S9Ks(%EzdN{(NSs@Fw~n@+J+1=$}(n6mpZKcjHh2TtgXz$9G&OA%a9|6)l%7D7>0A4`FF_RMl=)FSl)RekILQJnJ>>3p$f(1Cb$>Lwx}!L+!N z6n35tY(B6BoM+9r-+#8X+Nzh*Z~+T}H(> z72M-KdgFDn?0D+^d1jt2d$Tm3HXdkKt@&we)8w&Tt=*<_ggt!#6Ro1Enig?c|5WDXSHYC z(7f{spZHcQy0bhu*2mzl%Xa0PeuX`uP)f!HJi@Sh>Yml!SeYlE794L7NOdYF+KRE; z-*VJGa=u1hv*(VF3<=SFpKCJD3;F+=?RC&8vLyT zWAjumW#h;S4q^%hbcc|Tw>Z>tu)8l&osI&FK1{a$ybY=~TaUFkxs~7sJYqc*nM{&a?_rW8SC{gBgTgt!?s7SP>e7ythzz{v+;s~a0-VaAT<0|g* zJuwtct!Qpr>y1~|Qlf|Eq_uTNUxt59_4fX$6%N6jd&AeVC^0>*#}I$;ONN{Q9otqC zXFAlq0vzOQ26eNKY|TnXw_<&yJQ}4nk6SOo31(Re-Eqe3K;mu{NjkP;tJa=AaHAB8 z*l(Y^#zi*yrZaUc*@G^l2GC34Pvm9axSa+?J`~`ZsdpAoL#9H(nu+QRkudEb2m>0@ z9Q?yq?}KTA!fQrC&!dq7jw`fFXOW~e5~?uVf4LT*)al@dSWi0V8--1gepmF9JHMVRkbFA({xM?d)(H27H}Px`IF^_*W?)J4Nk^4{QP?vX+L>{2|gHX)vuQx^4#XGZR1b{ zO@qFo@l^ah9=Y5<3HyZ-E1@J(n0>N&>X$E1Q=!U*hl*}nT^5NR&_`ujLaIZ>in#L zlsE%;ZB5-wvVtA&JL(x)42s*|D08t$_&1E%LZ3l%kaL*O94+?k4FfnD-G0$Ua)U_M z^Oc~WA1XN``^}{}g+&jaST&TiXVq5I`^MZM$m@W8e;+dm&$y;jU3Ag=n?3LzWTimF(&@k6Ee zn}&dw-#5wFj|LpSVBkRw?xc_Zaa`YiA}Z@s`y3r4M&mJ?S5mOHz>jR`(Pw75`)II{ zyQ#2o&h3_~b)~Jo1s=BxvBSZA1+Y;5pn?EBV*r3sJUl3H!^_*Deb{C)dw{(Nnir&> zFc%q&s==WKTE(rE+O?{ws6RvemiBWHnIV!*&QkHW;IdyW&F4lxN#ZuP<->|4^kq;y zNqKa&E&n=x9cs?Z( za53qA7Pb4(D3pSC^8c)d-h7SQU7^xXhO`T_^yVSZ~gB5P*wtssTgek`-g|g;-eN`4W0xJ=$zD^Xt&m6)364uUXJ&r zn(nM@un zfu3k2$f@}Pj9Ju3c+$mD^dAnYL`G23F&4KG2{Q${QJNbO8F?9mA4cGn4Er5do31}pboSc9;MsuzyP<$3ri}2%3CLA7 z+5saM+CBR=FBVc*&nh=M7SHU)(SL`xm|~ih5~F7O%F4!{m09LTO+h!f#{N(89xFKT zkV$;(S>3TWb2iH*;FSA!O|Y7(lw&&i>~-EAW=poD__tSJxyuSWAyltWC0Tx%Sw)`t zLT0t=a(`0Z$j+63*F6?j(c~5KN&p5wKerpBJIP_R&+@TvgmN&}?uoK2fs2dF9%y2N zthHp2)mCF8ur7z_lz5I#MoM~T72Vl>`~3NIeEi|q8|UNxEPN;-5fOi}&5DWnVfD3D z9+v7nclOtFO$Ib(&fLUnQhxsRNyh`Q9Zs*)r7`@udfFz!8i7`==-@Zt#w@t z;WtMCAmwwncoSP6aWUQ6=aQdbAw7aQ1*eR?pXY^)wN zGTD0a^x+_NQP2RhkESdz2SEKmE;2?O26<&rcn(DBEjV zNaWb2H;LqbZAVwUjN4XvnSic?TBsz5n=@MYINIl%**9i%*_TcbySc9851X0Xe;>tN zFKe_)u1^6h&?oL*BBVA>Kr2Iny7NOQKHs)G0T@Wgi%(>axlohn-{-Ds%Sy!j`Xr~xTMmByB@h4QKb`;R`23ju72Z? zL!6vhQsu}T_hh4qphtJ2=u4x-#9T|_9H4_c3+R2;Rcc}9eE$SBdJ-n^o*+;@t(WO_ zp#S@TpS`_ygl7NJ$oI~$3a^I+4!f```>2=B*KmD&EY6-$3Z6>*+>GlEmQ2MQl<1aF z!%47S{#tKEZRcXQXHp%c833X$hTm%~;NuX6S;RgHmwJu`)XRI#P8T!axzyD~f6Yf| zVt;Uq>I6x0i$I(QO1t}w8Iz#@<~uH!7}Px8w9Y8L^m}qC%uufZmP(IOK_f8P$`(K} zGpM7jJbz(ww0m69xIGa&n{SJsE%dh-?^&=|;_hN&9@dzWK&K>zhfnnA)*Gyd!(Y4? zIyx`e#j;PZv4sAK>;Kio;5HVTT z*z~m_U(!R+dh8b8;72>}1l=z*B3iDwhEnQ`O(r}TB$02LQCf_!nI#p+_= zOS2uPY=U4)X2G^xhCX3f-RdJ-8Jzu6Bpt7@0sNk>$GWW)ZTHk8qGY~8C$V#2%${7m zxPZcm7(o}Z{9DtmMFpHi0(wS>i$jjWWYL1_#iy!{@MAQ z?2t|*C83d3u{bu*WzBGo3s@t(9^0DK!pA(-M8c7s=CHH+m7ewcNsV5e`Qc#iR$~Tv z^Mu~6=gnCLk$5lMB8f4F83_pKwE>D)U=4)17wU}l!zOXvJ)wFYp53(g(;R7f*D`u%mOoL5Cru-`$% zgmPE|c|#4jhkY%8f+3HLM^+y5ke+ztZhKqyhAhpfXyoD>eZ!dp3w3q%Q_F>UeUKU= zy}!>fkGoCGl{+dQOaor(r6K2&frDJB#~o<{3XaD03GZsYu*Jl1@2zTzWQg*$&C7M7q4nU$mhYr4 zInIPTi;f+7F@c`&E;z~nhktxL_=>Yp`r}m4PBAFeBn-@*6&*@{LH*azF5B;kUf!aS zxfd}`lRSJ6pDNT-w14NmFCaacmgoVO>go$fj;HbdaFH9Z(B8SEy**7erAnZfDurU>q6a>H% zkQWdf42+DPLQ5`!lpw-ceLjM_F6t48aW1`cvy%bk)imhVf~NY$`no0)x+022hYwnX0-9Q#nXk8-9m9SuI>mH_|u6zQRVKXc$0Pyy~Q!uQk=En>;3 zpiPp7Eo#uToDmc76%lFiV7vb{@;8Z7EO1MmX*v-~Y@` zAenDCmaA=+?)RE&<3pI%7h$jRAEPwH*hFHxqmB;Tn4==70*k8~Ehi|8eicH`kj9e8 z)jgwu|A(!A#%4%`CC2AIS62f-5x0nz~n92s;bg|DSNt2?ku!{Uf87U+wP&i zmmL9*l*bGRmaC@#ej9?U#haS!Lsm%d(m-x|57R*PVlK43?QNPBVBp#jlL?SDrQok^ zssMVSkPf;|Eg(=X>?za3x>%uE9biKk`h1UUXqfePxN$P=dzCXvMi)`CW)PN3P(2!X z5Y2Q55@3K9trNhdugHB{1&Fb#I;%tQr-M3%j$ZaF5ACly04FA~92NeRog;5h2bL68 z{zTDB(`#_11M$)pzYFB4O0YSNTgX%UC)dK8T4}(wiRY^AP@vty;O49&Va4la*Zd3@ zga96o)Ezkabh}RTLpQ?Jn7+;YvpD9jX5VmayxzQMvd6wC)(!#;A;5J4Y3KbGD(IV! zp&=5q>-AHo5o>j^U)%U^9V5=jnwrXCuX+}o6f*;xfETy>C}u_E{7p@HIW~G20S=)( zL}sA>-?aD#ghU0_7P!VGF+>B7>J?;O8US+`)ZV5QS->gOUC1b0nnG+1SZtfj0iqmS zdOYGmoTT3EB_~I<+cl;iE`vE0tzGmasV_i7YgO5c6KUq>e#7r?agHK z4m!J8^jZy|{NzQ9-Wqa!ef`U0?UyF-@GFD?c`v9cK=+%f{NxJZ9e5S-fvr5)ZlXwd zlh}WOOcChI+D+;MjtCt6d^Z(H`2^gSiqt~Ig9%KJuKXKX9jDuBNx>8vG$+D`%q^ac zIN+Gf7-e*?0g5(beqJBg^C%bAbbGA9ocGO~Ac|@1W=HG2v+rS9q)#w|xWF}lfr&}> zwgaFd55}P^EG!_l5_mL%?CuBKMZ}p7DVOmOAfA(~zJMbUAfwgn8o=(7LEZ>f2T~4d z=AJ{U*(ZMg4h2~s;^OTSU<2@IaP0E~*CenpTs-7;4Dx~$N??GO%i(WyxlFY%Z^AUl z3!J~w($apt1VkfaYV?#dX%7cn%7vc_;*>bLN%~x2t~4y@^acT7_T%H@=XX_X zIgR;FkONt-7RR}2t6MO@;^X7n;}a(^?g)>i2}ei(Jk}%#!4G_|CMPFB0yTJGU{}#D z)9nPlv3hm(B)|vHK%DG687#T1a)%Y`DqRo*{0;Qjx;7H9R-*>Rf>3-dP(mF({REgg~D@zh>XJI^at}7#J9e)(sYJh6)M_c-$%2jXk6%ei$<7i!v#>-8!vk73AbPQw zFLL!KRY5}|_4hM>u^e89Y4%NUnO6nbzTd%HuBlgJ9bXMz^G#qkMhQ68Yx332N zrg{CsevKtzC4i90PdX@PgTYberp_=mqnPu^)8ZS@0u3 z86WUO1qcLM5(sQYSwP&l#uPpPEkSrN8+D>=-JPXg!fc6l5F7&R5=s(6W_IDG4rK_I zm@+;-=7BjIHb5!H9QQM=H-T8%Ui-QdA#^Yg1+d}4*z}aZ)Kn`~xdyR}OC#}BngOxZ zFM{v;*?z3tUUgB{=9 z9I$b<9ES3G?HgJFTT}%lrTF8uNE+5evFjq&qh2!EzypAoR#XQfe6NkT-yw-7ffB{XM>8~ymL7Ywu0OsLS_83cU)%Wiaz|z$fBwJUyf_;`lzvnSi=GeyD z=bW4gFGmE!fLpT*Aj7!LdoZWVjRwIFJPJaN0X$>`JVwFn?qSc|J=+F`t6t1Tbr;iV zNl9aneWx;1S!WqZ)4GIZGi2}(h^6qLZIvX zx(9xPc^^~;fk$`RpOW3(pFb+aO~W<3>)o71cpAT6BROZCFI}kG{`VC8jpW_0Usp>? zB`Rbue$gjoE#>;U=^*ODr55$oI%f+Q?zD8}s`I|BIFR0Za5%ASZJ2QA!q^i4+wG8zFcgk%e#l`$_|G zLTCbm4V*~q&s4;5L6myux3S;r&qYOzrlM)dan=E3QLzDP3b}W3mS3!%-rwD>6!aCI z{ET+uX7r2mh0VjAyKzHH?yq;p_7Qt{DS3y|5RQcw_@oLP$w6~ci_I$H zwM{@3f9Ma!hCAO})ALCU=e;WLEakWq;<}%MB|o+NTaGODg|^E%dvUurKv$!#Ci%;k z{(hz$$}6{<+V#D?J!KM%DP#Qblf9R`yqa0~qSPvpjU80ZC(BJ2f@OQ$3KNPqlZDk; z?@Q~T_7ZGhHX&ZkURsisKV?Ypw*qeKV3A)W>^g6!s{JDu3W2P*BaWQlW6?xOU%w83 zelqoAJ7!nRFcw@diO%oulCFdhhtf%4uNzlCSQ!GaX7*QPTfkxVK=-x?V4#E)JzpRyY>d+y9n~ z3qfZHGlaWeSE)7!8!2sy%OVv*RG1)6(pv8HNuO9|TzXBPE$4gh4Fw~&gIVeP0oZtV zQoQe%{Z>7@=WH%Yp3Oeyxzfo{`be$*&lEP8p9efRAKVzVFv>-1e?L|=pi?QFu*+-v zl9WW?21lIj%22^K2iKZ*R~OxKTLt%X`lpu(Qr`F*U%YwG(`HNnP4j#?4`YkN4DJXVk5K2PwZggOMXmL@_Pgz;n(hy2xP<3x}XceJE3tv_Ud`a~am^tq%9ft*Ri z(O%PS-LrdDfM)Q^x#1(n`MOX-ih~};xEpsq&tu>jGETdshSfqH-06J2~nyZ?Q5yvCKY#;RfCT!oe z8tFh~`Ss}-EOlIT$EQLc8$8dvKv1+xqtT_q?ZcAVXK5@@Q98(h;>l`KPzHGv!71Og9M!*R5;`==ElpbhSHtgNhjY62iwn`#~~NDMTYZpwRVNKr0eq)Yo+uTCkr ziSVJZrL0R=J{-Y0wj>xwAz+L4DRsj1j>%+Y{~rUp|n8O=)9lYVgd0%Tph| z*WujX(T1Cb=GQj$Zrl`;&w%IDBf{kX9ZF$iFDl>>p%#z~wm(YLzW>U^|gJET9AT)pSr+)1r$|=2P{@y z4+F5j3C-$j(2wAZ2w`7;l^~jEv8s~r6)LLbycv{6>FVLH0}Uq7N84AT+AqwJw*8mk z)FVG%rndw(2;mp)Kxh-Qvpk&!H59y%3M{$|u_+WCl)FKxUh6 z%=(K^ZS`eFyv^=zqt&+RIsEzP$i~^2NX64ZO6(T`9|=r;-zNfnifx|trI+ky)9

XIW9-#SjrX96*6%32=Cd2zS=!kL5PG&Dn5g6}iM6+7{ z+O+wglS=q3qq%#npLs$KVgh4jj!y;A;(Y7%4LSLp_~m*7j2=$%1ES#Lx{gJ8c&(rKkMkGZ9KokTwXYS^~5Nq*LNYI-tG5j2QkV?Hnw|m5@qZiVhgWoaiB)z}Y1_4dwg-yAL@_KFlJzA#km<0#uT6pT)Am!TwtCg?Wq^(-{tf5cl=DDay-Z zP)m?2$aUU}i~mjflCrBf)>lj<@(j#{QK7$JU@o&C-MJEo4cy*{NxKZ3I%liKFPbN! zItSCDZx!kd_Vn|ZsmGr2cmv+nSpSYN9q#j#zUJ-uJdN$khqne00p?;uBO^bb9Uotp z%)D+mT@BQ!MTP%@y8y^Dk4Nt*+S>P+%Sh7tVhFt8ZfO+I339eLfP%VYeGAvXjH zw%0s@#G#2|gnw4PQUI!-r}*cw5ty8Tyk@o3&kNl|r-z4J_-<$EI&Qb0H+=49w}dCv zwBu_}hXwL5uaafgTh`F+;pat;Cj-1*TH5Nn7bk~@Ykxe6UfX7^49wS0r?^?*J*LlJ zFq95^n2fJvft>>yL=65_LNs^K_MZ*#Qlp|z1BJmO^Gb$j1?-nLF-h0=cVr%CmDy39 zZApodq@q1zr@5Igk1~r?A~C=$^-(?2})PkG-MRsW;q(Oo@I zewZ@=2y@RJtNm;}7A(qP{ybBevdcHoz@H)1l;00F`)JYm&AU)x(I;VBfPcaNB+l)3 z{hpU7kL!hy91iJNDEXpsgbs)0U(4h1--(}-UgoA&BXWkPE6ppvZY%RNv_DL$BA}qh z5-tU-Jcscj~1&&UHbRa-RF^lu?oH)qOW$K$~^vl>K>|= z0uis)_i2Eo0U$t-wRHEmpxWfe&K+wK?aA+VQbHc|>|s5o5P%<$S_Rb6qDMk-iGof1 zaDf(}VCq6^`vjjJ#8P4cVAB3-$qQ76#1^b6z`cPNL8_uL@@`Zhi7m(`yX%399^>FAy=Ih6IDs2k6X6*m{cF zm+-jS*+ZQXA%A;JOfuV`X$qOK9B1--(`CTqHxns zlc8%|X?T1DQJtHc&IheWpkqY|PCHh;lB1i&FEO2<(Ao+NNa!OK|9O<3xOHA!pPKP; zVM8=P8TGROet825p76VH6&N^9lOROCv}jJ}-VNr1q>P0H&L?=GrtmfW&Agpu*5lD( zCV<3n7txec10Dp2xEc;dmf$lQx3xZ67XfNfW^=KVcc)r|zMiJYDL;X8+H`fJ}j)!Fy3ddFhYDye9G z_|3fX8pf%YGVn7#6!p9ITc=4kNyXSA(;w!&1MTmGlE7-pP_X3kERn%UvjWC`l6OW` zUA?Ur+HT#rJCN;KO`QE`a>L!C&0{XkEznAFMg-2BtkB;r?4lz*;t~9znw8fPNfU$F zF)rJEk1&bEMT(k)?oY-)LqRTIZ2H6y783aZpD8~h^B-V8u7)>z(t9=hJ$Quj699fU zHSr1zjercW3E*eimON*h0FdG}&J?w$Tq4w$Nvr5-;?RjE;tYLwQMDZjH5y&cj zDe=pz?WSA~;d8kbSaShFTx=nb_}fPCN{C|buQjOk@dTWnik%fd%(=l=^#=W|lD9p7 z%W}fZbp(I>A=iR{P>zxXEL&bD#8Px86neOwuZ<_(@&y%7brh5a9I-N>BzBoNO^<#A znwdR62%mn>vL^^L&<7a>k7ywCd<{oGr9a?A>y!>TU;y?5-OH=#P7%&!cz<>V)HTK; zcQQa>!@g5O&hrE~pJ*O6Tv-dk`5HD7I8&2SQ&XEojGV9|8q5}6QJ^3%lMAP%I4UoH z{3bQr&F@|B`}BU_`<>o%qvFa+Rgd4(U~`m+oj6NLnN_j$3nR5$2$8@kuOO3ZG6^8* z8x|mQySw`Kx3g}?3I`befxxTvn}bM~jYk-!$Cg@6Bg4b-Efs&yVy=UAZgmM+A`elrW-*&nN8 zKtB*H2mkgSNzH4J#=;`UxtjI#z}b6ljVJm?gJJo$tJxbm?=`fBqqmZK%{TjwdQqUs zoeHIvUr!iN2y_wj2F)?ge`aeCpB1TzU8Rr9Y6{1W?c&{=uEp8y;&M3C==#Z>naW!$ z3FIvR;Wey${}d=2dWs8$v;ayV_*jRd&wG&ca;6<~$pvGCNST0Dj1_{^1w+5>vT3c~ z7ZqE&W$~hN*NObyS0z>I;+>jsI;&%K?^t**nD(RzAP(TFFA2?iQ zXg$+Ug4~w@0tEB#(32;@E*s(YS5Z%RNn@`!O0WQ8PEZ_rv4YRS@{6lQ!t`RvqWq31 z9tuWCz>lxNtFtvz_{cDU!bP+FniAAv7F!~538CZI|GbNHKJqwd*&0XVRDXzY2) z*Uk)rR*>ZhpCP3_9uej$=rC8Pc!KYsi;dGdP_XjB%dzMbQw+y zjI80q8BFSE6>VP|x}=UZmkm)Yt*p(?^c(+WWRPd`w5Uu4d-goMk=W*y`X_5l8DhD^ zGe3untW#3I$75BHvaSGe=KoIIy4&+=t59S286)mMe^&eE^rF8U@+cWfS?Ve9!~d@{ zK@7!NG?cx2#svHLz^Of&sCL0|w*eVRtz8G(V zOYe)1UO+A4n`X-8U=aEy()F#Q zV|}zjibmdTnyY2{&>=>o#nARG<^Mk!aErV=kiapn#~Tq=`N$r)ip;YX5ul?J(`gSP zuBx1Rz{)%fR~CB;=9z^#K=alm)nZ)12-BX?a@(*GP#@RsL_{vDXq(?VcsvkWcV#i1 z;3J%4vv%wHOho>PUqSTyjVHNnOeYBm37{U!K0v7x1#MPjAGp$rI5R=rlmo%(Z^xG{nvu0s#TXXugZ2EZt}WHe?Y4` z2y3|=rr6s`Zxdp@+CK*!969}7zcKk;WMFF@9FVPZU1u%NFg zDQ*1G@EIE$i`)IAJR-W|9L@7*3-5>UWFw+)bhp6Uz0vt)M=%xPN+nT4vdmH>@Im7cq=`~P#ON7TP_q;1-5?v)PAF!d1vDDqLzN< zXJ4O#`RI8h zrid?@ZK4Oz5k8fWCJ~7-2T&bXp5-S>GXURIG%6m+-s4I$X?~~1rB&Br&}9nBl>^S) zlR$?72AsQi0mBr@P=G+?1rJZCc(o%VRqbjl0EvBGHNXC^m?52ow)IIbWh<>I)@<>8 zAIJH7My*#!W4JsZ+fi_r-B}2&nCtC}JXP9`*aeu2jn#{EG7=X(7oMN{l))(RPJF)) z%~8Aeso!2p{#!cVbr;eaUAeeHd`*(N-v_gKFn^x9sat@5B?yCi-YA2msHHj9a_j2i zee^dYO8|*h8L6&v3hpUOW9A~*BR|;B^hPFvncVpvLG=nrf3E49J+fDjn*fq<04X&purYtr$Nx0nBXNjJsa@eoGH5yyTht;v!@;KR9J;?A{RlzOg z?%R*I1+v+`tb6q<2e1+)^8|ZP;&<+9X>pL>N%fcl$VDx4H@blo6BA`A;6l=+iWcRd zZf2y4L=_(9bOby6lfv|+)%6ty8P$-7pJCtS?<256vFhk&e)0O>@+`U&?ZKV_$g0Qt zD;pbD1wWtj3=Cq(Z-$~nMrN_U_Ne34=-W-BPsDenNsBLi@hUtjwO;(HF6$TO#^ifC z15~w-qxG;|y=!6R#<=y%SQ)RP<2%0Cc$&CNvE{swS3h9#sKyaTFx+;1z|B*bl_B%+ zdk%U58IX*t(cAk8B6Q2Myu}!3@!;MtY=?3~Q?;4DuzTXav1LFcwvU`(@|t^E=*u64o`1Ue$IqdwU7w zh9+Fc*5cQ41lu4p`kEQ6?nN4V2XFZ1 zvD-UxK4-HwF5Bw~E{qoCJ9I2qTmpQ~Hg8aM;-2;K_x67FBgg17$5^3RUYr)4qLvIQr8g%%#^J8T#wZLT8;O(j~*@k&G!3NAWaDr4c9Bw)-`%Wd1e)7 zoosBq??i0y_NpS8YhZoUL7$;Y<&5RmJFMzMEF$iUZ!8N+3|!=5eH>_|u+5!={&v6B zq37ZZO4j(9MHr3JaqgoSHu-`B3;(|bvzwDletRX3}k9}LeCPNku{7KLPZ`BI&ICYU!#8?z&`gpgzMY5^2yl*TVOjJH)1~RFz z`-Hv}7bL3b9BM9X8N5mzkv&$_oGB76NAie|7p!+A*_5UB!*Oho{HPgogoe+GH99%v z;^o0lR`8uiqk^d%qwm0Y*ZQRWRcea??{}|H=5l+YUQIBVXA*hYlLrh|3JY339sY2Y z0r>b5Vc72O+VyVlmgnu!^WE}#TqI1;uzfV`_;6Y#n*iC<^9#_LUz^hL1J#hPTS)i8 z>JKNUylLY>B3W_COs?`UpqUwas01&8U~fh529L8n_Jk>mCK?54a%##BD0qsBR1uTL zu|B&8QaFwdL{F*x4mhgu7v8X$J6E`c3^PjAvAR9J=S>d&@8TZAH(8h+8gN1KiA^>k zu63oSM_Oqz{zd`Ec&awWFR&$Y6L;`xhWdUzC-wemKSJf*JI$;f9M##e;Qb#NJtcn{ zw^q0FqqU^wmGBV=RODVs4pE-Y^DDkoWAkIsvVeMWAeD6Bv&43jE zzNIg!>o)i*N(9XmiKP_2ZhVg_C!Q~Nx6AdQLS|<6&dQdZ zz4u5q$>zQM-s9+xj(Xzhaewdoy07azKj){08`14Nj?einLYPkl9bXhhB~DJI`$|^v zKaIBlDQrHZlw5KXNN0c?14hBGsYEayo0cjwR+u2_dt?MF8TnLAV*Is0MDU|9EoE6; zo-#^X8$D6(*mOT!mv?jl>-KA^8<0S{sff~{ik_o%O9hRk+9D=$i zgAxoSKZ`zG8`sOgy8ATVI7;u)qtl$PA7o`d8p|kS3Q-O9*Pd@(+MS&c($%;Bp30IZ zrkIh0r=o_A$2J!Z z$+j6%x!4M6jMS65RrxPB$8UCp|B5P;A9>MJ!PGJG9@s8*y|v4X;hKBvZvuTdgar$1 zX2&Av)W2qfJF?nnAv0$@w6e|x9*u7|%HqGQpUu)=@eL#b_2X^mp&Y$U74daNGc z>sh?GR-gRi67nhthqnF2Q|*$kti8fP#Iv)kaxISvko^^+5u{ah%FR(_$(@lPY0qMF z`0HDgUJAd<19G3gzbdP$q*rr5;0c*bg=3_G4~{Rca6&fr*$eBdjX8r^dmm228c0e? z5-|iML8e3O8r8FB+$v9^dyXf_1oy=$9UE}WZ>}!JjV`KdYXxFrVraIn{!JWL^=}=^ zv}y<&GRmvbrPXyzwVH)dm~{&Cluj2lyg5wPZ@d`GP9BM-%a^*<99B#z4gcF$uPyTN zQ>`g7Qu%#(6m9qhdG7&#)Y+mxQ+|GQ0m9DSPVuv7I=-rEmtQ&0yhnz9RM5&esaY~K z?M#3u5CSxUydLsm@?G1~etC%{ML{V!T$?QiUp;Sx=le@V6_rTuzW~}V@T&h_?31jV zOG`_O7}7=bYSE1Hmj?9F7HBWO+k8JOr@ ztenu;XJB(L=9e(;98Yk4@fB*p5_{V8=g|}B@iBf0R>|Eu;%Qy5WAz=~I>!Cv|D@_S zGsTO)DExbVJdBY7z^5XrV+Z+J`7ejPmDhih%1&kFV<4DfH_g$0gGWzS7eJ5&X&RlO zYrP3PFGrb_g?Ao<3h7}|7MAF#v1MN(#S@;>(HTR8bk z=xz3%jiSr<&u5Ih76_^}*^G$i^@BEccgH{N>>+>PpWol#DnXkt+G7-~+d8&(apCUV zF&W(*&w{0TVgTQFc6N5xCuJehu4?&bACiBDwh{65m&}mjyw|Qw^0~F0yr)0OD)993DDLv4S;C<z#OB8xQycGM=Bfu3uq+k!Zzlt7P)MhVa|VAc!&&cZfk^Yy znd$w(FX21wc=p<@j4kBJe|*M@Y% zj(?)|Y<$qlk2kEucTY{uPHKNZZ`4XAXpd+J4z5v-aXF3^m!quIiMOWY5xhP4zOQYJKFE~=yMXA!_NWK@o^j%$4!{u{?w5qD;fx9Al#<&)1etv7DLvu094LsTKJxt)SP>n8f z3srCq2VEgBK5up5KweHsArHi&9AGJFc)zgsAF*&WPZjWw6rR7S9U2Z~G()17uuHk( zpH8qZ9-ydo19ximCqzzCcSi6c{1Mc+H4eNu9&!P7%;84KtMP-`lEH)Z0{*E+Yxmph zHUp8;`22XM3|Ew6Gh2_Jp?hi+owU+D*vJY(6z;6+7R~Ay4uIf}fv2?9y`mBSo+Yx$8W;4j91tC02AmLP~I7s9G36QCz@HnV_QH8kfwL}`7DnYUEY>QomnInjm{M9kOs zW2a_o(y=*llW%T%dhcXx=`BYS_6LN5!leMbDE0>IxyiDE`1~+8eL%iNULK;TaCm*z z!)*8v#$Yu1mGFnS$Ng51{g(SleD{97O(l z%r{o{p&Nb}5l5#nCzwaQNtX<4?*Mz8U@<;;nXEHI`?_z9$k^kQl{ex_JsZ=rzlW#+OAPYvL5LhJd7M0cX3h1 ztigP!pv5of3?3GvA3=2ked~&RS#oGuMkLRMPp`{1A7b7ITVZ>Lv*^{vIIu&14TDlN1~^Up>p7=H1rhSV%_OxcCY!Vy%+;{>3aUiA-E z*^st(A$ZPSPl#uC<$9JV?F)GpSDTPe4#q#%)SfJQ{imz>{r%rDdjfjw&+LMxAkrf( z?I9W~K|-Yz0j`)YuE4w;nw%ug=Mr=KGb;C#_R?!Y@?#lfrGsKGkFbT(;WP^DtR65} z1V^CwUzkHw%b>HZvlZDr$gRwO;V-6pQ^3UO#m8#I?s~`b0>91X>C2a7e}$kQwrupE zQdeWreK&Vdk~&F;reNOF~tJECIhLxfAJHtkObwZPj9ek;q-Kf4icEha>vq zKk~(7RvYnv%ffBRgI++$>C@+0JbR%KXoV43H<%dG!j~+t>2)C8lJ2`JNX(NnV(}{~ z{?DcFZo#+J!g#`B4(6paWMq+-2uw_stacg41AwuYkr5O591wkFHEb(UI{fG1_*zZULG zySZ4t8ItN??%l1IUFH93jGfw(8~Q84wxT{suc`5aBTLg-G%bZmXDx{cyImy}$2Ewe zPdPb1Rz6mBhS;9;k--uIsO%iW#&l)bBCijbK-Cx57<%%jN`(zmuTmEa17EM|yt-9d z#MASBJS)zz0(-sE@4MR=dKn3CdL4)!MUtYRUt74|Juhgmt_n59FKNac$!!bgZ{4H6 zbi2i>Q2YxC3v09EE1b@ST3C!D%~M;1qr@X=LaRyUg$xPD!yDZDSi-e~YA0aL`ISn? zga)D(bGgF8rJUr&Zx!E*Y-W-VmraBG$$ER810)+bJs-=OTmDOl`ucW57%P5@m2NMl zFE~gRTl?DpYB1rW=$B~>42p+3|> zWRad!^J&Pq&jQT2vXICbQh*&|?_Sr}U;8U83-rsj|{Y zilzaCqz=Qw678x%(Bt9zvpjmFQB%PPkj%`I&=yTi$%B*k=ucfe2FM}%vFr}Y%%77& zTU(7#NTre#Uprj^yXRBuOu^NH~*$fv_f01RQY!?{X<(sSndT$(y){@8L}E> z_CFm~;HvF<(`$)$t?n-s+pI)KMYtwiLNxDzNa2an8IJe)asBReRjQBX(hlma)hLhd z6y&0p8drFcY`!1kj#&hqXG1P+2mQFXDn_MA#l=_8uNQ7YQva~kpnMo) zI`l$EM;C5Hj1#2<%LP~S*AHQ6=yl)nf-4QxkR|P@3n&Y6HjfzsZ)^pmwFym>G)}76 zA3Y+~z!*o-O)0)@%DV~It1aztm}-I`sQq2XN@N&b;fo5SF-uwP%nwB(kM23nJ;LzX z6N#?z+%9waH&xopKGf?zBG09R41O^{BZ#Bzum9n%b8PY1)+^^YdFVn(Z}ThC56Ffv zv6q=732m`&;7e-F#c6i=G4Fim<@_Ixk1}RyW8q%!36HdlG(Ei92A*SFpRO!S zyer$^fUrP~nyQIg`*DO}Sa8T65t%zh`2JbcI+|K&T)`#HgzZou)Nk~UMVRaHrW5{$ zq55L*kJZTT?EM_N`$m~Rh1qoR2q(!HEzLY+1OD3hdgALvC$$L0mNob2=sbt+K8G6F zKT?H)pl{~jYdxm&{P5X)<{t!A3x|XGc)yo}My<{iIpy_dChT8x*Wh&vudI9wGy1}P z8M_DfK2)v??*)%iR*+csVQc;{%{yFvUC#ybT0DO;gYYN&BZ#+B2=>n|INCdI1kBE5 zACB+ia(Sdnpm!{OLHULzN#apq&$E|$NFkr|d%pSIQ_zOZL&F1DQ*A5Lnxre|$22-` zrfq?sY09-`C$yqmdzjcAz|kWc_X)MXQ{3ys&109W&R^<4%M?<_3AGQ<@*2 zq%ojWE42I8Q+fBEf6{IDi@fBJjT9hNNoJJ9&>9)XG*Kwjv`aJckXWU8a+aO<4~Mo( zBA(7QR5Ep8(5$MeVP>|k@*ArIE3=8UBgglG{|{A>=qa+1s^=UFPyLP&lw#qcKPfK$y6w==(@s1izjCHia~lrq4V2DKLN;S zn-(fZdm`8UtCzofEP^gZ-}ikZ0MzPK!C1}Lp|T%dwuR}eg!sXgJvy67!WR0;$;gz8 zCFQ86S^r5WM%DL+6_^^?f%zLv^6<1=yomgwRU@Ks8$!ty^ ztezdPjWlK-t|CXpPA#$e+~?p!x3slgz|kNPukD3gt5Sd8YFIqsZb@+`i~JJ-ZvjRN zE3@73?zK;OeobGdb6@@xcwW9u#_J=@YjT6N6XSOPT;WquVzyB)? zbHkb&yDNIXSPU+Uyt!q7CyP`MUO}_6s*O^&tFkNLE}MD{hWgxpWbL)FAU&CC-?7gaQKk`Icy4V zaQ&OXV5Y$FiN2b&Dia4sZe^v0CN-9}9$C@Ry6UYdYjy8;)>4v{sbc2Lo#aMCinAU5 z^)qiJ7UreT)KbJa$g-`C1J7VQCE)i;&BY$|Y-7Vr?(*s>$2ZqW`&}1GRXsgL8JWNW zNY{k<<(-$0j>lf#fHpGkOYjTs!&4(~;zq5oD~3;_3Xx#StPa@#MS3j210qI%eG z(b2Q^YRb!FT3cJM9l1p)sKucSJ6#{lHO$T0{+)$<-+DNEGIHp1zvan!pc&_2t9mt!DFcRXX;njnaTaw!OQDx(H z)AT85U2t)6g;=jIeVt=o-&{S{V$fL3Q3{zGNR`K^_F%m=qgZmJJp*EqdS_beoBGtQ z{k{Q?P%t^UBU1I2dh-4p6p>xtNDFK6S|boxe2bZBRF=+$zr2&f@TC~ux#$;0*~szi6M=(yifitpHq+pI0 zjU;8p`cpI--Sb7#6IXQgxYnq0rHfE1F-D-TW3a&; zqF4O=YX=>XW+#(p6YMw3<^JqjC!04B)t{9ZG_gpbp@SK;;+Te;4No3)QKXLZg=8Pr zc)O$D|3v-+7FJNiBvCmaMFIklG-=-(OcmS%sQ`#hx>h7&vV-&Vn~f`4c4}z-4pG^7 zETgBaUfacW>{haA95VLc|t zz2p1KH&qkul2nYc7^^t4RE%_gZ4jwg(3*u(pBQL&VcFZ0r+gVew6IW8md~jAikyGn zOR9*Pbiq1%H%Vw2ZH1V}3uE(sZq~@j6HML9rb?>)m&XndBW-N z_O!WUdoR=b^mL~RrrnLpP=0+{>y@5{S@8&Td>?4PBY%67jJ#=4=QOhu^@UnZ`tZo? z5l;3P|IE%_?g;rR zoclymZ_4p26uCRfq+YmIJD!AQ)fmesIxB^J6!x1p5tZdkXn7!mE!1Pw$L> zpKF*M`k`MKry3ISgy$uGkcByRjmVRv_%HKro7Hb6x7>?HpXmFS49m8BK*ra9{+7A^ zM7{qO81zvliy^lFf(8m25N9g3J=O?L|EkkU1)6i&#tVFVzGa**i~EWbg@9nW@}^?Y zcuq({KzJENb-{1KAR`PnQ8(Nc0#MRAdFg^~H37GpSilFHmn=7W9A)!Qd3DbdyWV?7 zC=Q3*&F-3n1R2a`g`eYpNJwbz1If6@K`l|eQf@dQh_F9T7cl&{a&28)TyBWQA$ez~ z>OIQ&up;rlnMnMSzMUHMmm^yxVWUps0WWT@9G&-_FLvIq2rzssGm>AAUDp)8AAR3b`t&B8zx{oBtxiB!gm7_N#K@ZK@bolkTwe6u zZ|?PPipruRziA!zTkcZueO#$1mz!(JQAT1xPGLzI715O4swn~&mDQ<#oBS92tNZ*= zU3r|=WBb#~_dSD=ai|>uQCmO%{lq7A5kF(iU^p+ycq{IIa`OSbL&mQIP2$g-pC1m| zg4doQBXRSBijR-aecTGtTW+Qe^>)G~YmpudmW|fCdMHT}cp|KFMB1n=f})J^o5@Nh z6yZp13w)qHHV%5g*C2I&VtR_Qo-nx4B8}y8Jg@z#eV_JxY>$fTR7C;f-&p{{=%83z zFGrj21<+IKuKvB8_pSffMLAJ6C@MT_#urAK(Hq|a!uMB$(we-TmK9fJ?Z!~h>W<3A z{ke-Mgo};Qda)O_;3FY%_vT^&``@&pfiOs#G{cbuE-?wm*;o5D9m}(QQKi&^oW|z0 zoiEL~7u69EJl5r(N@)CEVO9#sK$0V>#w6qW=B{VYce*RAy5Y5^P=@%0S8-H%CsW@j zGPGp|M-6|xcCO*qWH%THrWo+}KYemCea-h`&h87OrqJYzdEo)i#1=b z^)%(+iOVYO?FC)gMhw~-T+Cdu=)5cm0k;|gP}hF9(;=~CwXJoyb|V*Awg!fMjPKTO zd;$WSOyVcEu~kwS6nu7*X<={=%Dld)-wVZESI@l*6%)g}XW=I@hauOAqM)K~LCqs8ub#3i!1gbk zE;#k>-MA%>u|3lxPT-4>jqnceSHKFbQ+lEO9RI7A9zANc-MhM1OIeZW`KXvro_h;i z?9P}?w!;MIb$z|}fk=6uT97|KDcM;@QFvyp09;m}OL@DiNWO`M^qOW&q619qO3ry8>eiYS&e(;l*Pm@#2 zcpiK!F+-hb{7<6cUABfkZ*am+P(-l(qLOh?$ty5lD))8rL=nN%_>xneG6sx|1X2g! zk(d@7NBdTw)8XfPjwPKhJ?k?xNB8+WjRJTuIjCHdmKFKR)nm7JLwP*C3sBjwla&!S zoWG3jY-rpJB%_NE9_XY`SpCOT45Zy3&|$_?34ZXDLzM!gCUXON;o+?e4<1prBGBLC z&}Uk&tmcE^eWIvAw$jv&@JxAx)BV}Y@qIGNZ#Qopdz$Yo=0(doPh7imaa+(K*C7{( zs;GX7VDti;XD^3o?%$)qWqP4&4}ncOoIAhG&Z2X~-#Y5*y~(Xh;$>T?!S>ZslV>RWIzhKEtoc2BW*ZxCye>G_zA1^On71g9S z=#w{y9etd9wfDPCQ$Ebjp1|S>5qki@miv=Ca(qwbmIj1BH0(!F`;*u7{>wde}3aw4&@0 z9u*|btQF%s>v)B6gZ6yeG3^qYoBF(#7#G<&F_XQ-^6aQx9GIW4C!Wqk+7lmze{6U| zCpa?p;?nI3d^q2@ zoHWf?Kkjs}r9yCXqXAdcUFyY&QM%UYi*3XNLxuJBkl$gU8V09i;WE!MwKi=w)A7di z_;mTWo4rMks{69O7k$QgL3?`gUu;*U0!YHl6vJ#kpmA8&ljiO7aNXPhq1=`H8WkGjlJY%TQQ&YaB#k`zr}! zKTXEc@zK$!goFv|2R}@4w)RgJh~C`P)j5s7pqb=zG2h$#ck3}Qbzd8~6b~{hKY*@1LExt%Hn(?)O ztLh8X7vx&6i7POZIvmdGkMloe4Q^!R=gYe}bb~@%IB)Gfx$pfNZ!h$Pc)wmYJO`5! zNdo!z*0LDIkO!Aal-|)mP+j%yo6=agxUDS<KY0!u(72f0X&^vBxe@dB7`-ggImnH?MVrQ5 z71zU04UW2@^N6AM#$#k$lj~(=@F*Wu53B@*QaasBQR++XF1kP8)6#~SBT%)4Y-nm~ zdPC$#5lMA@bxPZp7U^*1sQ{7_au2G@4KYc#JgnHbZ%m{2?y^?ToHcy?K>u2p3GIHO z(i2`6I(eJ@=HGaK&6!{L;M#7Y-iFoi z^140eBDM!)Gqw&$tlul=c5Qv&wSDT=&(VzkY(+{Bz6S@aVfn3lKxt9}_DQXNTq1C+6jant5Cy=DBP> zTi~j?%pYDz_vGGdV*DuP2C%~ymtR20m2GR_=W{Z}s*CdtrrUy3g3$_m(AUx8EjGQb zKD&H=jK~)mj*~=t+U0PwxL@8zlEjN!k+CtdBRW;UWZF??;xFKPc_3T%Tu%O-&xy3) zjkjG}U^K6ZWFMVnGpqXAQCa)u>Q+3V?<*nHM`*EXYPCWfk<1Kuv0|F4@AE%OEi6wT~!RE&7rD~#U@|SY3)l4(yg;F&D8Z5@xPmyp0QZ`8Om3hw#SV{XXJUT-59RN zN!;#GQ>bhTmN?s>Yni*B=lXBGRG0ckJSvp5d=Da1yb;Hlqi^#m@Z% z{q~%GPxkX%oeHs&l)N7>Q_tIYf9fG{<@)O+=h=JyDdg+trloDvhl@8aliymGdX!P! z1QsHsdY4-^1XJLA^4F-;DlLCQfBS%PR5cH++h(z5eI!}2beb$}11PFiTn}RE;%h0* zIHtWCrwjp-%BglV^X4lgGT&i3YR00Gkjnt3bcAZ-sBj9bur#5JvjfkDk&+i zL$hsCOeD4Z)B^>{>HAzN9|9PjjrO{#TBYG~CgAIgU5OOJ5yrTYP0k(JN9SxubME1$ zLUWHRSnRIJvm)r_GF~@dKMHQVPr-!5d@@NJoAgyIeh!FinEVv@R$uF*YLzHXU*DYq$$Oee0b{p-fr#S zN27aL218O9JAM!+N5hccI~`0>oztbdSM_s9ml*(FXOMY;1ZuYV`rg1n4@pFBG4na`SnyZYVto%KxfPlFIvi5Zw=SdotRL zKa_Kym+Cd@(vjT!BO4tJo*SGj%Ow2MbP<}>_3(9{5ETngMK9CaY^KTp$xmL5tnPI> z%TA@!YnideqEqR6EiW1@|H_1t*^{XI?g`?uLDQR z(z2Q8N+de*0xkCEQ|0Q!U`ZDgs~_?eg-Hrt^kl4LIx`LN&#Iq2uKNrZ<%ZQK&`()8 z6ydN^yQb^m?&+56{{880V&b>!rI1@k-tFb$_g4PlN!-FK$a#vjR#-j8GrE1TxG-cr z9K{=!Xg`Z?5c&VrdbE8JHmEToL+^;VVjTTLm1vBE*;io1@cE2hUV)r&STXptDuW%$ z6DH_3NndJ9Xa3Jq1;OLnaXQMR8Nxyb*evALqw5xm4K*w*~^Qonk9 zEJJ_9^qY4hJ*OZvlUizj^Y}6HUAqI%7dtLxvumamUH&5YH2v1*-fFlTMEIpv3TU)= zc=fDX%w86E`|q&YvW~Ln(KqrvJh{hD?S-NqAF?X{6Qj|FiP7-ZjpL(^_%mQ`r7 zR@J*#uO{?!Mn;r?0ja1y_5g!&z^^P+b4xX=+bs%!dpR&rH?lzp&0I{l1d5jK6Shx! zy=QJCCAG1$cD8de;f;Y>Ml7M3QE^eyFDyx9!v#VOT-;4u$F0%S(d0w6uDom<96HUp z^FLb&-*yOs$FOSevKty6a7SJp65q!ZiSoj%3yP^+5M(id@wTQ1m=IyWp^EFD!20gO zs^u$D8PhS-wNJ!;zlsR5!Pk-d{t^X+S#<2w_JZxDquLg#BJbs zfQ5FAAB`Z7JI1Dbv>&1*iH2Qo55*>hg` zQZPz&Dc4upI8CyVGXziCA}uqPr2*=tDU;6jwj>OP1hkP5=wIrfReM>XmW;{V;T zTVZxIZT*^GeI+krTvZW%v_e)7wIT`Je>@NmW&Y4wDH-?`Yb8D7KG!2Je5sMZn6wm? z+t{d4oiRc;M0=otHJ89$;hj$BF|b`~{g$p+ON<8AybJ~)jc`{(y2qH)I;XYpgJ~&4 z`{MF)GbUGU8IHquoY%?S4dpDg=iZ31j3FPRcReyq2<8**Q#tR*gya6Y4REW(z5+5r zc=)nL0SCQCR=aW}(xe^D+Qyi+G;eRR11_G+Hxy(kAZ~M4_=rrciU{M*4{UJ)ftoUDd^|^#oZbpH@X+Ws$q2qlDZT> zJ~nM>b}Q6jf*tv_{QJtsckAkEdwRNsZoJDDIhZ%OABf+(TmDfo#v1)YDU$!_skesR zP0jE|7B%({dPU;50zs)E9n$2<3H|Ky@*kDts1~dlUW{j*u*gMVUl$-0xhY?c`8Lcn zc+|W(m^eqBeoy63-7kJQz>I~{|`5f=$qH|XmPlPy)Rh3@gGqL!8dP*XB$EnuX zHd)|9e$j`5N4k$#QM09sIv z9Z!%HMJ^db|0nqm7acJQ_KziZs2bYVt4!SVY+U$%Z98=SDKkCRu{o+*LiLQoN6ng- z3l;pZ-EN1bh9;1{iU7zlW_cEBVNtTIh3;T#T2D4_Y;-We%VepJ^zfYz8IwTE!Slv zqyUxBFubsy)6>L|co=eX7mMKfHyYM%I7s&M&Ceda*sT=|Ux|2Ezqeb5VA=<{BoLgM zXx5%tS@+`f=r!PgyUSI)r=nit%|o*T-)Gb|2@890;VnpRgwwqj^5bd>PcwU>Fg2uS_nl&_74U z+J>MjR47%4YIQAStV8tTM>o#0D`ztT^T0=b>~uCB^fcBbG-R72Piu7KvU~oIk?!99 zx`+7q-rdRf68hy&<+Oq)Hh(@QW`3MB#U>gOi&w!k(xpm8qN>k__ATjm4Kq^m-BVKi z$NZ=H`6qbRn7A*|so&7MdOi%qM_kwEIj}g$-i=jQ?tZ!))M3WXX{N-J$rH+TaQ~_{ zg?&u1DBmY0-L2U_7&9~z;)-v1so0xvWxS=u#>IVoIYugvllFCv`f_dDUM8NE%e1Pc zy2#k(o_Y6RJPH47*P7M&r2VI$@{fGn1Z0(bZIR*oS|X$4AOd-3r~AoL{4UBFFwz z8OWvj`ZlGVyd1Y&E>eZ@*C)A@vMkzoN!%iUg*qS@4`E%#nN&=HL-iq{A{Z?|GVAH- zsgaTwMQ#c*i`(uNy}#vr&#;SpoOWIz9a|l}my_z~M_n!gc1KaCxDLzzc3nK#N)(y-Q85^j*IWO}c$qytoeEw``;$9{ zyp{3n0BO$j5FK!D)yB?x)-JrNd*5=$Ri$DJagt{OyY^_59ce_^!Zsvqg&z*GWiu^H zlK(uT-LN^6Q5ooQ`UV(2B}7*4T_c4BEwZq-$0i3cvOQ37;db!HNyuy?_~eA-Ke?r6 z^WfAO>AlCLW~~oy(_1A@Dq3WV?6)5U)1&A~x>5d+FeeExnKOuCt3)h_eZ^#PfS9MlCt+HKW;r`iyS7T2BW|Ux zwEhr6|Ej(v{kQnMVF#`Lpj5m>JOK_`ti^j@O%12Yp2^PytjFBr(+JOaeOY-$ zb^kPY*io3*htYLNe94GYuh1h&m}m`FB14v8L48nET8I48rfbi6C5m2>0kNgsW3>-s z_43IoYDc%!KS}m(*+<>713ga_yQZJ%lf4YmbW^8_EFX0j? zTihIH59`d&F;+U6f3*W|e-Z2aKwk7RCM}(uj_N*2z+I$l1PSKgY&pQ%8|H$3)@+oF zi>xp4*b(q0sysIf}T*?h~#AYu3F6+x)RinahKjX~vJF^pC21jx}?ii9;+T z1G7o0w^m{$pF@hJq)GZP!;ekZL&!WhNV~ZVa$oRC0Ivm)+aC?^Z~!7d#qatIJTW(G zLsD2B=6q^()19Fk8$6#y2?`z+)KYC9viTD~Uw`$@v)QN9JjJqiJ zf3fnKp}s)&QEl%P)R|s8Sb`WkiW;V@PQRNvKGuC616Furh z*$u3ihjLxmNb*`JOcHdkUTv2Za(ZfHG1ECIJR>n20Oh2p9q$h4-TO5j-fMo zOlo6o4Pgwx-**y#&e?)5P*gGQA%dd?P&=zTx#(cKgM<(&dE9&c?*QBk((ctYc4lS? zSm~U^fcYOCA6GLlcm}F)P#r{jh0D+ang?bl6nhWE_*q!OK%U+Gir-;Y4p8F|WCAX> zKs%ymXbZ5o@lb`WtgHZ^Pf%A=T#T8}iyVB}04^QC@@E^tXcBx^04e_tA<2X_daKXC z9R~&!+`5UK*Xr8ZL~k6Fl`-MnRaRDl6c+f$4|gA+bGx}Y!vAb@bF;hrqhU#IaWT7# zW1>E@e2nElCO;A+E?l2kvDYr%^*!HYy!F@tUs)WCK;RfDEdCw}u`5xXoib=>=+1nj z2Uqsm(Wxm2<&y7MW69N`8n~%zBoQpWo*{pQEIfPhw*}N&bw& z{rg*eJX%YzL7ruZoL{NFB);S&_bsRFd^{eW5++QLJ(~&$a{JU0VgKf3xah3(H{1M ze_IiJ8F6uO@RlHJ325FUjV5U%{|o@dvAM_tLTK8-2N!xlZ4%Hq2Y7-1;OxP?^;J=e zF_oB@7&o6VVma&4N~9P!u$mx3;dZ};troIplE6R(p+@|N5QS21Kf?#8<+pi3M+7o6p?qw6~3{fXIV_Lyh5rcip(%pf7s)NCBaEWD3^gf|2+6SDu5g#BS3N$ ziGEm;`hCpPs=*-CeS69pfz$}<8Gh$`Sva}B0_JO`E?}K zVl`A^Y33C#$epyb)kWOdug{K_{uIi~J+tT@&6fk-@#dnx4Hv16!%G@`l;;Kp{gAIL z3-kmA0u6q5^LHq~51a5T*nf zabWF8AK3)b2>f7!7ZjD1b4p7&O)JLMT7^6-u}uxCKQ14vge>fyfCe2b_;f5R=+dfk z^70u_+_^YTS_NJi!jin7HWk+lxjv8iZpYL#-Z{!a^E)}U8SiTSF(ny$4bErYzkeTm zGxcj>9Rj?*jNoZZAqDuM0z?M#EmjUZ5Tb<%97eW|VINYm#1m3SZ+m_AUO=5(ahx<{ zgK9arEf~jNc~Hgz(XfF@ysS9!%JsseLm{I$D(;&(A{jh^zui1BxhX!P@-U>LO5Z=4 zX=+u3q$B!IrMbQse0KPq1f|mrG2uV8T)%t#{Z5BDLK!GwMHL}{pW3IeW_uTDXcIqh zGl*-pmhm?${#NLj=2@H;U*^ar=duNn8M|j{1d`N~a>Hd?i-&il5dLz`YIJ^arY+kn z!tWp`YhU=0BVJdlZMB-1(M6@moo{0k&_^w*d&T0*{8n3)iInSIh*v~rT~Sgwmqp)= zi745GqlDu)UIKns)5cz8wp@13*X4sZr+;=zfGXNu-q&ux7{kf+4z}Asiw9;M94tDG zo>fjy|DQYh|GY5e+*qi{Wp-1!EzrO=4pjYUu%pAaO*+-y(bdIc(uxFLQM%S6;A&%| zeSmZj@U_MIK*}iGJ>}(56%*Jkz^?aJ;6M}#dbp^9JPPfm%Wzz zlzr^=+wXhVGSk!F3cgx@uBnL}{GkOr{AE*iuqmq<84W_Z1#yxNmhd)bXT-xWNMV6s zH3%<_h73A!J1Ut-3K+A_+2Fhb#VZp&4L$t_@PT&I46GagXjsM6lm`6EB@!u!R1L6Q#K>n3p^Cn6_oeN zL78uD%}I025glT`7<=ArX0vIxD56&BzLM7o0_o8g#?|<;03oX2muiX3Bp`5e78J1}L$B!5vJ!$1b zet4La57!vfh~YMZh@ zbQskbf3Bs~`G@y5M_bk0%=1rvu1wG7A6KFE{$!#$cW`==yU#jDD-aZFmstLcp^px+ z*q$r{n~)s-R>h!b+ZKTt@9S-yTLV9!2btK|Zu2Q1edO`sEUYzn1Yy&oBgQzKvPzQ< za0kBCEhzy~cQDBKKE|Vc@>D--eaj z)bs`D>17abaT@}2xYi5)s+B&TL4b?g2K=0PKfIjJmX8(qo$gOF764mujT{|>C`7<} zOctjShm1bh=2&$~sg_T2l#*KC-KUU)It>J3W)Oq{Y!1HV6U%{=kcB-)2ufS#@o%9j zXRQEJq!XO}5W~a7%)A6&D(timC@%0q5**RWnH~6^wqRg8Iz3p) zFDY5D@dXARBm_Y!31od$+fCg?8HoRB9=bXjG=X}jIWi7C;dye@+ic>*M;)q!DdJg! za^(~4b~O=$-h8vygv$hoJi%EMh;I_DIsfQbCvAI*PUtN$rG z`?=wZpG1XP8Ho6)5oYBTu+~b?z0HyRy%BYA@l=OLm?7<8R6f>PXb~ZByOE!usL1E{EvBq-yJ~1lM4}rSnQ{zdFT#P_be#mz+hxErBk!(_d`}Vq|7-WIpm~Iyn z>{Oss7Zgl7JK7kTepK)w4y18l08lqFQn9gNPUd%9hpjH`i96V7&CSh$NC3<{Z^(m- z_S)Lo5`# zEEEFmRlpu}f(c!x$y*Q}4;iQe%{nn|!4$+8kXhok?*(PnB5*FlPNTr`UZQO6Fr*=4pn+4*1>-0^XM$rGLdJk|c z`!{_2vA1keWGkD5BqRw*QQ287RI);nJ(G}(lI%*dDp_SqrOZS|Rzk8BW&O_k{r>*P z@&CPt<2~fLpXa`x`~G~cah~UOT??O-2hnP{8$AlH4QPs=tPZiUf z-5cU8m;L{QLk%DTMlwg0y1 zJK1-(TZ`jr>;CNeFx$$sSuNF!<`C%n8Ejn`^O}|~{OQ#7%8L}ks3=$d`t_^)U|**@ zx@YL>>PE~Rwl6QORElZp4CLugN-ND9M?C^81YVn1Y^^+#f`N0Fp8i|iM=#7mD~I_< z8-H8M_{deJOXSptGijhHM1=_Ta?|-kMnrM=-kGvdp6YnY7;B$NQ7C}XFal0p9*sj3cJIE1 z!fm2@eDTMpQLKXt!0bL&EL$6@{ov7w;SCL9Ht!hTGBNkBq1svb<*Uh}-t=7a!w0h- z-dE+jdR6tlw9qyk6Auybg9ii|chH^DIcR<_!ASUpu-bY7TY25%dHQq)ZmGC)9(O{7 z^n^xOXafdgT4tLpY>wTrJ{FXjUN$h%KQp*F%xxKt`TbRFrD(F1jN-wP$*YC*0kQ>KxT}?PA#x(_$OZ^R@PebJZI;=soZh;!aEy ze9J-)5X;JmpaXZAwza+4R7WSdnW%M0Nw` zXC3`S-S>AK-n*4uzmzBbuVg>_K%ubDzsA?ee=e5pzZ}ZPfAxrSpLFvbDg8{P6R#Xx zX_QHnbOEG@gdU?%a;L%Nr@k6@?rF!7A|<{ZdHQZmh=)z~g|pvP$;Ahi4`v^%K$HIb zy7En>ODqLr<^8|@zWFowW23rz>W~!Is9}Yyr|`xHuXY9Fkc{ee&WC@i`2SjPZGY3) zSKy#XpVuXkybb+w06A+@=^PF2!uks|cLTd60eC|+Dw z?y=eAMc0NYzs1I$z|EDI&6@jrE*70@PNW(bd9&o6Vem7(A#d3guD zyp)x$e7luzS!(a#Kzn_8Ce$KdM`b&;uwDAQy9eS9$n0g6j6S$E{$N2>sK>)ardWOI zNGY+gPdie&GFw6R%buQ+s>ub0z${j>ko)IYPK7Yrqzx@YY*u4k=Ur-&tT zT<{~i`*S&Uw#t1~r19Qte8ZK7gAxhfj7|q=3)OymbG`lZXGmQV(=#&2rl+TSUSHe& z(04&^>Cc}L!oj0nlXIUypwtN_^B*Huw=1uDUQ+YC!6-*o#2Cf1EtundUs9-F<;Aq_ zZTlJCtBH53TSl$_ik@knbsCtc%5^am-&fR@?AP_HMr(b*P;K$!ZWW)UoeP*Y(bE%g z`!+M8$DzODX@{?0-{(2gANl;bg7b(_T)_K}A>Z|_$~XeH*L+$yL=|l1UHR#4=-ZfR z*NlaO2W!e-xb{rDzB?=Bp-O!u(WSS0&&4vW{zHcXEN*l?lqSXx?9+C2Lh@_|b<&bD6B#J*%p4T{-gZft^C3zhk7^)`2A z@7P4)_tUl^zx5PeOU6i>su>u_O-zsdbe$R8@_Iv6TtZrQ{6`@Z zlao3xj$MqfDjmz{NvyrZun>SE3X|J1H+dDV7xi4F`D&n=q8rjFH8#Uu; z?&cmF3$o=uZ{xeQ&%^9F#i3!2#S;1)$50g z(rEALk-4rLkL ziiu&UyJDO^T$)Km#WPsW{%glZ4b%4q%DIK+8n3GQ>16S}O5aE>ew#ck(|@mjUu)Wo zUYotaw=lTIcCWOIL@F>*uFAP^aZKMi;o6^PZD(J6wJkP_xIOjS@1oCr20CH0R3CL; zQ3>k!0E>Jsg}m7BdRaehq3P9oed!!V4@&AnVh(v-Yaqc!wj$|oyYqr)`HfBi?9WPbZu^Lq`vjqVrox-8voVqHKp zxs&>yfli}W=bWWNF2^2D&IhlC8@bDu?lr|wTzNzFdVyZ~_%V%7Ia~AdPs`o&SKA(% ze}jX4bDXqL<;{IDX{X@&v~0k@^%|C&YO&2@=ml6+BH!jzPBZj**U*&>>f<|~aQsQ> zzOpr1^8lGw{~=bd*YzVdEaOt|N8xtitvY3+#_XeAXqF6akpBS4ru`98NOG!DR7!t)D9QVVi*et!v zDbkH8ygo=SSp;4D&MIter*aix3+$W}`N=@48FQnnvn3vN2W$2?g>U99Ow^$g52U9$ zZt`~hYjJQV$uhrYPOfyPiWl?Brz-)bHe*V`-OtFr6qcS@|7Y;IEBAmzrkA|c2{NW? z&ZtH_=K{Ab2bK9>XJTNxYhbjlR5PvhRlA11Gb#LGUve{wEFp-!&+t~@<>`>8CEJ$A zas@a2tH@e++Z;A1JS6S~F2=;mnej z$h6qWSavXq#G5Q>B|IQL*`>%-Kzg#Y*ObTL{>6%0Q@%n1Y*vo9@@Q3O52)@hoP3+G zbX~KPIh(O53=VJT}zYdg<2|l8j&flb}dtE}K;!$_NiA zxfuA<$?$|rWtj}M;@X!Wt1c(oX0DmmUs7#f=@gYI1_o-%xoW2Be|c;_|9HD$B-g#E z#H>GQezae^Uy+^j(OvT^3ORT$^3x!{cR}x2S2B9OrT2 z4yAZM<|ff4?noD`_fU$|pX^l9`;wI!!2St3Dm`x2-Ar~xv@Nk6x-4j7e{gLevvCjR z+^CpheTH5Sn;{O8l@e=(Kr# z3%^l4KRkDdqmfDf*SaB>=l-O~UzvGKW=>57?!FK({*awMHIBcV za`or3yJTBm?9bH#HtJ56zDMzL$<(Iz>uftRMGLzn>4Q5N6+>zjDW8FzJNf_q0>$Y~ z;$RCLTqVGFpqIJ9UVg;hGMB?P+3`}(P~+g{{<)3Sn&J8y{|)iEkGuQdP9O9Cu)fKD zj5N5ZJ~va@e|{yJKjkGGwXE@_DNl;SG35TgZ|r@zZYXnKXKAHH!*rzEU+S&Rn$5kP z68a}iRJJqYI=At z`yQTL6SLz#qAp*qiDb9hA6%y;!#Vlyw-t}k)ji^hiSNte^C~Lxgw7kM3o$0X=i=xK ztAFrtWX^7=hRoLY!D`Fq+NSHBz-@ZJ9kTVsgcyGmU)w$RBL$n1ex^E2rF&{E5rGJ$ zQBh2{76V9U#pS|rQb z+~mp&mI_--UGusrV$^;1JiG2N;q)h?+h*MJy}Mf(ZT#vi&6j79S!F%9a*jmBCN#1z zkUbVl8n)aLnkrjcHz zDlebu;Xj{-EF%dks_H$v>-Qh09FJf)fUC_ucF!QuL}*_}tgeWoFs*@jL8d?~zwXrK zfF-uRj_2kt-|jj6P1=a(fpz+Pi`e4p4`Ze;w(MV<>-u#tD@*g(mQuNug(EVR=T)Q* zUE7E+p<@)Sl(zM`f22^qT!%z#&~`Snu^&H-S*bhCirQG@ zo3UT*Bqv1}QRm1OTI)!T+Ziq?U7Wv@kt?*e#`FY_+79Q&E1y28FSQ-CO6g`WICi9M zu&}X)6#S5XDE?SkBYCsiRi+Og0xDExru|NFdUd3Cx_;feTcONvJlG^9^yI-?Bd#^$ zqc0hCgiViRJf!w zr?!p<1Lfo|Ro%ZongBT1ttJtoz!{;38T=}uTOIX-rH9u$j9WfNeW?MzrsM+3k zQIWPJjuk{UmHWr*mxmrQ;o|;lY(cN6=tBPEKJU!z-@gIIyC{w`b)1T?UVvfSce{Nu zRzrJ(TM~?Apq;~mIqXBnXSv$_tN z5--X*&;>h2Ts~wcx8F`qx_~|u7Ul$r$!_k~FDXz>&M9&#r(mNoPj=h+G~=CRm$a^3 z>mLzt{Z)4Dj6ltFFAcfX&ereQOvbs?#<{%hJC%oN%C6;DwfxRCaj#tC{nWK-n#av7 zUr}H$C+PjgT06@~;o5p(z!N#1ArtgZu619L8`&JI7DyU;u(S5cU*CYnI=(mk)cvRG zY?p^HBG^-g+mPrq(RKVfQla=ubD-CRMLRp@2lW zneV?5x=hVDD#q}2Kx)Q`7x=v_)NgfAfO3R880bGjfShQ8#mx#^!d7(v~A>(eiOQQv7Q_o!>>Ln@47~hwpl;_wNxW8+PG=4nU>#>sRv;aWd45@|t#tlhxX? zD5XR@q>;pnV289<8DWh2rW?x9S9PSa23=7d+t42H%{N$2Fj$_g!Gj)oibs>jOn6`j|62hMX9rlc1Ga=C-(fY z9+wb$gIMI7xeA!p2M=3dlT)!)~BCiEJ1F94}=k5niOJuG+e69>ds3S zO!nl+k-(eu={ZzAFT!=xf(Gd+%XrC{m>RChsu-3|8@js`G6dgHAKWjC3oU|+nWXu@ z7E)*)y@3#{y)D%VGTByY%am%=LeWis#v$c1kcTp|x z_{8zj{y&2St*(HKRhH?@&t zd0qO4u$|9dC^o}a6pejF@tWtB;`s{~B4-N@3$cFu`0@C#{y`ptGsHrGD{5Cq$7{|4 zwB%TkAvWP{Y{G~4?g>^^8rENFw3o*lSawkG`bBYdBOa_Aa7j#ZcT}sac;{MTMhYg2 zeNUoK5ymZHr9L9UHX{Fpv0gLd`0+^7Y{3E}iG-779TBIKn#WF#a3YT&kd9Ll3C6?s zvDIyJ=3jSsQ}cuc-Z_4AZ?BbOFIk5w|9vaHi_#9RoClhAbik*brEzdg(9b!^R@s(Z z{XX0HU2}6_g=%{FR)L~-wmj7IWmX*VMCBN6u_Rdo(H|6E*&(r6oo1 zIS_Tkx{8jmN@MF6p-bbX5!pKiV#55d>f{&`Bwj0S-w|tFH{>zm^SHLD{9=j4_wjLx zG9UdhxAOGvsoaoD^N6TU);&YJpomRtEa4Ak0D6sBADr z{NBBhxLqL@EL>4kN-0c-4jpQ1xi`_)^Ez{Qi{lEpMb*C4G9=lV>tsv5f%-Y*pPg(+ zb%vT{$qKp44qX?H(~Zqb;jt&x0*e8`1de$V7XV_u?nzVb4l3m&0m+ zrB!bHQ`}h8*gT<@sQtT<#3VF6v36OLGo zr3ig(N9;(owy|Y5s8m>Y&-Up8ANeOSG*lbB(wVjqQu@t@AuB73ROYpa3GxnCt`LGs zW>DXsnCHk%I)*jTX|!S8M2f2(7|i@N;z=+SfUW*7N2wfOP8ncUTVhFif8o-vM8aYv zZ|58P_q5=LR**Bhu?2bqk%4T$k6?3TyF-Il_3CL-&D@+E$(ef{_+nE_>OMP#dn}RK zHFAuZ?K`1I-_9I9rxjXnr!B-Y{|X=U&W1W{ql$jf*2o zHB4$#8oXL;_N(I6w$r92Ce)!?#X}cPIG)(a0p?Ngi;WzQwi^FoN5|YEhL5G#Lw1=7 zmtassjdMe+3y(RZ%vLnMnxAE#G@IKd$iqnQiAFZ{&ZTE;ZAt#~-2Q=UYracX@3Wp6 z=N4UP<^T2d1&vb5QEyrMVjj#*X5nsmE+rHfF~>(9SaY;*#p~V`iU7z-QmjjpUzICm zL((dd@Kd$YZTjl_m%BLVCw~9CtA1VB@=5m;Ld6r$vlzY}4%HI;HPKQM6IGJMaN6|b z$&im94TN6BR)=c~L3AvB-tzCO%uFG>CbweGC7oA$_+x_Ycuty_e0!ccvN}2_-Vs%^ z4Y-+T4_Qo8Fp%C~1C`v+I5dVbaFbjf^H+LK*D=Vx4$u@3a5ykBuVN*`jfc|j?DgS~ z91ATiar>dSq7Bv3^Y?V#*8H6AGW1ip?aFUvbS`)I?#?}Vb78@))=&EFjP#@YCr@a3 zqr)PkzxQPu=L*DDpXyUBm6ny=Vv(Pie0l8ZbW)aKE;`gge0;n5 zOsX(HAmdRHOU9(5_Qi|bmo2%Um#(e8X zD!EKDEpHuPq|>U=6bRVZ@WTXLN>_kPN6T(sNtsne?{gOwsh9UYoxgSaHuOof%Y;v- zB&W+%k7^Y1{c|3D=Sk>Nn32+EUlnuch%JHl6m&*@;~#vO5YxyuJYaLSM6`Tt;y6VwRL9Ti8Ko>E><#wpmut` zlrJY^K6Brmw9}p{+j(~E2yY#)Y`&QdAISL)awM?>IRBlyOsbfK%adB}m`V)Hvt>m?WsMI5ICBcpM ztiNjdr&hckR?qad`n>rTGKG8p+FJIP=RUK2=Pf?6Ot$$C&lFpCf8(b1KmuCH;+5njG1O%a%yE`Q%*$m+9lqNXT+B z$<@C(#((FH)|t=Ru}(X<`fd41_VbikzhX0kIfxLz&Z1^iNhLoHk-d~*pI$>w@jzqNHhoNbjsK#v&j@N8lpWtR)nO zfoOx;c6Nd~hYuIuSoM52=5{wRaRhFaXZ!YsX4&dnPzLQx&|h0=(s=9Mx<5SUND|v< z!?C*y3kwl4VGb+OejR%E^ExL(Eb_%#x+Xoe^19f@elD-VPeruQIsPS2Yo$p%w^zEg z)sNbDMbKrUO*-=085m?5W`Wt+O@4H(v;D*?Waa<2*~T71pq}UFnuEHt6)o?+KU*hZ zlW|-C`a{Sl6c9!|#QZv3otq8ZI1W2*ZcZ0mtEpyvLnhmJ7iS=6^waC$pS)8^q|ZnI z8m>bT-SA=*UrA#0{=Iv8Rvb@{?~HKI$tWpj_1>3$d?)c^oC_jERv6KBcfsi=g@rUV zdvBxX)ibkVa)6o*dz9P-<8+^#Dl_D^E7HlzK%j1Cqj$`hG*g~ko3Nxq(!64IMI2ti zmgcU$=y$ihe`W??2?L>>vzzWMA*t*;4%Y^;xI{%ldAg`Ag6odxizX&q3HNu2aCejT z+u#Zc+y;usip&Be#Y0LPy6njm@Auv3=MYHdd-C+DM22QFL?a{;2;4U_78X~@rMMW{ z>m*{G;`2WLTq##^CTWzgm}CC{muU&Kp!}VLWl`Y+Fh&Gh1@bpQQmPJ@$V_~ zO^$p{hZli6nE36JX*CO|C93#>;jZ5_{N5xIn)9`aSsj+t(*&zfYpV(5q}>lXcHjdM zs!v^17_-`SALQW$C<@zeVd?>`SbU_n>+ZZR`f@9ovv-67iFp&q8L8@VnI|PU+fQHT z^_$8grjw}s{(PctaJG8Wk5t2si8U^Kn;V^A#`f;jdmSLgRDCF3(y_YHJwG>B(9a2$ zA%bhm_t4tx@`Vgjpqn)vIad0ui{pWkRWh8~nMOQ@54Df#(RB}AZa95PK6yzS?B&Q7 zmYV!Fz1f1!5eXAUE@ai(6(<=Bo;~A`q(1SaZlCfEkzG%^oFw9%c)OwQP12KGvYnsp%2*q2)+!G> zg4zq0ZTpTB8K&K=RYc;OZXT+9T7nvlr0*n4-W8=Qwl6Z1=Se>y-*Z+W=V+sC{QJ8~ z#7V{)KZzhx&&4mFNu*qko|klG9&}|w3dg8eV`z5A$JZ>3X_w1Td*MB~C-rmei}Z6c zjo*dnbnUmWay(_5!&-{kIeSOfH{A!O28<;V98cUhkzGIz$;iTnbP5sbvsKD zQYBz#$lmj>g&F6HRGpE<#(8ZiksuLw@y7n+CmTX3FAv=3?Jkx-E6=DY_w_o`Bxo@2a<& zGA1SuTs_UFX}96FyZ@9pS+D#fRb zkB&5gjCf#8TsR;275q+sY<`jhnrC(gglS}pGFEk$cL05R%Hzvt8cOcHVmDM;P4&zq zy~t&rkC|DkPVSvWaga*)q3F)kvR(OD7xr>h^s><|0=z=!!6Wewb0Uj7iL+^O0gL7& zQn<-5fP)6Xc?3^F^g4B{-7^p?L!38?%ak~ING;+?AXL+yJwNj3iq0`4NxZDwSI#VJ zt(~1tIuSDN9MyQ*oeeqF0V_r^6XIh4q7ZgK(X=CHypwaeLe30G9g&}7Wkqi79;!P9uhtTof<1micat3!_e+ zIX>oM#N$gb7nF)C@4Q) zU(m!J=LTS`r$M1Oty$rc0QdwiJtRY#Dc5~?2i5uW0a4uC-RAxpEVP=>J*7W;y<_g* zGpvaS#5;mXzy$2q*^_U7TXR!`V;Q+|b4V;eF(eTmV3B#8H$ltMH7DUlbl9iN5<%@? zT*Xq^P5Zv3k^9)pSIW%H%h_OTt5(Q+s#5a=U4$R(XPEdM`}vE|BC|C4%v0E@Q{J<` zZ`K0UeqD3Zw^_Pi zkv^DAGmGq@@0}x@J}=t7YeEWwp`=0p$ZU#u2qQ2l#`wsUO%o91kxNH-Up}4dcrtMh zGDHw7BkPa0X#*XUW_)B6nv^J4mYp5qorViKh-c=wB5h%B`5#_2^>mJ{<}&c(o)QM{ zQKq3K$D#6Zt}15_4xX)K8-4y+KT5eM=0%3Y)Cksi*6f881AHtV{+T8pPtQc)6IjRi zCP7p9j`1Yk${NLx+F_SudQ)J<{~gwQ{srscX@bbJ$Vc3#y~=TnT%}Egj$m-Sy5Z)` zq^R+czKjUgEUZq;bk|i*?Fvei>zVXGKr8E8+mTcAHX1|d$(5hiA3gdYc_omBrM&L9 z;SfRk>Q>&v);O0G6jnyeo4F|#kl1!7tVii|*$2c`gbfL)eK}IwDcYir+ErZc+cJp+ z{gEI|i$AB}lZGXn$loDzm)M96lN~C*qoeA2Y9~hn`?d1#R zNdR&J@+|}Fv~&wx-mnw+F0tvu(!vhr$eZW1eAf_v{2JKsOyK*0i_h;HvZH7p zV3uG~^Q?Kn%QcgVz?XyMnvFX;?wfTE=}YcoVJdJdf3O1ZpU>=b(79DlLxHs~mNmX{ zBB`mGHakE&2WV?WPi4NHH0)PQtqTNU#KSBSMiDuzc~?_-dqh}30#IdYQ`|q%?Ga$J z;ZbgXX><|r!8$rC$I~IUJ%X#-gPx|sF5)OX!s?S{-xRmglAgZ^to|oCG<0BS?eE1% zvf0-ZpSvlxsM7{K9JFBk&ms#l*2_UmVwgh24o-@^5>5UXUv!ypX>7Yp7=IAB@qg~c z#Rry|R^|VLogE@CJDyU0B;QIv-?hIV)!Fi+hsm!#nzirZHI=jEzCy7-&O5szd8tYG zdvhnFSODrr&UvNcYv^1(Vt9}U*Q_xjl=%@CW8R6=F!o9p<#N5zxj}k3k=)^yBvXN+{j>jhhM}bq{VZPPD=!=#D9QTR728qFb*7PT zj{1|tkCChIIBr6XoX6^X`d+9$rtDq1Lnzu69w{=?wX^JVrV zehUiy(x7@;K|ANfe`WyD4;Pu@)46X`R`K`E#NQ_<-YIZi`}IQeG@r|NTJDWS%tYIh z5$Y8x=k4S~&n;tBR&bxc`T4}u6nImXUO+|jXH?OB@8LuK%p1V8TUrbOJQ_Y`fAi)I zxQwRJiC@1&_^EA6``Wv^55GJ{;^E;DuogrvXm4v9pwf+mdL&acsxhdx_CV$h1;&G- zpJlcJkWJ6emma<`F0ZI~m!+Wbxs)q`OSsIB92z;(HZXAXwegd|*~2L1Y*%-5{q6H+ zVrE9H<*J9r-7Uys0q~~u6u*u;OJ31UthKIE&0|=YXgI1g|FQP$Vutr zrChsr2t22i<6-p1m_C=u4$;@k->%bbargJv@LS5-A!^{WHB8WNiNb|KkBzY&4vc+} z?5ugBifN=aQoO^V7v*?Fdc|uR>+UFt%zHoJHRYAh%jQl}Kvg7dKOIy~uYZ5BByviW zZ=}vy8W_%!<5K^Q3E!%NJ_9rD~6ntJr+YxZwNB+4yJK+yQmmgxi`j;IYKry z!oG*MiZtXW+wtdWF?0~#Q~9NGii!mAD|z6sU9s8Ri?nsd@GUzGR~Vz?C2>iwZFv2T zNF-qB>4{nLB-enF0Tl_<|7xQ#u2 z_~XRv>|twb{$h1$E~24{(XjFV&}#YH%347AKAmU31@N>HgP)LBRsGJtG90e4CWs1B z2?>dzP~ zBay@sBh7rijEq@(^}!aYX7~|?ZM=Ah%;6N^2#Ivv8a3<&1_riB>A?b`0dw8Yt~{z8 zjj}RZcBmUHaVYafXFh&R<6N53^ZkC};7x6zGLK2NerM(O_j{l|V-9cc>pOB+vR)2L z5+A^`ZJY2PXJE!l%ggoCp6rWMxKcMawqi5J`uh5YvW_Lo=0xer;XQh?j0bS@Kl~vP_J9_jeJ|wtvQkxJ)qc>!UMfCpbe`2C{Ra;I~_uo+SxqiJ?j*)8>_|M>X6@H#(g$=POKJbFY;`Z}I4o8*y(92m2_QWJDV;5NisN}fE4 zP%-WBlLRn+&RlKbop4ZeP9zZJ#6&J=KH+kooRlD{s%n|%76XCpVzR8DvNAV7Pb_H+ z9es-&Jg~jpXv8xel~OD3!MioOi{22@uD{Ygav#5mISwAJ=XNOREmSl8#!RTnF}C(S zQ{lNDjwFS(CZ4d`l@%2~bgs@qQMzX(pUvjKZg~ZTAV^6JjvX5Xgk)CXu?u*}ksO6| zT2`SM#vi?8FpM_qKTU~O#Kgqrrmy&KgJC6bFi2_*)6|*pR7|a}g|4)h5^vf5!%!G< z+l}?XO_U{E<>BS6^Qv0pgL>Q^5GIxetXc?w;lcHRLDu~xT!LEK3$YuW8ta`JISaMr zl{e6W33Lcqy_`477pZ=GKxT>+oMDnDzh_UVu87btF4%a`2dFQ>ouRrU-gZR4%P z73H9K6GJ~=mX-=*YR3>E9Kyhldgwk+?>>Gc zG`sLL{MUcUpS^HF7#sTOQ`ilDpias6?_=^~IFKhUay(y^YYQUT#*-rq#UBp?}T4TnY=qp+>&ZnxRjK9{PftR!q4 zcFgd=gM0UC+p`YKtEn-93G+}Y0OquPuNx%@Pqbd3Yi)~U7bhOk>0f8dtigF)Xnh!p z9a}Z^?j0>NpK1ttjo&T9v_yK1>{T@O@Tg+%>nKh7Qz6Bj2I zq=%_DZh1h2=4n)xulU~BmUg~>wG+AWvFiV^+<>O;%I*_;-K2Q;CSU+lD zK#;xQ-s`Jwtlm+#=H=sSL^T3kzDd-L)jy)!S3y(ZV#L<@a4%8FydP_F6q~Kg_pbt} zC3)fP20EkM=y0`7lC^n@9UPmQ8jUy7ktYMK|J>D;0mnbyl6vH6D7sj-7YjFDGR#qVMm>*Od>krr$5242cN)_uj z)>q?ik3LLIZG4>OM~~BD;It;~iL>Th&ZYY%m+6PTEpO3SV^O%r2&R5wVuDm7t%_=U zETpKx^%*ZchOYo*Hs-=LuzZHsmj}a}M#*YI`@6n;sk4M1^>_ZvOX2pSH;jC2gP z6_jil8WQ;Czqx)_fn_Tr_1b)lzqX&B`k(1O@z;kzDAqMJP~xWE`LZ2R+w0AZRTu&o zy_d04b(fURY;LUM-|ybP*YjCWmX{Bdty&pTwL$H0kEQp=1Vln3ao!7XO>-d3=>#DCKda<^NzZV|(JbJc-B8i*Z4s|Bsv47kPZsvflP z2Hk&kdts|}&Ya1T+iOv5A1bG(3hRn$J2@q#FtE22Lt2vf8aFsNIEL_?^)B3Us~mu@ z+=3npbEt5lGk*ZK3|j-W&Biwee_T#LSrn?$cScB^Q`n07{hROr8P(Mqx$3Eg;+TYR z5S8mA@yFCzwIrbbVB!7qSYsWR$Gu=lT9!cx=PLH>(SNIb)1JQut9KAZvJ+V`As=<& zzKA3S+Ny*{#UNjQf+?qSfe&rT&~FU~VP zLWdGR8?u>ed^|kpGtodSzQl9jaOS{06OIw(`+8I6Tnm=|Yoj|*moV(2LacC+Pp5?9 zY+YRB?9|KJ-h{M@+(;4`p7#caN{~sQ>*>FP{xt#xg5CxpS{d1?n+O`t{se0zpB}NjOkcXoPHt^in>|;_S=jWEz*0=F8s0%?$w7d=m zLG=0a-J&{cDFjmp`p~ZeS_+};XTYj!8>6_3@#ec)gwHwepv z8td$T-$T#r^Zcc0XO~e#JAwV#*2V(n_}1t9~&`(3W>w+S0J+dN!TjiWE4>!>OJ+wmk=_)MYpOV+zPXN z6T3_{M(Q|N9Zi8)k6yD#?Vzx*u&I!nutyJgpwB+BsnNl7#yC^IrLvb}z-`)R;*y}B}ZyP`rB8-X+=#(SaVK`pvT zo%m3r2qh7m5o-4j>Qa+wCa>+->n1XJlp2H{N}6#yK~U0K9X@=xy|XhInqR^-Og=M5 zuoEOphZ+^xcBc{$?g7|U_z#v-RrO}{Hf4KMyax^5X&ysbrE>KrM`pW2N9C0Jdg9CXutr@J2mAB@W&9#W1F&b1Lk3eT&Ow! zLJ(MZ(``ODhad@rJV99_WjwOsvG+tvI+^c1VaZmf{-Kr6$QiJe8?ls$dUogeMEo1BB!+SV}|ELc|%(7@- z>6LJ;4BfW8grp>4!~m$!)r+acl5!oqu}qu-!IPF07rW3=^wEIYD*m>T*}E%L!3RKH zy&GG&tMnYz=fxhA9U)4=wXrUR7uh?G+fah#9B#%z2#;Ve;e9EC4~A;O61MzZZE6Ayxbqy9bvQno2x{C>*I9_i+FM$#C#m| zRFDdB(1)gT4#)hwGsa6xiFF#9<=|)4`fz^~o~+mnC&4&fkW#=w@Dt*?C*>1_%HCrM zrYup7cUrg$jB}CJVzf@^`z+YZD3tag`0Baz>MrFQUw&Kl1{toX1BiLowub%HZy1E~ zPdCRHLami`KRYWQ$n;Ol3Qlx-7amHJ*KXZyU&B)CvUE+Scu^c`k(j zuN{NhuiTij)H_xHW#C-ZTYGtY6r4kmR20)TC4w2=^_48lu3%JEMI{2j4&n^@+Y;sl zulbUjuY%@XsomlSg2Ytpm(n+Sl=FmP)dJWYY?zyK>A2Q&ZS}({RCGdW6!4x;o;=ZY zT-1?Cs-IoP4}(%Oa99kUt{hyK!Ez0a&OG_{YJsfxa40ue0l7VU5{z}XlQJ{{QaG%q zyd1K}47m`cA^!A)D;404Mkp%G6(zdz;%v>P`fKT-&6XI3fVC$;=8B4&Zp0RE(dSwtOM z>BilnwS~yLQNlY!qp?DU?k)G1-Y1-tNKHb8%pvf=)(Dc!^1ozr2kGaySr|V44 zflhJ-O=GC++!WX){eJiK_usBsUiY3`k9mIWc0dqZ95;LJtJ( z1#pZ@O7+P05J^LaMOc^P78Vr~>X6Jndi=P(qaz54nUag$BmL#>gsC99?%^+Z*pLed zd;1Qza69zYs`i_!3ZxB?3Pw~URA=`{v7pH+a*exQ1l9umT#rzUyx@W0!Ur)hn8c6KlyLM4D_ z=q^P<#Eo@=MtWLeC7hBbB71W2RDo6y$u7zrl`i*&;F9fVQZy|5hXQHtyehVgPa{X`(8iT-y&Lbkr#5zJ8q=A5dNKz2?U;6r7H20_= zZa9o|dS&Il1Hq5Fr(7r61Q9tuQY=o?&rxw5p+pE%e6E>`P=9G??0`IpNN=0R>d^2e zUX=;P*-?=fSs$Ltuig^L$wNmDAEsgESEEH13kO=;^iac}AA4%2q-6cS-&3A^hcg@7aP9m#E#!i&aBL_jgu!2?&?O(q} zVmfH{Xf4=KA|pn;Yy0W`9+U+EC?k$QT6}9{#D2n~BHK66BL6MnTZZeX;2MA`WmZ;h zW2~p`O~ti-uEeDDy`Werccrja>2xKnE)a_$MqZym5SQLo)ya8=D=f zs;aRG38Cm+g#}LRy2H1(*J7vL*;xNOn1>V;a31!-{{K2Zt??dt3-YT<;Esz`#JV?J6#sv;*o`CMNk7p#ZyJpaIFySe7~;^`udEFBW~?>`Kan zs1N@lH~m%vpck0VqwmMB5q$CS+>_)GiP1rI{Kh)XSejbBODc``q(p*Nz6ne<(ST3% zF?UQ8;t1fq=x&3?$Ot-V5O=-!O28d=-nBTF){oAoKYPZ=A9J`TUm@ia_MU+rH#Er5 zi)KL9)Hz8s0ZU6ub15vW(<9Y1783E}*|X?>bxdV_sQwCMKPOb5|L{*j0FEF517Elazb-JvuLL2&cwe6UVdEhGovMLs+2S@OBj(VEmfg(9#6P!`AfAe68>f1cW@ zMAgwqs%HAnTvId9AJl{pO3QjVq{GNncSY9k$5fnKx3z^}`Cy^}g@;02@}7CY>Mtc7 zKp@prWQufdKD}?>u<$;O;|nD4Vd2u|SYKApIs%h}0}1$#SM5 zCnIsoHaY3Tfj?Rs}D15vOqUCn;>*Xu2yo>WId!cjl2vOUbY5XOu}Y3i1aFtnEX zdJf3NUf(b{_i)Tb#a1Z=p%gNEsUEWGLD~MP-q5bg=9CdEf?6R!QMK{QNFK${`y|#< z8sCo=&&#?xMyw0HtOv-V7k=X9GWiv=sk5$mvr}4s!n-wy!~Z~AopbWzPm{rJTRD}& z^rV=>-1A+*Wwd1sa>%!B)<(DqydKK}VV28l#qQ$8!~bBsft^VqaE9TMRk@-*CMfH7 zzi?r${|`1P;e53ux{$LIt^fr_uzRrew&o^f>Ih&Ewl`+tYPrH1?TJRyVVF`k{AP5z z#;S=wS_gVCTZMZrfRhNa3*py2ryo^G3||AwXG?&{%KFVS2p+-ntSvs%!~*i5s|)+u zFBS2bI9p_YhYoQc3hGAZhoY6gX`VO{AA9q@f6TaH15j632GA{F44_I5fitGVNB5F# ztf$WIA1efC<~?1~O?f)JZ~ASTbv}IwI+~@9Y0#2UywtA;jbKwIv2jN#qGLQOkIe-jcw+VBJj!Wo~ zVWXLQG7}A8WA^{yK~)N%ZKUF1K%~O?eQ1f?tf3)<@W<*YB*QXr z)2=T&KMkG6V&tyj{%Z+b>>K0~!0;IKRIr~B`A{Ka2CqfWTRph;Lm8F?k6SA>8z;ke zM3zdix;z_>>IN7rDE~>|YjE2%)`qvB8jau^@SFjP2ONeMDra2P_|j^?S>L4hIo!>BKDSIi&_BkV}c<>aEWKEedGuOJS#MS^Cg8h zn8sVvxJ~}y;T}L-MYO3AK72bJoC=T$7KIQvURxxEM8hX}d3mz%`arl@#2E~T#d^wI z33>#b5nWMWj^4xsv^IItme|w$sBh?b>Bx?VA3LYWecTZFBQ_5RGy%pb_+o z)INQhPszDI0=->p92CK0lfW>n{7|mmWzd2aTb{GuqKSRc_zBJ%Pm+);4+Dk)boxm>Qse9v&RPqllI=aCmL)?PRDZ z0B*^Pg{5`BJtIR9Ecb9ulC>6y5h5Bz>}QVviBx7mjy{6kzlxjSQti-g3u_gyNiAF{ z_7L0x;CTX@qb;|(jZ`y3B`czj!j;v9JD|0)`9c^5ZP$TxAON7cIxVD`2&bXmLZXf2 z8xC~X+gc()h&P(P*w^<9wR$D9zqWW%Gb?>)$OhcecenD`Mx<=Ce;uyP-7}|WUQ}iWLBpWnKlj@new^QL#SZJL ze^QV`P-t2(L7(^mZM?Szt?-5y{}PY1usg+;W`(_?yhM^@INLNn+uGV1j?ZwLUtGS2 zmPD6HX@M7)gxij|h~ zxTz@(B4R|hK(Xxs1L4Nuw9EkJLjNHS;YF&Yb^imH+IMFa&|yXx6&D~;;cc*jL#+#& zfY?E(ohW6#kg)Ttu$Hzec&i{g9$=0HfrTB5{f-5QP|mExi4%*CVC0fNotLty+Wz7N zaj6JxYG5-Fn-RFd>TI>m6IoElR0tD5eF}0;L#hgncOE?`vrs(mR&JHtu(-znJ_gSm z3=i7TgyBFe8|;9fbLIrxiH3eei3?y3;DrrEnyf<3tVqkSJRm|vl@ig<3*k687nG|O zoqf-S%!LZK2Z;z97c~)K;O^hJv7f-9Qc{di&H!u>us{aP2tp7LcgQFL5YRP^9zb%! z?=v9?$|LZcIWRoZkP;O{hS;cx35jB~9OFpj23Sk~Bf5l<^C10h1RxK0|8r{Ugg(2J z(4L50TC?^=QrAy!d@H})y|L=s9bYkYrk8crNi3HG zX<19R+MwC@$Nh(55lQ_2qZ9t%Cv^YMzw0-*I0{`Tm($*}L?V$yJr0?9oc%vbEJ?LW zE=mPb3`Pcq#<~U;x<*DJhUQj=rdCGA+6G2e1_tcPHTftSa`RI%(<*UmD62bi8K{B5 M)78&qol`;+0AiqeQ2+n{ literal 0 HcmV?d00001 diff --git a/docs/_static/inv-interpolators.png b/docs/_static/inv-interpolators.png new file mode 100644 index 0000000000000000000000000000000000000000..0daa3778895c57ae7b8039b8875f873c58eff652 GIT binary patch literal 55476 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 tM-PjN%ZQ5Z;P$frf4 + + + diff --git a/docs/_static/vector-cross.png b/docs/_static/vector-cross.png new file mode 100644 index 0000000000000000000000000000000000000000..e774b776b2d87cd4de32de983ef1fa8c30e687b2 GIT binary patch literal 13425 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 literal 0 HcmV?d00001 diff --git a/docs/_static/vector-mirrorOn.png b/docs/_static/vector-mirrorOn.png new file mode 100644 index 0000000000000000000000000000000000000000..aaaf582475e19306f93d3afa21cc3079f07e337c GIT binary patch literal 13106 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 BMaTdE literal 0 HcmV?d00001 diff --git a/docs/_static/vector-perpendicular.png b/docs/_static/vector-perpendicular.png new file mode 100644 index 0000000000000000000000000000000000000000..61dd67152fd5bc1ef2587dc1a870d3570a6d8608 GIT binary patch literal 13768 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 x0GA}6IJStV`|@P7|6^=SYA literal 0 HcmV?d00001 diff --git a/docs/_static/vector-rotated.png b/docs/_static/vector-rotated.png new file mode 100644 index 0000000000000000000000000000000000000000..442642055782c3927a4fb58c5c0be103d4720a09 GIT binary patch literal 12682 zcmWk#1ymeM5L}#~L4sRwclY4#79_ZP2<{LdxI2eyaCdiicZcBa@bBMyCp)j_ZfCB$ zy1IHdR7pV+837Lg003lZDKQlQfPe;nE`^5#zoKe7&w$?`oKz%5fQku%WAMQz2dVE) z0Dy@8{}Wi;D_*%z;&OE~BFc=c zi9N+IM3Y`isizFllnf_+^whmef|)&)hj3KlvJZojKQeMFs#Q(|0>68H5x4pIjxH7s zg@79XxLMndn?NpSCb$1SsGVSu9)fsS=kUBd%*Hw-!|jSTeU5pEBY8*k2R5C37kzK{ zSQ8`2phA*E>D}@CMnjYJJtmI(kC9TAi_AK2GdSubp4;cF3KDNUEh|`)|2NG48U{x~ z%lEI~aBZjt&5zVsS=(`Cblkl^@e4vEq@PIMQByscBrFOOTp^??AYGH6oLL*)j@k?_ zjo{wQ1GoMOvg_~)q7S?8koxD3E6LWRU$$?NckUznQAo}RSVs83hq(98+Fux#(15~V zrcX0Zd=cTA7xUB2kAZg0r~V$5-j=gd&Wkbr)%gZcqw4|-FL)w!L*c!N*T*LFIHa(d z(`BGpR+RpLT&*u&@~advcs)G?<21_~l!Hs8`3f#~zffibcvb>ODKL z3YuL3-dk~WO$>vigrlWU)kC-HPc(u}cJ}2M12vR}P4T$X=d>6_Kq(vVJ5%v+W7z26 z)SD22@Aa47DZqxjqV{cqgWdWE<8Z$6M*j<$8TMZU9eW?oZ-*za3Dh_XB8s?0M%#wS ziaL2hA-aLCX}SI-(*eUlI4c42LWv}z`=cTa{-Pr(@D~}^0fH6+ z$`_KwJ22rGCNqW%KeBDLM&={8OI1vyv$sf`y(;$~eTV|b#j%*~-(yOZZvsY0u(;3M z0f3Nz&FeIhq<0+&^Y8TfxKi5IZxH~mrRp_M?@vfOuJ$tSTd_7CNDnPmUG6<05gMxM zvrg1K3mbh(fpD}$jf;*autGoXi?U?GyT8jup61UWIem;oR5mwACr7Z zh74xX&}gmaaDwBg%2uuscd5GS^=RBjo(fKAHga1AX19ki2-95&k=bGZ9E}?$UAIg> zM@)+n=H1&o)8^ID!gzW5kM7mu697Ck%SZQ{sfPK;<+Hf5>WX{`ef{1223fRX#i@5& zLKw`aawwf-;$HpQ2{IXZ7#(e?V#awPk`}*pF?vxB< z*x$lF!E?O_$pzN(})60I^uq89t3#C$ql?Zu&*>G2XS{1ncqJa04``E4u9 z_lQVCfS1R$?7mzc`tkHti=iB%%6ISGHT`Mvl5nz50g7bn6DRW8udQkS8^=S4u_tpC zeN5ZI^`vGX3$cPiV@90xb%pP zc!PcR#mrU#Dl0JnufW~;q(K~iA?G&gHpd$F!O*FyRMZsEbe&p>tT+0SWL`UBw)AdD zm8V$vrGUktjJ&}s^D~pBb70i;6UhWVW;5uOsd?T|2>hA$^a*$JSc7AfKpR5VdgkSS}fKhsiFwDbqTC zdsv9SvCdq&TUN8u%Pi+3{XSisCz%%&myRjUf&^u-k?O9m|E%4I@x*zH?0~Gb;!Tsa zqj_nm9mX&m;jGU6#p$2fiaY>@X?%?I8uvzi)6C`}-7E&|RWD$C~12~J8*R5s!n zBmtAnm?|1WkMOD_t>hC>*$6=yY}Lay_e|G?uf1;~ifXW3L(X?yAIqDsn!|&{M2h)^ z4O!ZSAnA^HmyOjY@;-#8m7C8VGOaY| z{`p=(lyW3zjb&m<2T2$*a{4ZCo}>;AsUEn${S#05%+1VfYBvH7z2VyZWHrka zzEr+My=Y600cIWuu|sk55i(%xoPBkoPDa)g>^`3`#JpllgXnKk*(9Z|irZ=759I*ryBqcFSO*CfBW59>vj*+reHTfIFQp*?wT; z(st5*-^yKmnX{2Ffg$?w{ojKLu+Wf`wbT%5akVUP+>O&Dr0+eG3c#`o8q7OEoK(F)A>q*?;<=QGHh<{|v(oH^lKXRM?22 zI%+)p&h!@C7E1#nO5^Fu&4K_@6K z&lOrOJ2Z+=5`uWOW#~;QYJ818t{Sp*JBOxnzlFO)+${Vq3muKt!LMm38&|SQ`~>p} z2(Bm42of+iB4sX_$#ur@WU$;nyIt*D`i$5In`ziPjx092DA?wCR9zpr_oV1E;j?%3 z^GmbIl**5(^^x`U5fC?M7x8HQL1^BB*8GwS7%AT2z;1M9Xf9 zV>Xo)IPzCne6qW4l`xQZL!q@ihr&nXYtWXIy*lOMzlIMRc%DyV)?MOS++or~*XFQ+Y~!OO`7O?t0l zs!xkb`XglFbv(4U?;pF;-7U;vs8SJv$hE&dU#6_OY8F*CwFGz-@SFbdulYqZE@D(| zeN-{Kn^|f4udSU8_iro>XIf6kIlfgkuZA#~y3(6G=ZhxN4R^L)gH-aMtDJ@udZ2;) z&VsI!t+^bp9nsj3k<*Zo@6Oh9$bPyEi${CTVMtb>75ntf3eR@dJ=}a6^y?t>j{E?f z{A#T(?Q9 z31=uj)%Ni3KsVYlT7l@l1ExpCmX^e%Bb)Owu1S^+HMx>Aq>`rAmQU9UfhRum9 zScB{eH^?b3_=qm@$7Dm(F*KVs>MfVd92@(AnXnm30#J-@irk8({fly$EYn3G?QHvx z%Py$wg@4~6`u(2nM;d{AkrG4J6nOffu$GaetXgqPJ>QhOs@Jz7cg3tbv)PEc z`dL1?Nv)V~Oa-b3g-AA>vh>VfDeG&4Zlhgqv!W zw*RT@BllrE6x}BZY)Onne$mvx$&80k(o#7hai;dwCrtpT@kx&RbBaYxoe*VPn7%tw z_?cOJ)o=1ODG9lKjNc933}>g93m4qErXJl6Tp(6^pP#RhU9OiY!t?#b&+^o9_Ef&H zW+QJCiovA%UKJH%I53PGT}zDdaZK>R%^JWJF%>NmxsO;mmnI}syMmH_+F zllh_0n3vSgCcd|d2TJ?I2ArAp|irvZ2B%h7)}C z)L($Chc!P861{(I zYS-Tg#|S1A`R%h;m))F!u(Hk6~XBczC{SQEMV3Q34Pr}Ijh4jx&;K>6wQdCtWFWbM?4bPXSac98w$hchhm^meu3NTgo8~lily9*6xI8S@uxzGaT4Z z_b6aWg&*?xQf6?)SA>TcX;PH^$x9Cg%6FdR8JpDmf%k;n z`43Gb=$>zT_P2dNXX=Kb$G+nPm=Ty~q&Yrb88&O%SsU@y?v8=ccU=KvL`^D9XMAN> z{=yE=-N0l&NK3&?0g;#Kk!4S^S$o4-Qd2OR=^&i0ECB0D+zQlU16g4|+w26D6noOI zhh5pyAXBayEy&&S@_MeG$_OO@7e{l?@s+N%necB$wrOBeA3o#a(C7km!jrmukPF31 z9JmDDkZS%GaXL$k^Y@FRdjZB0azVMZ_oM^KH4sYpeZ|-^_3RNnr=b4OXcEHWY^r6Y z&qSiO><(O6!rG?dGbcksC#Ml;L^3M0xgEWUa+ruL|JhlD==|qA5dO4t7T9peG^XiW zppcdIKCh#%uH|4_>}biO+bG5*WZ<)(rP0~$Azt|y`5^zW|{rGJN~a9e%xWQpFU0A*u3lAmG9b!x(q%wl>0 z_GW{gt!&EFNXPv8u`6=t<9vSUWCYx#_9h!W;tyD1+BnAZmdDN^{Vog}yeb+_CKuDJ z#Cb|Pn`Jkv)soc- ztt~k#N@55u1yucM3^J|k$Lf2hGBRl?3kdhwJW%uH9yc~{09?PEU+i;ZvS{{}(mTiYHV^ATyzs)$? ziM-Hf!5I7%OhFEZyV{|AQC^x)7qO7F$;ajY?X8tu7qfOb`<(Zzr7=TvRlKzR5jq=e z^qt!b@%8*39nJq87LkRXLZVaMhDev5gr%c1bSNO1kUFq8WPXt_d>&WffKc%Ka_#1l z8d31x2Js49Uv`DLrV8h_jUEc&V@n{>jE%PUv#+{3D7=11hOVVKpGQ2PNv+SZfzH}v zZoQ~QYs>6=#pso|bi;IFON`vQ=abVF#P3#LOeIZpBn8)|kFbP+X7kK%0kv7N&o_7d z6zVj}*<3Smxm|fn(1tbGVjKa6B{_S!=J7=P@o3+$-1-Cf|LMc4RH|Jf&-s|9gpYyC zg>TX#^7*7SWD7wRFk3d~ukz6a>c_bYOGqz7XJk>fm9Rh7NYbHFw-uQF`Z)beRG8mw zBw`m;&8|@Bu_9c?`tKn-JM=r}O#{_v9(zCAqxSBigewHA_+HLVhX+jFI! z9HLzN*$$Jdr-RFJ*tl|c&&X4!??aMb$8FNo?M>&ClBopEqL2tOo8jDS@fsk6lS0}v z_^n4r;|T+15oVh_y8Qjhay5_DG~+7fm{?=pa^3muP`yzKa8`_{qj#WEd|iCrNCQ)+ zkc7oFpfx{ne+E|*!DeT`nslqNfn*o2R4`GbCr~V2wD0H!gR{mD4~$Roou3v1&Ph`Org|Tt@|D{->jM_W@W!xZV- z3JSg;LGiD$#N`%KtXsARNPNo^6@f^@^))l8#&efx!tK=NQiMPrKfr9hC6$7%;uJh( z%K`3HQt*iHaY2EFoLe_bbXNuNDyDF~34`5IbvA(gE}1t}FH0E=J`8~ixrXgxO!L!U{e2TvneuLHd!O#9{qg5X|Z!zn3Hse z1YrjO{HkM=P7=#C_*6lmm+t9dw>Ku$yMw>Eesr=`Iz{8rbO*2CW&IuXebCppjlv7@ z$=Tti`*3F>_M|5MmD|C@O?0}a0S0$~f81AFBG_7babx8vDctl9;~I>w;VnsawNBKu zBOdC)-=rY`1huWMuE1EhVMpos6@}}Dn*&-nE;)}~aC+?m*Hgn+>-=HnRP|886Q>Ye ze&?;NOi%-h-HpMxwDlv~FCq3V$Kojlq|BiixFvJ6(v1d;teY%uaGGr39z&=@qsyj? zdHRWB#a`c&L{g;Ec}jq>GI8AH(MbB=lYaXLAGVi`Q>i($9e%r63=xl?Jp5xSKz#Bk_-1&B32b^=Bi>9Hn zWJE_zbF5C$3kqev(x7RrXLtk=BuWAIGvA06fGPu?DM-67c%OhgGG3Tu#BHx+IR zPx=F_;cO6c+^qg%@dWtJV-6^^pb@h~WWxZkAaQvfEUtI+38SOwQoOn)<(2`QPMw?s z$a?XS?fEXiISv?7s|l5)L^m>_t3j0{gx$K>xiG#kZc=pkaVRJ89SklsooW;R9$%r4 z?zk2(f}xQSc4(m`gSGvLU*2)H(1puj!gA;8JRaY-^L3U4-C7~O!A4w|>HoBGpgL5T zuFV^Lk;7%CEl03Hl{)N--M%AnQ(<1_3N=gtwK?B<-=er3 z8y!*8Rj!sqcGS);rhV13)OBsQhLo&HcEaNhC=-Q7A|F zIRB*N_?kyro)v-cT*GW82mHxI%l$*U$iebc*bh4TJ}eZK5KrPwHnbysc)T?9mAyks zlWhsaR;-d66$-CUMfNDpAxO|*`k`{)OmF-R))7v9U?3fz&;CO0;F$7J!Hs{{v0if1 zaZ3p)l^N6kX(6M>0K43{|NeP0#J&ir-DceL_*Tw zYXI!~?_aDum#A>Oxj%RFkC^p(bgQ3rKt_bnx1*dG&_0q)F`x0 zkS*#fhD_UKJ(PL<1kb%m&BPLfbTgqso_FL&;>^pD9Z6*w%$(Dl?Ou88?l?l8rGky* z9d9DX=Ua?`8^{COqfUQSD)2BYY{cTgj8gq~kXiXzYtk%5h=)wD9bYR2HYJop<9YAh zCxU-WxC6wvz5>U*eqg>g@RGS-HM&lGgFZhqC~kGf;%F1MxR*ZHTBcsGIhdHPgQ-9f70O*KQgjVb{rZf? z;1RWwreNF5d^ueaIZ7q0y~dJx($03$GZ80!BSZ4`=^;6 z!Cgdj3OaIf4>o50%X;W{N5d@LrNfgDmGnhB*>rTTmeX6wM5^p zZcOt)wl1a;Oa6p~*v{_HpRKvx9G}>)yj&}9=B~|@h+P(y5B*kzIIzRRmsi~pxEaCR zbJ(nFa_!5!RrR`LaF^dsuJ{H|C1ntJooV0PZ_JvSztV-zVubK21cTcmt*1vK69~u4 zCd(B$olwHP!SIN^AUP3icx8jhlqJEeyr`favpDj??sVC07*VLv z7BLkG3J%gwJCafFvL8F6fqU*7t4(veY2P~9Q zdoa%}M^$8%ul_@GnL+#aMmxmTj(7(Da7m14`Pbg%B6A&kJ9#$t=$-Y9pS5|agUK<+ zC8{wp5C(fv9U8rsv7!tly(89io69#*QPU9Iyw4W>g4;uAP0igS2(7O8$(2&SyMzI1 z8r(~aMxW5$ba`0h^5go_#T~?OX@Z-p=|MPm6pvB)Xg2^r`~3g40AKs73~>YrhKFN@ zFQ+9XurIseET$oaS34V>!jrk%FyT#T1zct8s5L|{6oYeSa-<@A+9E3WR!oN3AX4Dv zCKciD8tnB1xhyv`1L(Seu3gL4U&g1W9K1tn%-`SIsi~DX?EO6kGOR{-KHiJI7d2q^ zT2Lw~6Y$#c>n*pDSa*wjnd9XQ=(kF+ScV_rP_kNrr>&2vMOUjX=d>b3P@kG|YnRDi z2>SQwC1NzB{bOSfh?(D(H`yLSexgX9A)csuLw|Jadw`Ct7xx6 zG=ZW_PeM4`JtFem*^ly^^leHTnyQIie*Hl(r?%RqXx6Y<+YK(t3B*Xh7*bFw7ga;i z=BqMPE+iPYiNG484^9g%4Vn%Jg<<~EJ@E*#$=d5$hBPD1gSjy68YF_;pqmj-3}9k8 zRV`P2fr+GYOrK-5a(Xlq2yL)624D>c2vT--YF0fp!5ub5@?hdhE#;thftS>R@7Fx^+C7LWX!qgRFD5RY!ifyztB{i?c>D$c(av-!3Hc`P z*4u@Qf08nnSHsR%(0=h$Uz45kexOut`U!sV9C6AsH*=%}m|7PsZ)Uwty>Ih%>fqUt z0m*0)QW`~cjPIO41W{yzt)VFlz-7OXe?+E#N=ir|_>lod^hLSgY`$+$A2`L+mcV1H zTodgsmO4QHPnQmM&N(Rr zr40COE4O)HoTVSNmX74}5}L3AI9wGfH$Kq7qgS033=kDnaBTgjKO921q%V;!LxQJ` zh?Tyz&E|di$*qCNGvR?+wB+VmhN-Qc?)~)r4Dxp*4#Bu7r@7a0faurEE9UI zNqWH!-TCPq*6$A!LKe~a#g2ZYaB6c#=8vnQICP-O?EuE>8d}&A>6d)hVQ()K@ctAs zOC6#qAKYAYSkcyi?pHFzZX_XQ{jxAWnvy0$59^0PMf={Dkbd$f8VrAaGZvY6MyE?N zu_{)yMQSLOQAoA#sduVNiolro0ZXkBzYV_??Q#wjpxgfJHKazwjtoKp@g=`Mt-DI_ zt1bti*b&l&Xi5Z|CMVmrG=K6dFR^|7*a3}2rUI{T4>LYp!zFc3RLm?i9JFI&F|o?p z&7rt@qD?JHX~>DKAk9Cvs}0__(~_R|r-nGer8>?TNIG`*UtI$J|DK|&21*G#+OzW? zEz+4XFq)d&ygO%&EH*ehyAat;O>=HIERd@WxNo!~UxD8tofV3yadE89|K^ELdmuq#AOVdr75*&`>q+@Q#!EAJ>W-4iCG%*d{G&>p*p#l)6Cr zlaP~(70nU~`LxLB+yH96*qk*2abW@za3s5faV{*P!id5GgvkeMWVd7t4* zdOH~wx*=X3$hfe7@+8P)@Tz-!YzW-D$B7fzcNut3Wq(_&(3`bj7kax@&69`(rr5n5 zJ~qS!3XBJ%)M*oS>r4AhE;kSK%NVgPp}7jzELN+|Mtu>o%n?%=f0$&2rY_@)z(R)Q z3clUW{{Ho%MZxDk>={X>5EjW}O_$af#g)yA9<#cBKvr%fKD>(M0U6 zsy7|-y6IdNnCadgf9><}@oBW*?C`j$aAMQ{NyW-KGdemtJA2a;gsA()%Smbc*qU8b zQIIz^x0rACg1y%Aep6uZ{USR0-I&E}!X&F-$3C&bF>W}s^3<(fsYK1v(z3a^+0f81 zG&B?i1;yRnoq~cwr9{nY-oR{YUh(Y-yg~t=SMFYB78Vxo=UZGhv#}pFKC!*lRH9`a z$CU&yCIqcc$6pl@lb&7pyqEa$**aae^Uw zrxLc<1gV8fr!OD9R7)_k$&dydR)_P_}Ry4#igeDyt-++}-FROHy zQm*q;E;q4p{cJ7dYXq|c1!M@|3ioeX*%cke9AdDc$x}0CmZEiip^8(rn2N4iN>Z9` zOcsU*%YESHMLs3fP{S#Mn~y+hX;v?eP70oB`i|GW!)QS#L#VkPXrUZa|J`nGJg4p*}HqgfX~g$KHF7-h9f0c z&=1or5=u_SlEn0x7UAZbGOak8{46ghDfba6&)5Ri00<nMRoX5-VC#ncoj0^KEd- zR9vu;Hbn)FiJGW?*WZjHtr`qeN*MIu(6XfGBVQB@$vCXm8cOA5X#ERW@cvkj2vBD8Wf7a zkul7JAj?9wr3!W+qw1#oe6hS~OiWA*cD%HACY-zH2nHflKQU6YP_d|}sB-Q4n)-U% zscir7@bLKf_|nqS=x9`N<)6*EMYC6KZM#L2gHpT<_@{9o(0Z{l*^X*WL&L<#2s%6x zM`*P>ylj7yhJ?^|B<7IX(c+v%cl@*iyQHUN9*paTXeFhE$?NC4!Ovr-LkDAP_Kdsf z=QeXinpF}4@mll^jsHI$9xBZ&tqiz>>!*D0t0eNIrKF_f`E{)C5*j*mx%hkL$0 zIw~kcX_qfdC8&|AmCo}MRp#gaW)3mL3CnfkCyE}#2o+%*?Zu`uNd(OmVb#F1xj*#l^+Z(G%gntN(I1 zI2OjU%G(LqO&+6Kxqt2r{Xrv>g4#Pg#KyyuNpw*p*l>e-rVydVnCh3~e{}N^Vdui~kAk5B#2<9!N+?oM0Z;^9-4S=j{;U zA6HP1FE6OXf^A@M%cGLtbWAR_*PXmfi^<4XE7xhP2~C(U)uh7=(|koLEGz_{TbiIZ zujV{hbKxW>Cug@^Nf4VK%M`!|fPaZDu@U? z4g|m2+MAI?IuHm1@%sL9p?lbs6BTcGzSg|Gy$!TDpSbJ}AOk!+Jc^n85X_D{VgMLp z<d)!&=XoEPcu>cH=_@<_&-Vju<^C&zJ z&}N^@wXh&z;NWoEEHUG!AFeJD@cx4L%gZwkghd{)L&4`n>dG0-xaVn;3dX1LIH$z& zGgHdv#9Lz)^k8EohM};@K- z4)yo+JbQJUf9yPA36Tc#hr?$1eb)7OK&EZ0xoc>X6e$LWh6=v?Vra=DQxvm2)Ds7SS3H;U&?rPZmu-Q-eT>79ofEkr`LQs|0G|+ zTI1;HaLg!&IPg$k%O(=z96I>|(X302874NV=$}~fS--2WZ;AiX-3HqJ&-Y+&t6%iJ zg0o>${gLuZhk*9I&m!A3s{B<$?JdV`Vag+511nmGOZnZ%%@q0S0Y;Bq>U1Co-GtQRZxX|W`Oxls6A z&&ff(89Yw>{QMf_+KFjtR;O|E((#lWc55lO%wVVXn5Eb6;AdmQ=vpY(2@?6LSq)x+ zV^wV}A|fK$4^WX}me2dsAtNK0r0J7|g-_WS(^xLN16w->^`&;j`c z1u!r$5I8(P$$?m@+kR|)hs_W&(YKzpW+!n<6(jZwu%B^qVs-8GhcnRAH%0fx=45&^ z5!qk%fB;McnC~DfBcmFVVf6FSIT)yCle)}SwB;dH(vGg9)69ci5q|mzR1P`1o=p~m z>KWd4cn|&UPK>%^=9z&B7A8IrK|F^;&xb<4#%3XPy%fEHs!y)+It0P^ z(r<5>-!_>y`UpOqPtnnvCoq1wZcak_q<XF{C3wma1M41{ z7o#OvL;Kf?7fKO!_CT%6w0fo~{B`WC=z|8E9zpwp+(d!&s!3HAi^CysK#Q@b1O2`< z-0k|4Hy7=$ms{Nz9Xe=JO%kibLuyT+fkH7^76f%0Xz3It#O_4@Ju8A z6?PMh`=_7vlj2!beg05z7HO2z;JXQ+(%1@{D+go2BjElSxcjix{MXh1 literal 0 HcmV?d00001 diff --git a/docs/camera.rst b/docs/camera.rst new file mode 100644 index 0000000..817fc1f --- /dev/null +++ b/docs/camera.rst @@ -0,0 +1,537 @@ +hump.camera +=========== + +:: + + Camera = require "hump.camera" + +A camera utility for LÖVE. A camera can "look" at a position. It can zoom in +and out and it can rotate it's view. In the background, this is done by +actually moving, scaling and rotating everything in the game world. But don't +worry about that. + +**Example**:: + + function love.load() + cam = Camera(player.pos.x, player.pos.y) + end + + function love.update(dt) + local dx,dy = player.x - cam.x, player.y - cam.y + cam:move(dx/2, dy/2) + end + + +Function Reference +------------------ + +.. function:: Camera.new(x,y, zoom, rot) + + :param numbers x,y: Point for the camera to look at. (optional) + :param number zoom: Camera zoom. (optional) + :param number rot: Camera rotation in radians. (optional) + :returns: A new camera. + + +Creates a new camera. You can access the camera position using ``camera.x, +camera.y``, the zoom using ``camera.scale`` and the rotation using ``camera.rot``. + +The module variable name can be used at a shortcut to ``new()``. + +**Example**:: + + camera = require 'hump.camera' + -- camera looking at (100,100) with zoom 2 and rotated by 45 degrees + cam = camera(100,100, 2, math.pi/2) + + +.. function:: camera:move(dx,dy) + + :param numbers dx,dy: Direction to move the camera. + :returns: The camera. + + +Move the camera *by* some vector. To set the position, use +:func:`camera:lookAt`. + +This function is shortcut to ``camera.x,camera.y = camera.x+dx, camera.y+dy``. + +**Examples**:: + + function love.update(dt) + camera:move(dt * 5, dt * 6) + end + +:: + + function love.update(dt) + camera:move(dt * 5, dt * 6):rotate(dt) + end + + +.. function:: camera:lookAt(x,y) + + :param numbers x,y: Position to look at. + :returns: The camera. + + +Let the camera look at a point. In other words, it sets the camera position. To +move the camera *by* some amount, use :func:`camera:move`. + +This function is shortcut to ``camera.x,camera.y = x, y``. + +**Examples**:: + + function love.update(dt) + camera:lookAt(player.pos:unpack()) + end + +:: + + function love.update(dt) + camera:lookAt(player.pos:unpack()):rotation(player.rot) + end + +.. function:: camera:pos() + + :returns: ``x,y`` -- Camera position. + + +Returns ``camera.x, camera.y``. + +**Example**:: + + -- let the camera fly! + local cam_dx, cam_dy = 0, 0 + + function love.mousereleased(x,y) + local cx,cy = camera:position() + dx, dy = x-cx, y-cy + end + + function love.update(dt) + camera:move(dx * dt, dy * dt) + end + + +.. function:: camera:rotate(angle) + + :param number angle: Rotation angle in radians + :returns: The camera. + + +Rotate the camera by some angle. To set the angle use :func:`camera:rotateTo`. + +This function is shortcut to ``camera.rot = camera.rot + angle``. + +**Examples**:: + + function love.update(dt) + camera:rotate(dt) + end + +:: + + function love.update(dt) + camera:rotate(dt):move(dt,dt) + end + + +.. function:: camera:rotateTo(angle) + + :param number angle: Rotation angle in radians + :returns: The camera. + +Set rotation: ``camera.rot = angle``. + +**Example**:: + + camera:rotateTo(math.pi/2) + + +.. function:: camera:zoom(mul) + + :param number mul: Zoom change. Should be > 0. + :returns: The camera. + + +*Multiply* zoom: ``camera.scale = camera.scale * mul``. + +**Examples**:: + + camera:zoom(2) -- make everything twice as big + +:: + + camera:zoom(0.5) -- ... and back to normal + +:: + + camera:zoom(-1) -- mirror and flip everything upside down + + +.. function:: camera:zoomTo(zoom) + + :param number zoom: New zoom. + :returns: The camera. + + +Set zoom: ``camera.scale = zoom``. + +**Example**:: + + camera:zoomTo(1) -- reset zoom + + +.. function:: camera:attach() + +Start looking through the camera. + +Apply camera transformations, i.e. move, scale and rotate everything until +``camera:detach()`` as if looking through the camera. + +**Example**:: + + function love.draw() + camera:attach() + draw_world() + cam:detach() + + draw_hud() + end + + +.. function:: camera:detach() + +Stop looking through the camera. + +**Example**:: + + function love.draw() + camera:attach() + draw_world() + cam:detach() + + draw_hud() + end + + +.. function:: camera:draw(func) + + :param function func: Drawing function to be wrapped. + +Wrap a function between a ``camera:attach()``/``camera:detach()`` pair. +Equivalent to:: + + cam:attach() + func() + cam:detach() + + +**Example**:: + + function love.draw() + camera:draw(draw_world) + draw_hud() + end + + +.. function:: camera:worldCoords(x, y) + + :param numbers x, y: Point to transform. + :returns: ``x,y`` -- Transformed point. + +Because a camera has a point it looks at, a rotation and a zoom factor, it +defines a coordinate system. A point now has two sets of coordinates: One +defines where the point is to be found in the game world, and the other +describes the position on the computer screen. The first set of coordinates is +called world coordinates, the second one camera coordinates. Sometimes it is +needed to convert between the two coordinate systems, for example to get the +position of a mouse click in the game world in a strategy game, or to see if an +object is visible on the screen. + +:func:`camera:worldCoords` and :func:`camera:cameraCoords` transform points +between these two coordinate systems. + +**Example**:: + + x,y = camera:worldCoords(love.mouse.getPosition()) + selectedUnit:plotPath(x,y) + + +.. function:: camera:cameraCoords(x, y) + + :param numbers x, y: Point to transform. + :returns: ``x,y`` -- Transformed point. + + +Because a camera has a point it looks at, a rotation and a zoom factor, it +defines a coordinate system. A point now has two sets of coordinates: One +defines where the point is to be found in the game world, and the other +describes the position on the computer screen. The first set of coordinates is +called world coordinates, the second one camera coordinates. Sometimes it is +needed to convert between the two coordinate systems, for example to get the +position of a mouse click in the game world in a strategy game, or to see if an +object is visible on the screen. + +:func:`camera:worldCoords` and :func:`camera:cameraCoords` transform points +between these two coordinate systems. + +**Example**:: + + x,y = cam:cameraCoords(player.pos) + love.graphics.line(x, y, love.mouse.getPosition()) + + +.. function:: camera:mousepos() + + :returns: Mouse position in world coordinates. + + +Shortcut to ``camera:worldCoords(love.mouse.getPosition())``. + +**Example**:: + + x,y = camera:mousepos() + selectedUnit:plotPath(x,y) + + +Camera Movement Control +----------------------- + +Camera movement is one of these things that go almost unnoticed when done well, +but add a lot to the overall experience. +The article `Scroll Back: The Theory and Practice of Cameras in SideScrollers +`_ +by Itay Keren gives a lot of insight into how to design good camera systems. + +**hump.camera** offers functions that help to implement most of the techniques +discussed in the article. The functions :func:`camera:lockX`, +:func:`camera:lockY`, :func:`camera:lockPos`, and :func:`camera:lockWindow` +move the camera so that the interesting content stays in frame. +Note that the functions must be called every frame:: + + function love.update() + -- vertical locking + cam:lockX(player.pos.x) + end + + +All movements are subject to smoothing (see :ref:`Movement Smoothers +`). +You can specify a default movement smoother by assigning the variable +:attr:`camera.smoother`:: + + cam.smoother = Camera.smooth.linear(100) + + + +.. function:: camera:lockX(x, smoother, ...) + + :param number x: X coordinate (in world coordinates) to lock to. + :param function smoother: Movement smoothing override. (optional) + :param mixed ...: Additional parameters to the smoothing function. (optional) + +Horizontal camera locking: Keep the camera locked on the defined ``x``-position +(in *world coordinates*). They ``y``-position is not affected. + +You can define an off-center locking position by "aiming" the camera left or +right of your actual target. For example, to center the player 20 pixels to the +*left* of the screen, aim 20 pixels to it's *right* (see examples). + +**Examples**:: + + -- lock on player vertically + cam:lockX(player.x) + +:: + + -- ... with linear smoothing at 25 px/s + cam:lockX(player.x, Camera.smooth.linear(25)) + +:: + + -- lock player 20px left of center + cam:lockX(player.x + 20) + + + +.. function:: camera:lockY(y, smoother, ...) + + :param number y: Y coordinate (in world coordinates) to lock to. + :param function smoother: Movement smoothing override. (optional) + :param mixed ...: Additional parameters to the smoothing function. (optional) + +Vertical camera locking: Keep the camera locked on the defined ``y``-position +(in *world coordinates*). They ``x``-position is not affected. + +You can define an off-center locking position by "aiming" the camera above or +below your actual target. For example, to center the player 20 pixels *below* the +screen center, aim 20 pixels *above* it (see examples). + +**Examples**:: + + -- lock on player horizontally + cam:lockY(player.y) + +:: + + -- ... with damped smoothing with a stiffness of 10 + cam:lockY(player.y, Camera.smooth.damped(10)) + +:: + + -- lock player 20px below the screen center + cam:lockY(player.y - 20) + + + +.. function:: camera:lockPos(x,y, smoother, ...) + + :param numbers x,y: Position (in world coordinates) to lock to. + :param function smoother: Movement smoothing override. (optional) + :param mixed ...: Additional parameters to the smoothing function. (optional) + +Horizontal and vertical camera locking: Keep the camera locked on the defined +position (in *world coordinates*). + +You can define an off-center locking position by "aiming" the camera to the +opposite direction away from your real target. +For example, to center the player 10 pixels to the *left* and 20 pixels *above* +the screen center, aim 10 pixels to the *right* and 20 pixels *below*. + +**Examples**:: + + -- lock on player + cam:lock(player.x, player.y) + +:: + + -- lock 50 pixels into player's aiming direction + cam:lockY(player.x - player.aiming.x * 50, player.y - player.aiming.y * 50) + + + +.. function:: camera:lockWindow(x,y, x_min, x_max, y_min, y_max, smoother, ...) + + :param numbers x,y: Position (in world coordinates) to lock to. + :param numbers x_min: Upper left X coordinate of the camera window *(in camera coordinates!)*. + :param numbers x_max: Lower right X coordinate of the camera window *(in camera coordinates!)*. + :param numbers y_min: Upper left Y coordinate of the camera window *(in camera coordinates!)*. + :param numbers y_max: Lower right Y coordinate of the camera window *(in camera coordinates!)*. + :param function smoother: Movement smoothing override. (optional) + :param mixed ...: Additional parameters to the smoothing function. (optional) + +The most powerful locking method: Lock camera to ``x,y``, but only move the +camera if the position would be out of the screen-rectangle defined by ``x_min``, +``x_max``, ``y_min``, ``y_max``. + +.. note:: + The locking window is defined in camera coordinates, whereas the position to + lock to is defined in world coordinates! + +All of the other locking methods can be implemted by window locking. For +position locking, set ``x_min = x_max`` and ``y_min = y_max``. +Off-center locking can be done by defining the locking window accordingly. + +**Examples**:: + + -- lock on player + cam:lock(player.x, player.y) + +.. attribute:: camera.smoother + +The default smoothing operator. Must be a ``function`` with the following +prototype:: + + function customSmoother(dx,dy, ...) + do_stuff() + return new_dx,new_dy + end + +where ``dx,dy`` is the offset the camera would move before smoothing and +``new_dx, new_dy`` is the offset the camera should move after smoothing. + + +.. _movement-smoothers: + +Movement Smoothers +^^^^^^^^^^^^^^^^^^ + +It is not always desirable that the camera instantly locks on a target. +`Platform snapping +`_, +for example, would look terrible if the camera would instantly jump to the +focussed platform. +Smoothly moving the camera to the locked position can also give the illusion of +a camera operator an add to the overall feel of your game. + +**hump.camera** allows to smooth the movement by either passing movement +smoother functions to the locking functions or by setting a default smoother +(see :attr:`camera.smoother`). + +Smoothing functions must have the following prototype:: + + function customSmoother(dx,dy, ...) + do_stuff() + return new_dx,new_dy + end + +where ``dx,dy`` is the offset the camera would move before smoothing and +``new_dx, new_dy`` is the offset the camera should move after smoothing. + +This is a simple "rubber-band" smoother:: + + function rubber_band(dx,dy) + local dt = love.timer.getDelta() + return dx*dt, dy*dt + end + +**hump.camera** defines generators for the most common smoothers: + +.. function:: Camera.smooth.none() + + :returns: Smoothing function. + +Dummy smoother: does not smooth the motion. + +**Example**:: + + cam.smoother = Camera.smooth.none() + + +.. function:: Camera.smooth.linear(speed) + + :param number speed: Smoothing speed. + :returns: Smoothing function. + +Smoothly moves the camera towards to snapping goal with constant speed. + +**Examples**:: + + cam.smoother = Camera.smooth.linear(100) + +:: + + -- warning: creates a function every frame! + cam:lockX(player.x, Camera.smooth.linear(25)) + + +.. function:: Camera.smooth.damped(stiffness) + + :param number stiffness: Speed of the camera movement. + :returns: Smoothing function. + +Smoothly moves the camera towards the goal with a speed proportional to the +distance to the target. +Stiffness defines the speed of the motion: Higher values mean that the camera +moves more quickly. + +**Examples**:: + + cam.smoother = Camera.smooth.damped(10) + +:: + + -- warning: creates a function every frame! + cam:lockPos(player.x, player.y, Camera.smooth.damped(2)) diff --git a/docs/class.rst b/docs/class.rst new file mode 100644 index 0000000..827e131 --- /dev/null +++ b/docs/class.rst @@ -0,0 +1,344 @@ +hump.class +========== + +:: + + Class = require "hump.class" + +A small, fast class/prototype implementation with multiple inheritance. + +Implements `class commons `_. + +**Example**:: + + Critter = Class{ + init = function(self, pos, img) + self.pos = pos + self.img = img + end, + speed = 5 + } + + function Critter:update(dt, player) + -- see hump.vector + local dir = (player.pos - self.pos):normalize_inplace() + self.pos = self.pos + dir * Critter.speed * dt + end + + function Critter:draw() + love.graphics.draw(self.img, self.pos.x, self.pos.y) + end + +Function Reference +------------------ + +.. function:: Class.new({init = constructor, __includes = parents, ...}) + + :param function constructor: Class constructor. Can be accessed with ``theclass.init(object, ...)``. (optional) + :param class or table of classes parents: Classes to inherit from. Can either be a single class or a table of classes. (optional) + :param mixed ...: Any other fields or methods common to all instances of this class. (optional) + :returns: The class. + + +Declare a new class. + +``init()`` will receive the new object instance as first argument. Any other +arguments will also be forwarded (see examples), i.e. ``init()`` has the +following signature:: + + function init(self, ...) + +If you do not specify a constructor, an empty constructor will be used instead. + +The name of the variable that holds the module can be used as a shortcut to +``new()`` (see example). + +**Examples**:: + + Class = require 'hump.class' -- `Class' is now a shortcut to new() + + -- define a class class + Feline = Class{ + init = function(self, size, weight) + self.size = size + self.weight = weight + end; + -- define a method + stats = function(self) + return string.format("size: %.02f, weight: %.02f", self.size, self.weight) + end; + } + + -- create two objects + garfield = Feline(.7, 45) + felix = Feline(.8, 12) + + print("Garfield: " .. garfield:stats(), "Felix: " .. felix:stats()) + +:: + + Class = require 'hump.class' + + -- same as above, but with 'external' function definitions + Feline = Class{} + + function Feline:init(size, weight) + self.size = size + self.weight = weight + end + + function Feline:stats() + return string.format("size: %.02f, weight: %.02f", self.size, self.weight) + end + + garfield = Feline(.7, 45) + print(Feline, garfield) + +:: + + Class = require 'hump.class' + A = Class{ + foo = function() print('foo') end + } + + B = Class{ + bar = function() print('bar') end + } + + -- single inheritance + C = Class{__includes = A} + instance = C() + instance:foo() -- prints 'foo' + instance:bar() -- error: function not defined + + -- multiple inheritance + D = Class{__includes = {A,B}} + instance = D() + instance:foo() -- prints 'foo' + instance:bar() -- prints 'bar' + +:: + + -- class attributes are shared across instances + A = Class{ foo = 'foo' } -- foo is a class attribute/static member + + one, two, three = A(), A(), A() + print(one.foo, two.foo, three.foo) --> prints 'foo foo foo' + + one.foo = 'bar' -- overwrite/specify for instance `one' only + print(one.foo, two.foo, three.foo) --> prints 'bar foo foo' + + A.foo = 'baz' -- overwrite for all instances without specification + print(one.foo, two.foo, three.foo) --> prints 'bar baz baz' + + +.. function:: class.init(object, ...) + + :param Object object: The object. Usually ``self``. + :param mixed ...: Arguments to pass to the constructor. + :returns: Whatever the parent class constructor returns. + + +Calls class constructor of a class on an object. + +Derived classes should use this function their constructors to initialize the +parent class(es) portions of the object. + +**Example**:: + + Class = require 'hump.class' + + Shape = Class{ + init = function(self, area) + self.area = area + end; + __tostring = function(self) + return "area = " .. self.area + end + } + + Rectangle = Class{__includes = Shape, + init = function(self, width, height) + Shape.init(self, width * height) + self.width = width + self.height = height + end; + __tostring = function(self) + local strs = { + "width = " .. self.width, + "height = " .. self.height, + Shape.__tostring(self) + } + return table.concat(strs, ", ") + end + } + + print( Rectangle(2,4) ) -- prints 'width = 2, height = 4, area = 8' + + +.. function:: Class:include(other) + + :param tables other: Parent classes/mixins. + :returns: The class. + + +Inherit functions and variables of another class, but only if they are not +already defined. This is done by (deeply) copying the functions and variables +over to the subclass. + +.. note:: + ``class:include()`` doesn't actually care if the arguments supplied are + hump classes. Just any table will work. + +.. note:: + You can use ``Class.include(a, b)`` to copy any fields from table ``a`` + to table ``b`` (see second example). + +**Examples**:: + + Class = require 'hump.class' + + Entity = Class{ + init = function(self) + GameObjects.register(self) + end + } + + Collidable = { + dispatch_collision = function(self, other, dx, dy) + if self.collision_handler[other.type]) + return collision_handler[other.type](self, other, dx, dy) + end + return collision_handler["*"](self, other, dx, dy) + end, + + collision_handler = {["*"] = function() end}, + } + + Spaceship = Class{ + init = function(self) + self.type = "Spaceship" + -- ... + end + } + + -- make Spaceship collidable + Spaceship:include(Collidable) + + Spaceship.collision_handler["Spaceship"] = function(self, other, dx, dy) + -- ... + end + +:: + + -- using Class.include() + Class = require 'hump.class' + a = { + foo = 'bar', + bar = {one = 1, two = 2, three = 3}, + baz = function() print('baz') end, + } + b = { + foo = 'nothing to see here...' + } + + Class.include(b, a) -- copy values from a to b + -- note that neither a nor b are hump classes! + + print(a.foo, b.foo) -- prints 'bar nothing to see here...' + + b.baz() -- prints 'baz' + + b.bar.one = 10 -- changes only values in b + print(a.bar.one, b.bar.one) -- prints '1 10' + + +.. function:: class:clone() + + :returns: A deep copy of the class/table. + + +Create a clone/deep copy of the class. + +.. note:: + You can use ``Class.clone(a)`` to create a deep copy of any table (see + second example). + +**Examples**:: + + Class = require 'hump.class' + + point = Class{ x = 0, y = 0 } + + a = point:clone() + a.x, a.y = 10, 10 + print(a.x, a.y) --> prints '10 10' + + b = point:clone() + print(b.x, b.y) --> prints '0 0' + + c = a:clone() + print(c.x, c.y) --> prints '10 10' + +:: + + -- using Class.clone() to copy tables + Class = require 'hump.class' + a = { + foo = 'bar', + bar = {one = 1, two = 2, three = 3}, + baz = function() print('baz') end, + } + b = Class.clone(a) + + b.baz() -- prints 'baz' + b.bar.one = 10 + print(a.bar.one, b.bar.one) -- prints '1 10' + + + +Caveats +------- + +Be careful when using metamethods like ``__add`` or ``__mul``: If a subclass +inherits those methods from a superclass, but does not overwrite them, the +result of the operation may be of the type superclass. Consider the following:: + + Class = require 'hump.class' + + A = Class{init = function(self, x) self.x = x end} + function A:__add(other) return A(self.x + other.x) end + function A:show() print("A:", self.x) end + + B = Class{init = function(self, x, y) A.init(self, x) self.y = y end} + function B:show() print("B:", self.x, self.y) end + function B:foo() print("foo") end + B:include(A) + + one, two = B(1,2), B(3,4) + result = one + two -- result will be of type A, *not* B! + result:show() -- prints "A: 4" + result:foo() -- error: method does not exist + +Note that while you can define the ``__index`` metamethod of the class, this is +not a good idea: It will break the class mechanism. To add a custom ``__index`` +metamethod without breaking the class system, you have to use ``rawget()``. But +beware that this won't affect subclasses:: + + Class = require 'hump.class' + + A = Class{} + function A:foo() print('bar') end + + function A:__index(key) + print(key) + return rawget(A, key) + end + + instance = A() + instance:foo() -- prints foo bar + + B = Class{__includes = A} + instance = B() + instance:foo() -- prints only foo + diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..26894ca --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,293 @@ +# -*- coding: utf-8 -*- +# +# hump documentation build configuration file, created by +# sphinx-quickstart on Sat Oct 10 13:10:12 2015. +# +# 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 +import os +import shlex + +# 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 = [ + 'sphinx.ext.mathjax', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +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'hump' +copyright = u'2015, Matthias Richter' +author = u'Matthias Richter' + +# 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 = '1.0' +# The full version, including alpha/beta/rc tags. +release = '1.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +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 = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- 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 = 'alabaster' + +# 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 = {} + +# 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 +# " v 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 = None + +# 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'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# 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 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 + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +#html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +#html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +#html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'humpdoc' + +# -- 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': '', + +# Latex figure (float) alignment +#'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'hump.tex', u'hump Documentation', + u'Matthias Richter', '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 = [ + (master_doc, 'hump', u'hump Documentation', + [author], 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 = [ + (master_doc, 'hump', u'hump Documentation', + author, 'hump', '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' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + +primary_domain = "js" +highlight_language = "lua" + +import sphinx_rtd_theme +html_theme = 'sphinx_rtd_theme' +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] diff --git a/docs/gamestate.rst b/docs/gamestate.rst new file mode 100644 index 0000000..c8ad77f --- /dev/null +++ b/docs/gamestate.rst @@ -0,0 +1,349 @@ +hump.gamestate +============== + +:: + + Gamestate = require "hump.gamestate" + +A gamestate encapsulates independent data an behaviour in a single table. + +A typical game could consist of a menu-state, a level-state and a game-over-state. + +**Example**:: + + local menu = {} -- previously: Gamestate.new() + local game = {} + + function menu:draw() + love.graphics.print("Press Enter to continue", 10, 10) + end + + function menu:keyreleased(key, code) + if key == 'enter' then + Gamestate.switch(game) + end + end + + function game:enter() + Entities.clear() + -- setup entities here + end + + function game:update(dt) + Entities.update(dt) + end + + function game:draw() + Entities.draw() + end + + function love.load() + Gamestate.registerEvents() + Gamestate.switch(menu) + end + + +.. _callbacks: + +Gamestate Callbacks +------------------- + +A gamestate can define all callbacks that LÖVE defines. In addition, there are +callbacks for initalizing, entering and leaving a state: + +``init()`` + Called once, and only once, before entering the state the first time. See + :func:`Gamestate.switch`. + +``enter(previous, ...)`` + Called every time when entering the state. See :func:`Gamestate.switch`. + +``leave()`` + Called when leaving a state. See :func:`Gamestate.switch` and :func:`Gamestate.push`. + +``resume()`` + Called when re-entering a state by :func:`Gamestate.pop`-ing another state. + +``update()`` + Update the game state. Called every frame. + +``draw()`` + Draw on the screen. Called every frame. + +``focus()`` + Called if the window gets or looses focus. + +``keypressed()`` + Triggered when a key is pressed. + +``keyreleased()`` + Triggered when a key is released. + +``mousepressed()`` + Triggered when a mouse button is pressed. + +``mousereleased()`` + Triggered when a mouse button is released. + +``joystickpressed()`` + Triggered when a joystick button is pressed. + +``joystickreleased()`` + Triggered when a joystick button is released. + +``quit()`` + Called on quitting the game. Only called on the active gamestate. + +When using :func:`Gamestate.registerEvents`, all these callbacks will be called by the +corresponding LÖVE callbacks and receive receive the same arguments (e.g. +``state:update(dt)`` will be called by ``love.update(dt)``). + +**Example**:: + + menu = {} -- previously: Gamestate.new() + self.background = love.graphics.newImage('bg.jpg') + Buttons.initialize() + end + + function menu:enter(previous) -- runs every time the state is entered + Buttons.setActive(Buttons.start) + end + + function menu:update(dt) -- runs every frame + Buttons.update(dt) + end + + function menu:draw() + love.graphics.draw(self.background, 0, 0) + Buttons.draw() + end + + function menu:keyreleased(key) + if key == 'up' then + Buttons.selectPrevious() + elseif key == 'down' then + Buttons.selectNext() + elseif + Buttons.active:onClick() + end + end + + function menu:mousereleased(x,y, mouse_btn) + local button = Buttons.hovered(x,y) + if button then + Button.select(button) + if mouse_btn == 'l' then + button:onClick() + end + end + end + + +Function Reference +------------------ + +.. function:: Gamestate.new() + + :returns: An empty table. + + +**Deprecated: Use the table constructor instead (see example)** + +Declare a new gamestate (just an empty table). A gamestate can define several +callbacks. + +**Example**:: + + menu = {} + -- deprecated method: + menu = Gamestate.new() + + +.. function:: Gamestate.switch(to, ...) + + :param Gamestate to: Target gamestate. + :param mixed ...: Additional arguments to pass to ``to:enter(current, ...)``. + :returns: The results of ``to:enter(current, ...)``. + + +Switch to a gamestate, with any additional arguments passed to the new state. + +Switching a gamestate will call the ``leave()`` callback on the current +gamestate, replace the current gamestate with ``to``, call the ``init()`` function +if, and only if, the state was not yet inialized and finally call +``enter(old_state, ...)`` on the new gamestate. + +.. note:: + Processing of callbacks is suspended until ``update()`` is called on the new + gamestate, but the function calling :func:`Gamestate.switch` can still continue - it is + your job to make sure this is handled correctly. See also the examples below. + + +**Examples**:: + + Gamestate.switch(game, level_two) + +:: + + -- stop execution of the current state by using return + if player.has_died then + return Gamestate.switch(game, level_two) + end + + -- this will not be called when the state is switched + player:update() + + + +.. function:: Gamestate.Gamestate.current() + + :returns: The active gamestate. + +Returns the currently activated gamestate. + +**Example**:: + + function love.keypressed(key) + if Gamestate.current() ~= menu and key == 'p' then + Gamestate.push(pause) + end + end + + +.. function:: Gamestate.push(to, ...) + + :param Gamestate to: Target gamestate. + :param mixed ...: Additional arguments to pass to ``to:enter(current, ...)``. + :returns: The results of ``to:enter(current, ...)``. + +Pushes the ``to`` on top of the state stack, i.e. makes it the active state. +Semantics are the same as ``switch(to, ...)``, except that ``leave()`` is *not* +called on the previously active state. + +Useful for pause screens, menus, etc. + +.. note:: + Processing of callbacks is suspended until ``update()`` is called on the + new gamestate, but the function calling ``GS.push()`` can still continue - + it is your job to make sure this is handled correctly. See also the + example below. + + +**Example**:: + + -- pause gamestate + Pause = Gamestate.new() + function Pause:enter(from) + self.from = from -- record previous state + end + + function Pause:draw() + local W, H = love.graphics.getWidth(), love.graphics.getHeight() + -- draw previous screen + self.from:draw() + -- overlay with pause message + love.graphics.setColor(0,0,0, 100) + love.graphics.rectangle('fill', 0,0, W,H) + love.graphics.setColor(255,255,255) + love.graphics.printf('PAUSE', 0, H/2, W, 'center') + end + + -- [...] + function love.keypressed(key) + if Gamestate.current() ~= menu and key == 'p' then + return Gamestate.push(pause) + end + end + + +.. function:: Gamestate.pop(...) + + :returns: The results of ``new_state:resume(...)``. + +Calls ``leave()`` on the current state and then removes it from the stack, making +the state below the current state and calls ``resume(...)`` on the activated state. +Does *not* call ``enter()`` on the activated state. + +.. note:: + Processing of callbacks is suspended until ``update()`` is called on the + new gamestate, but the function calling ``GS.pop()`` can still continue - + it is your job to make sure this is handled correctly. See also the + example below. + + +**Example**:: + + -- extending the example of Gamestate.push() above + function Pause:keypressed(key) + if key == 'p' then + return Gamestate.pop() -- return to previous state + end + end + + +.. function:: Gamestate.(...) + + :param mixed ...: Arguments to pass to the corresponding function. + :returns: The result of the callback function. + +Calls a function on the current gamestate. Can be any function, but is intended +to be one of the :ref:`callbacks`. Mostly useful when not using +:func:`Gamestate.registerEvents`. + +**Example**:: + + function love.draw() + Gamestate.draw() -- is `draw' + end + + function love.update(dt) + Gamestate.update(dt) -- pass dt to currentState:update(dt) + end + + function love.keypressed(key, code) + Gamestate.keypressed(key, code) -- pass multiple arguments + end + + +.. function:: Gamestate.registerEvents([callbacks]) + + :param table callbacks: Names of the callbacks to register. If omitted, + register all love callbacks (optional). + +Overwrite love callbacks to call ``Gamestate.update()``, ``Gamestate.draw()``, +etc. automatically. ``love`` callbacks (e.g. ``love.update()``) are still +invoked as usual. + +This is by done by overwriting the love callbacks, e.g.:: + + local old_update = love.update + function love.update(dt) + old_update(dt) + return Gamestate.current:update(dt) + end + +.. note:: + Only works when called in love.load() or any other function that is + executed *after* the whole file is loaded. + +**Examples**:: + + function love.load() + Gamestate.registerEvents() + Gamestate.switch(menu) + end + + -- love callback will still be invoked + function love.update(dt) + Timer.update(dt) + -- no need for Gamestate.update(dt) + end + +:: + + function love.load() + -- only register draw, update and quit + Gamestate.registerEvents{'draw', 'update', 'quit'} + Gamestate.switch(menu) + end + diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..9d4de63 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,52 @@ +**hump** - Helper Utilities for a Multitude of Problems +======================================================= + +**hump** is a set of lightweight helpers for the awesome `LÖVE +`_ game framework. It will help to get you over the initial +hump when starting to build a new game. + +**hump** differs from many other libraries in that every component is +independent of the remaining ones. +The footprint is very small, so the library should fit nicely into your +projects. + +Read on +------- + +.. toctree:: + :maxdepth: 2 + + hump.gamestate + hump.timer + hump.vector + hump.vector-light + hump.class + hump.signal + hump.camera + license + + +Get hump +-------- + +You can view and download the individual modules on github: `vrld/hump +`_. +You may also download the whole packed sourcecode either in the `zip +`_ or `tar +`_ format. + +Using `Git `_, you can clone the project by running: + + git clone git://github.com/vrld/hump + +Once done, tou can check for updates by running + + git pull + + +Indices and tables +------------------ + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/license.rst b/docs/license.rst new file mode 100644 index 0000000..9ad08e0 --- /dev/null +++ b/docs/license.rst @@ -0,0 +1,26 @@ +License +======= + +Copyright (c) 2011-2015 Matthias Richter + +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. + +Except as contained in this notice, the name(s) of the above copyright holders +shall not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization. + +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/docs/signal.rst b/docs/signal.rst new file mode 100644 index 0000000..c42a3c0 --- /dev/null +++ b/docs/signal.rst @@ -0,0 +1,180 @@ +hump.signal +=========== + +:: + + Signal = require 'hump.signal' + +A simple yet effective implementation of `Signals and Slots +`_, aka the `Observer pattern +`_: Functions can be dynamically +bound to signals. When a *signal* is *emitted*, all registered functions will +be invoked. Simple as that. + +``hump.signal`` makes things a little more interesing by allowing to emit all +signals that match a `Lua string pattern +`_. + +**Example**:: + + -- in AI.lua + signals.register('shoot', function(x,y, dx,dy) + -- for every critter in the path of the bullet: + -- try to avoid being hit + for critter in pairs(critters) do + if critter:intersectsRay(x,y, dx,dy) then + critter:setMoveDirection(-dy, dx) + end + end + end) + + -- in sounds.lua + signals.register('shoot', function() + Sounds.fire_bullet:play() + end) + + -- in main.lua + function love.keypressed(key) + if key == ' ' then + local x,y = player.pos:unpack() + local dx,dy = player.direction:unpack() + signals.emit('shoot', x,y, dx,dy) + end + end + +Function Reference +------------------ + +.. function:: Signal.new() + + :returns: A new signal registry. + +Creates a new signal registry that is independent of the default registry: It +will manage it's own list of signals and does not in any way affect the the +global registry. Likewise, the global registry does not affect the instance. + +.. note:: + If you don't need multiple independent registries, you can use the + global/default registry (see examples). + +**Example**:: + + player.signals = Signal.new() + + +.. function:: Signal.register(s, f) + + :param string s: The signal identifier. + :param function f: The function to register. + :returns: A function handle to use in :func:`Signal.remove()`. + + +Registers a function ``f`` to be called when signal ``s`` is emitted. + +**Examples**:: + + Signal.register('level-complete', function() self.fanfare:play() end) + +:: + + handle = Signal.register('level-load', function(level) level.show_help() end) + +:: + + menu:register('key-left', select_previous_item) + + +.. function:: Signal.emit(s, ...) + + :param string s: The signal identifier. + :param mixed ...: Arguments to pass to the bound functions. (optional) + + +Calls all functions bound to signal ``s`` with the supplied arguments. + + +**Examples**:: + + function love.keypressed(key) + -- using a signal instance + if key == 'left' then menu:emit('key-left') end + end + +:: + + if level.is_finished() then + -- adding arguments + Signal.emit('level-load', level.next_level) + end + + +.. function:: Signal.remove(s, ...) + + :param string s: The signal identifier. + :param functions ...: Functions to unbind from the signal. + + +Unbinds (removes) functions from signal ``s``. + +**Example**:: + + Signal.remove('level-load', handle) + + +.. function:: Signal.clear(s) + + :param string s: The signal identifier. + + +Removes all functions from signal ``s``. + +**Example**:: + + Signal.clear('key-left') + + +.. function:: Signal.emitPattern(p, ...) + + :param string p: The signal identifier pattern. + :param mixed ...: Arguments to pass to the bound functions. (optional) + + +Emits all signals that match a `Lua string pattern +`_. + +**Example**:: + + -- emit all update signals + Signal.emitPattern('^update%-.*', dt) + + +.. function:: Signal.removePattern(p, ...) + + :param string p: The signal identifier pattern. + :param functions ...: Functions to unbind from the signals. + + +Removes functions from all signals that match a `Lua string pattern +`_. + +**Example**:: + + Signal.removePattern('key%-.*', play_click_sound) + + +.. function:: Signal.clearPattern(p) + + :param string p: The signal identifier pattern. + + +Removes **all** functions from all signals that match a `Lua string pattern +`_. + +**Examples**:: + + Signal.clearPattern('sound%-.*') + +:: + + player.signals:clearPattern('.*') -- clear all signals + diff --git a/docs/timer.rst b/docs/timer.rst new file mode 100644 index 0000000..f936646 --- /dev/null +++ b/docs/timer.rst @@ -0,0 +1,396 @@ +hump.timer +========== + +:: + + Timer = require "hump.timer" + +hump.timer offers a simple interface to schedule the execution of functions. It +is possible to run functions *after* and *for* some amount of time. For +example, a timer could be set to move critters every 5 seconds or to make the +player invincible for a short amount of time. + +In addition to that, ``hump.timer`` offers various `tweening +`_ functions that make it +easier to produce `juicy games `_. + +**Example**:: + + function love.keypressed(key) + if key == ' ' then + Timer.after(1, function() print("Hello, world!") end) + end + end + + function love.update(dt) + Timer.update(dt) + end + +Function Reference +------------------ + +.. function:: Timer.new() + + :returns: A timer instance. + + +Creates a new timer instance that is independent of the global timer: It will +manage it's own list of scheduled functions and does not in any way affect the +the global timer. Likewise, the global timer does not affect timer instances. + +.. note:: + If you don't need multiple independent schedulers, you can use the + global/default timer (see examples). + +**Example**:: + + menuTimer = Timer.new() + + +.. function:: Timer.after(delay, func) + + :param number delay: Number of seconds the function will be delayed. + :param function func: The function to be delayed. + :returns: The timer handle. See also :func:`Timer.cancel`. + + +Schedule a function. The function will be executed after ``delay`` seconds have +elapsed, given that ``update(dt)`` is called every frame. + +.. note:: + There is no guarantee that the delay will not be exceeded, it is only + guaranteed that the function will *not* be executed *before* the delay has + passed. + +``func`` will receive itself as only parameter. This is useful to implement +periodic behavior (see the example). + +**Examples**:: + + -- grant the player 5 seconds of immortality + player.isInvincible = true + Timer.after(5, function() player.isInvincible = false end) + +:: + + -- print "foo" every second. See also every() + Timer.after(1, function(func) print("foo") Timer.after(1, func) end) + +:: + + --Using a timer instance: + menuTimer:after(1, finishAnimation) + + +.. function:: Timer.every(delay, func[, count]) + + :param number delay: Number of seconds between two consecutive function calls. + :param function func: The function to be called periodically. + :param number count: Number of times the function is to be called (optional). + :returns: The timer handle. See also :func:`Timer.cancel`. + + +Add a function that will be called ``count`` times every ``delay`` seconds. + +If ``count`` is omitted, the function will be called until it returns ``false`` +or :func:`Timer.cancel` or :func:`Timer.clear` is called on the timer instance. + +**Example**:: + + -- toggle light on and off every second + Timer.every(1, function() lamp:toggleLight() end) + +:: + + -- launch 5 fighters in quick succession (using a timer instance) + mothership_timer.every(0.3, function() self:launchFighter() end, 5) + +:: + + -- flicker player's image as long as he is invincible + Timer.every(0.1, function() + player:flipImage() + return player.isInvincible + end) + + +.. function:: Timer.during(delay, func[, after]) + + :param number delay: Number of seconds the func will be called. + :param function func: The function to be called on ``update(dt)``. + :param function after: A function to be called after delay seconds (optional). + :returns: The timer handle. See also :func:`Timer.cancel`. + + +Run ``func(dt)`` for the next ``delay`` seconds. The function is called every +time ``update(dt)`` is called. Optionally run ``after()`` once ``delay`` +seconds have passed. + +``after()`` will receive itself as only parameter. + +.. note:: + You should not add new timers in ``func(dt)``, as this can lead to random + crashes. + +**Examples**:: + + -- play an animation for 5 seconds + Timer.during(5, function(dt) animation:update(dt) end) + +:: + + -- shake the camera for one second + local orig_x, orig_y = camera:pos() + Timer.during(1, function() + camera:lookAt(orig_x + math.random(-2,2), orig_y + math.random(-2,2)) + end, function() + -- reset camera position + camera:lookAt(orig_x, orig_y) + end) + +:: + + player.isInvincible = true + -- flash player for 3 seconds + local t = 0 + player.timer.during(3, function(dt) + t = t + dt + player.visible = (t % .2) < .1 + end, function() + -- make sure the player is visible after three seconds + player.visible = true + player.isInvincible = false + end) + + +.. function:: Timer.cancel(handle) + + :param table handle: The function to be canceled. + +Prevent a timer from being executed in the future. + +**Examples**:: + + function tick() + print('tick... tock...') + end + handle = Timer.every(1, tick) + -- later + Timer.cancel(handle) -- NOT: Timer.cancel(tick) + +:: + + -- using a timer instance + function tick() + print('tick... tock...') + end + handle = menuTimer:every(1, tick) + -- later + menuTimer:cancel(handle) + + +.. function:: Timer.clear() + +Remove all timed and periodic functions. Functions that have not yet been +executed will discarded. + +**Examples**:: + + Timer.clear() + +:: + + menu_timer:clear() + + +.. function:: Timer.update(dt) + + :param number dt: Time that has passed since the last ``update()``. + +Update timers and execute functions if the deadline is reached. Call in +``love.update(dt)``. + +**Examples**:: + + function love.update(dt) + do_stuff() + Timer.update(dt) + end + +:: + + -- using hump.gamestate and a timer instance + function menuState:update(dt) + self.timer.update(dt) + end + + +.. function:: Timer.tween(duration, subject, target, method, after, ...) + + :param number duration: Duration of the tween. + :param table subject: Object to be tweened. + :param table target: Target values. + :param string method: Tweening method, defaults to 'linear' (:ref:`see here + `, optional). + :param function after: Function to execute after the tween has finished + (optiona). + :param mixed ...: Additional arguments to the *tweening* function. + :returns: A timer handle. + + +`Tweening `_ (short for +in-betweening) is the process that happens between two defined states. For +example, a tween can be used to gradually fade out a graphic or move a text +message to the center of the screen. For more information why tweening should +be important to you, check out this great talk on `juicy games +`_. + +``hump.timer`` offers two interfaces for tweening: the low-level +:func:`Timer.during` and the higher level interface :func:`Timer.tween`. + +To see which tweening methods hump offers, :ref:`see below `. + +**Examples**:: + + function love.load() + color = {0, 0, 0} + Timer.tween(10, color, {255, 255, 255}, 'in-out-quad') + end + + function love.update(dt) + Timer.update(dt) + end + + function love.draw() + love.graphics.setBackgroundColor(color) + end + +:: + + function love.load() + circle = {rad = 10, pos = {x = 400, y = 300}} + -- multiple tweens can work on the same subject + -- and nested values can be tweened, too + Timer.tween(5, circle, {rad = 50}, 'in-out-quad') + Timer.tween(2, circle, {pos = {y = 550}}, 'out-bounce') + end + + function love.update(dt) + Timer.update(dt) + end + + function love.draw() + love.graphics.circle('fill', circle.pos.x, circle.pos.y, circle.rad) + end + +:: + + function love.load() + -- repeated tweening + + circle = {rad = 10, x = 100, y = 100} + local grow, shrink, move_down, move_up + grow = function() + Timer.tween(1, circle, {rad = 50}, 'in-out-quad', shrink) + end + shrink = function() + Timer.tween(2, circle, {rad = 10}, 'in-out-quad', grow) + end + + move_down = function() + Timer.tween(3, circle, {x = 700, y = 500}, 'bounce', move_up) + end + move_up = function() + Timer.tween(5, circle, {x = 200, y = 200}, 'out-elastic', move_down) + end + + grow() + move_down() + end + + function love.update(dt) + Timer.update(dt) + end + + function love.draw() + love.graphics.circle('fill', circle.x, circle.y, circle.rad) + end + + + +.. _tweening-methods: + +Tweening methods +---------------- + +At the core of tweening lie interpolation methods. These methods define how the +output should look depending on how much time has passed. For example, consider +the following tween:: + + -- now: player.x = 0, player.y = 0 + Timer.tween(2, player, {x = 2}) + Timer.tween(4, player, {y = 8}) + +At the beginning of the tweens (no time passed), the interpolation method would +place the player at ``x = 0, y = 0``. After one second, the player should be at +``x = 1, y = 2``, and after two seconds the output is ``x = 2, y = 4``. + +The actual duration of and time since starting the tween is not important, only +the fraction of the two. Similarly, the starting value and output are not +important to the interpolation method, since it can be calculated from the +start and end point. Thus an interpolation method can be fully characterized by +a function that takes a number between 0 and 1 and returns a number that +defines the output (usually also between 0 and 1). The interpolation function +must hold that the output is 0 for input 0 and 1 for input 1. + +**hump** predefines several commonly used interpolation methods, which are +generalized versions of `Robert Penner's easing +functions `_. Those are: + +``'linear'``, +``'quad'``, +``'cubic'``, +``'quart'``, +``'quint'``, +``'sine'``, +``'expo'``, +``'circ'``, +``'back'``, +``'bounce'``, and +``'elastic'``. + +It's hard to understand how these functions behave by staring at a graph, so +below are some animation examples. You can change the type of the tween by +changing the selections. + +.. raw:: html + +
+ + + +Note that while the animations above show tweening of shapes, other attributes +(color, opacity, volume of a sound, ...) can be changed as well. + + +Custom interpolators +^^^^^^^^^^^^^^^^^^^^ + +.. warning: + This is a stub + +You can add custom interpolation methods by adding them to the `tween` table:: + + Timer.tween.sqrt = function(t) return math.sqrt(t) end + -- or just Timer.tween.sqrt = math.sqrt + +Access the your method like you would the predefined ones. You can even use the +modyfing prefixes:: + + Timer.tween(5, 'in-out-sqrt', circle, {radius = 50}) + +You can also invert and chain functions:: + + outsqrt = Timer.tween.out(math.sqrt) + inoutsqrt = Timer.tween.chain(math.sqrt, outsqrt) + diff --git a/docs/vector-light.rst b/docs/vector-light.rst new file mode 100644 index 0000000..300dfbd --- /dev/null +++ b/docs/vector-light.rst @@ -0,0 +1,398 @@ +hump.vector-light +================= + +:: + + vector = require "hump.vector-light" + +An table-free version of :doc:`hump.vector `. Instead of a vector type, +``hump.vector-light`` provides functions that operate on numbers. + +.. note:: +Using this module instead of :doc:`hump.vector ` may result in faster +code, but does so at the expense of speed of development and code readability. +Unless you are absolutely sure that your code is significantly slowed down by +:doc:`hump.vector `, I recommend using it instead. + +**Example**:: + + function player:update(dt) + local dx,dy = 0,0 + if love.keyboard.isDown('left') then + dx = -1 + elseif love.keyboard.isDown('right') then + dx = 1 + end + if love.keyboard.isDown('up') then + dy = -1 + elseif love.keyboard.isDown('down') then + dy = 1 + end + dx,dy = vector.normalize(dx, dy) + + player.velx, player.vely = vector.add(player.velx, player.vely, + vector.mul(dy, dx, dy)) + + if vector.len(player.velx, player.vely) > player.max_velocity then + player.velx, player.vely = vector.mul(player.max_velocity, + vector.normalize(player.velx, player.vely) + end + + player.x = player.x + dt * player.velx + player.y = player.y + dt * player.vely + end + + +Function Reference +------------------ + +.. function:: vector.str(x,y) + + :param numbers x,y: The vector. + :returns: The string representation. + + +Produce a human-readable string of the form ``(x,y)``. +Useful for debugging. + +**Example**:: + + print(vector.str(love.mouse.getPosition())) + + +.. function:: vector.mul(s, x,y) + + :param number s: A scalar. + :param numbers x,y: A vector. + :returns: ``x*s, y*s``. + + +Computes ``x*s,y*s``. The order of arguments is chosen so that it's possible to +chain operations (see example). + +**Example**:: + + velx,vely = vec.mul(dt, vec.add(velx,vely, accx,accy)) + + +.. function:: vector.div(s, x,y) + + :param number s: A scalar. + :param numbers x,y: A vector. + :returns: ``x/s, y/s``. + + +Computes ``x/s,y/s``. The order of arguments is chosen so that it's possible to +chain operations (see example). + +**Example**:: + + x,y = vec.div(self.zoom, x-w/2, y-h/2) + + +.. function:: vector.add(x1,y1, x2,y2) + + :param numbers x1,y1: First vector. + :param numbers x2,y2: Second vector. + :returns: ``x1+x2, x1+x2``. + + +Computes the sum \\((x1+x2, y1+y2)\\)`` of two vectors. Meant to be used in +conjunction with other functions like :func:`vector.mul`. + +**Example**:: + + player.x,player.y = vector.add(player.x,player.y, vector.mul(dt, dx,dy)) + + +.. function:: vector.sub(x1,y1, x2,y2) + + :param numbers x1,y1: First vector. + :param numbers x2,y2: Second vector. + :returns: ``x1-x2, x1-x2``. + + +Computes the difference \\((x1-x2, y1-y2)\\) of two vectors. Meant to be used in +conjunction with other functions like :func:`vector.mul`. + +**Example**:: + + dx,dy = vector.sub(400,300, love.mouse.getPosition()) + + +.. function:: vector.permul(x1,y1, x2,y2) + + :param numbers x1,y1: First vector. + :param numbers x2,y2: Second vector. + :returns: ``x1*x2, y1*y2``. + + +Component-wise multiplication, i.e.: ``x1*x2, y1*y2``. + +**Example**:: + + x,y = vector.permul(x,y, 1,1.5) + + +.. function:: vector.dot(x1,y1, x2,y2) + + :param numbers x1,y1: First vector. + :param numbers x2,y2: Second vector. + :returns: ``x1*x2 + y1*y2``. + + +Computes the `dot product `_ of two +vectors: ``x1*x2 + y1*y2``. + +**Example**:: + + cosphi = vector.dot(rx,ry, vx,vy) + + +.. function:: vector.cross(x1,y1, x2,y2) + + :param numbers x1,y1: First vector. + :param numbers x2,y2: Second vector. + :returns: ``x1*y2 - y1*x2``. + + +Computes the `cross product `_ of +two vectors: ``x1*y2 - y1*x2``. + +**Example**:: + + parallelogram_area = vector.cross(ax,ay, bx,by) + + +.. function:: vector.vector.det(x1,y1, x2,y2) + + :param numbers x1,y1: First vector. + :param numbers x2,y2: Second vector. + :returns: ``x1*y2 - y1*x2``. + + +Alias to :func:`vector.cross`. + +**Example**:: + + parallelogram_area = vector.det(ax,ay, bx,by) + + +.. function:: vector.eq(x1,y1, x2,y2) + + :param numbers x1,y1: First vector. + :param numbers x2,y2: Second vector. + :returns: ``x1 == x2 and y1 == y2`` + +Test for equality. + +**Example**:: + + if vector.eq(x1,y1, x2,y2) then be.happy() end + + +.. function:: vector.le(x1,y1, x2,y2) + + :param numbers x1,y1: First vector. + :param numbers x2,y2: Second vector. + :returns: ``x1 <= x2 and y1 <= y2``. + +Test for partial lexicographical order, ``<=``. + +**Example**:: + + if vector.le(x1,y1, x2,y2) then be.happy() end + + +.. function:: vector.lt(x1,y1, x2,y2) + + :param numbers x1,y1: First vector. + :param numbers x2,y2: Second vector. + :returns: ``x1 < x2 or (x1 == x2) and y1 <= y2``. + + +Test for strict lexicographical order, ``<``. + +**Example**:: + + if vector.lt(x1,y1, x2,y2) then be.happy() end + + +.. function:: vector.len(x,y) + + :param numbers x,y: The vector. + :returns: Length of the vector. + +Get length of a vector, i.e. ``math.sqrt(x*x + y*y)``. + +**Example**:: + + distance = vector.len(love.mouse.getPosition()) + + +.. function:: vector.len2(x,y) + + :param numbers x,y: The vector. + :returns: Squared length of the vector. + +Get squared length of a vector, i.e. ``x*x + y*y``. + +**Example**:: + + -- get closest vertex to a given vector + closest, dsq = vertices[1], vector.len2(px-vertices[1].x, py-vertices[1].y) + for i = 2,#vertices do + local temp = vector.len2(px-vertices[i].x, py-vertices[i].y) + if temp < dsq then + closest, dsq = vertices[i], temp + end + end + + +.. function:: vector.dist(x1,y1, x2,y2) + + :param numbers x1,y1: First vector. + :param numbers x2,y2: Second vector. + :returns: The distance of the points. + + +Get distance of two points. The same as ``vector.len(x1-x2, y1-y2)``. + +**Example**:: + + -- get closest vertex to a given vector + -- slightly slower than the example using len2() + closest, dist = vertices[1], vector.dist(px,py, vertices[1].x,vertices[1].y) + for i = 2,#vertices do + local temp = vector.dist(px,py, vertices[i].x,vertices[i].y) + if temp < dist then + closest, dist = vertices[i], temp + end + end + + +.. function:: vector.dist2(x1,y1, x2,y2) + + :param numbers x1,y1: First vector. + :param numbers x2,y2: Second vector. + :returns: The squared distance of two points. + +Get squared distance of two points. The same as ``vector.len2(x1-x2, y1-y2)``. + +**Example**:: + + -- get closest vertex to a given vector + closest, dsq = vertices[1], vector.dist2(px,py, vertices[1].x,vertices[1].y) + for i = 2,#vertices do + local temp = vector.dist2(px,py, vertices[i].x,vertices[i].y) + if temp < dsq then + closest, dsq = vertices[i], temp + end + end + + +.. function:: vector.normalize(x,y) + + :param numbers x,y: The vector. + :returns: Vector with same direction as the input vector, but length 1. + + +Get normalized vector, i.e. a vector with the same direction as the input +vector, but with length 1. + +**Example**:: + + dx,dy = vector.normalize(vx,vy) + + +.. function:: vector.rotate(phi, x,y) + + :param number phi: Rotation angle in radians. + :param numbers x,y: The vector. + :returns: The rotated vector + + +Get a rotated vector. + +**Example**:: + + -- approximate a circle + circle = {} + for i = 1,30 do + local phi = 2 * math.pi * i / 30 + circle[i*2-1], circle[i*2] = vector.rotate(phi, 0,1) + end + + +.. function:: vector.perpendicular(x,y) + + :param numbers x,y: The vector. + :returns: A vector perpendicular to the input vector + + +Quick rotation by 90°. The same (but faster) as ``vector.rotate(math.pi/2, x,y)``. + +**Example**:: + + nx,ny = vector.normalize(vector.perpendicular(bx-ax, by-ay)) + + +.. function:: vector.project(x,y, u,v) + + :param numbers x,y: The vector to project. + :param numbers u,v: The vector to project onto. + :returns: The projected vector. + + +Project vector onto another vector. + +**Example**:: + + vx_p,vy_p = vector.project(vx,vy, ax,ay) + + +.. function:: vector.mirror(x,y, u,v) + + :param numbers x,y: The vector to mirror. + :param numbers u,v: The vector defining the axis. + :returns: The mirrored vector. + + +Mirrors vector on the axis defined by the other vector. + +**Example**:: + + vx,vy = vector.mirror(vx,vy, surface.x,surface.y) + + +.. function:: vector.angleTo(ox,y, u,v) + + :param numbers x,y: Vector to measure the angle. + :param numbers u,v (optional): Reference vector. + :returns: Angle in radians. + + +Measures the angle between two vectors. ``u`` and ``v`` default to ``0`` if omitted, +i.e. the function returns the angle to the coordinate system. + +**Example**:: + + lean = vector.angleTo(self.upx, self.upy, 0,1) + if lean > .1 then self:fallOver() end + + +.. function:: vector.trim(max_length, x,y) + + :param number max_length: Maximum allowed length of the vector. + :param numbers x,y: Vector to trum. + :returns: The trimmed vector. + +Trim the vector to ``max_length``, i.e. return a vector that points in the same +direction as the source vector, but has a magnitude smaller or equal to +``max_length``. + +**Example**:: + + vel_x, vel_y = vector.trim(299792458, + vector.add(vel_x, vel_y, + vector.mul(mass * dt, force_x, force_y))) diff --git a/docs/vector.rst b/docs/vector.rst new file mode 100644 index 0000000..3ae48da --- /dev/null +++ b/docs/vector.rst @@ -0,0 +1,422 @@ +hump.vector +=========== + +:: + + vector = require "hump.vector" + +A handy 2D vector class providing most of the things you do with vectors. + +You can access the individual coordinates by ``vec.x`` and ``vec.y``. + +.. note:: + + The vectors are stored as tables. Most operations create new vectors and + thus new tables, which *may* put the garbage collector under stress. + If you experience slowdowns that are caused by hump.vector, try the + table-less version :doc:`hump.vector-light `. + +**Example**:: + + function player:update(dt) + local delta = vector(0,0) + if love.keyboard.isDown('left') then + delta.x = -1 + elseif love.keyboard.isDown('right') then + delta.x = 1 + end + if love.keyboard.isDown('up') then + delta.y = -1 + elseif love.keyboard.isDown('down') then + delta.y = 1 + end + delta:normalizeInplace() + + player.velocity = player.velocity + delta * player.acceleration * dt + + if player.velocity:len() > player.max_velocity then + player.velocity = player.velocity:normalized() * player.max_velocity + end + + player.position = player.position + player.velocity * dt + end + + +Vector arithmetic +----------------- + +**hump** provides vector arithmetic by implement the corresponding metamethods +(``__add``, ``__mul``, etc.). Here are the semantics: + +``vector + vector = vector`` + Component wise sum: \\((a,b) + (x,y) = (a+x, b+y)\\) +``vector - vector = vector`` + Component wise difference: \\((a,b) - (x,y) = (a-x, b-y)\\) +``vector * vector = number`` + Dot product: \\((a,b) \\cdot (x,y) = a\\cdot x + b\\cdot y\\) +``number * vector = vector`` + Scalar multiplication/scaling: \\((a,b) \\cdot s = (s\\cdot a, s\\cdot b)\\) +``vector * number = vector`` + Scalar multiplication/scaling: \\(s \\cdot (x,y) = (s\\cdot x, s\\cdot y)\\) +``vector / number = vector`` + Scalar multiplication/scaling: \\((a,b) / s = (a/s, b/s)\\). + +Common relations are also defined: + +``a == b`` + Same as ``a.x == b.x and a.y == b.y``. +``a <= b`` + Same as ``a.x <= b.x and a.y <= b.y``. +``a < b`` + Lexicographical order: ``a.x < b.x or (a.x == b.x and a.y < b.y)``. + +**Example**:: + + -- acceleration, player.velocity and player.position are vectors + acceleration = vector(0,-9) + player.velocity = player.velocity + acceleration * dt + player.position = player.position + player.velocity * dt + + +Function Reference +------------------ + +.. function:: vector.new(x,y) + + :param numbers x,y: Coordinates. + :returns: The vector. + + +Create a new vector. + +**Examples**:: + + a = vector.new(10,10) + +:: + + -- as a shortcut, you can call the module like a function: + vector = require "hump.vector" + a = vector(10,10) + + +.. function:: vector.isvector(v) + + :param mixed v: The variable to test. + :returns: ``true`` if ``v`` is a vector, ``false`` otherwise. + +Test whether a variable is a vector. + +**Example**:: + + if not vector.isvector(v) then + v = vector(v,0) + end + + +.. function:: vector:clone() + + :returns: Copy of the vector. + +Copy a vector. Assigning a vector to a variable will create a *reference*, so +when modifying the vector referenced by the new variable would also change the +old one:: + + a = vector(1,1) -- create vector + b = a -- b references a + c = a:clone() -- c is a copy of a + b.x = 0 -- changes a,b and c + print(a,b,c) -- prints '(1,0), (1,0), (1,1)' + +**Example**:: + + copy = original:clone() + + +.. function:: vector:unpack() + + :returns: The coordinates ``x,y``. + + +Extract coordinates. + +**Examples**:: + + x,y = pos:unpack() + +:: + + love.graphics.draw(self.image, self.pos:unpack()) + + +.. function:: vector:permul(other) + + :param vector other: The second source vector. + :returns: Vector whose components are products of the source vectors. + + +Multiplies vectors coordinate wise, i.e. ``result = vector(a.x * b.x, a.y * +b.y)``. + +Does not change either argument vectors, but creates a new one. + +**Example**:: + + -- scale with different magnitudes + scaled = original:permul(vector(1,1.5)) + + +.. function:: vector:len() + + :returns: Length of the vector. + + +Get length of the vector, i.e. ``math.sqrt(vec.x * vec.x + vec.y * vec.y)``. + +**Example**:: + + distance = (a - b):len() + + +.. function:: vector:len2() + + :returns: Squared length of the vector. + + +Get squared length of the vector, i.e. ``vec.x * vec.x + vec.y * vec.y``. + +**Example**:: + + -- get closest vertex to a given vector + closest, dsq = vertices[1], (pos - vertices[1]):len2() + for i = 2,#vertices do + local temp = (pos - vertices[i]):len2() + if temp < dsq then + closest, dsq = vertices[i], temp + end + end + + +.. function:: vector:dist(other) + + :param vector other: Other vector to measure the distance to. + :returns: The distance of the vectors. + + +Get distance of two vectors. The same as ``(a - b):len()``. + +**Example**:: + + -- get closest vertex to a given vector + -- slightly slower than the example using len2() + closest, dist = vertices[1], pos:dist(vertices[1]) + for i = 2,#vertices do + local temp = pos:dist(vertices[i]) + if temp < dist then + closest, dist = vertices[i], temp + end + end + + +.. function:: vector:dist2(other) + + :param vector other: Other vector to measure the distance to. + :returns: The squared distance of the vectors. + + +Get squared distance of two vectors. The same as ``(a - b):len2()``. + +**Example**:: + + -- get closest vertex to a given vector + -- slightly faster than the example using len2() + closest, dsq = vertices[1], pos:dist2(vertices[1]) + for i = 2,#vertices do + local temp = pos:dist2(vertices[i]) + if temp < dsq then + closest, dsq = vertices[i], temp + end + end + + +.. function:: vector:normalized() + + :returns: Vector with same direction as the input vector, but length 1. + + +Get normalized vector: a vector with the same direction as the input vector, +but with length 1. + +Does not change the input vector, but creates a new vector. + +**Example**:: + + direction = velocity:normalized() + + +.. function:: vector:normalizeInplace() + + :returns: Itself -- the normalized vector + + +Normalize a vector, i.e. make the vector to have length 1. Great to use on +intermediate results. + +.. warning:: + This modifies the vector. If in doubt, use :func:`vector:normalized()`. + +**Example**:: + + normal = (b - a):perpendicular():normalizeInplace() + + +.. function:: vector:rotated(angle) + + :param number angle: Rotation angle in radians. + :returns: The rotated vector + + +Get a vector with same length, but rotated by ``angle``: + +.. image:: _static/vector-rotated.png + :alt: Sketch of rotated vector. + +Does not change the input vector, but creates a new vector. + +**Example**:: + + -- approximate a circle + circle = {} + for i = 1,30 do + local phi = 2 * math.pi * i / 30 + circle[#circle+1] = vector(0,1):rotated(phi) + end + +.. function:: vector:rotateInplace(angle) + + :param number angle: Rotation angle in radians. + :returns: Itself -- the rotated vector + + +Rotate a vector in-place. Great to use on intermediate results. + +.. warning:: + Yhis modifies the vector. If in doubt, use :func:`vector:rotated()`. + +**Example**:: + + -- ongoing rotation + spawner.direction:rotateInplace(dt) + + +.. function:: vector:perpendicular() + + :returns: A vector perpendicular to the input vector + +Quick rotation by 90°. Creates a new vector. The same (but faster) as +``vec:rotate(math.pi/2)``: + +.. image:: _static/vector-perpendicular.png + :alt: Sketch of two perpendicular vectors + +**Example**:: + + normal = (b - a):perpendicular():normalizeInplace() + + + +.. function:: vector:projectOn(v) + + :param vector v: The vector to project on. + :returns: ``vector`` The projected vector. + + +Project vector onto another vector: + +.. image:: _static/vector-projectOn.png + :alt: Sketch of vector projection. + +**Example**:: + + velocity_component = velocity:projectOn(axis) + + + +.. function:: vector:mirrorOn(v) + + :param vector v: The vector to mirror on. + :returns: The mirrored vector. + + +Mirrors vector on the axis defined by the other vector: + +.. image: _static/vector-mirrorOn.png + :alt: Sketch of a vector mirrored on another vector + +**Example**:: + + deflected_velocity = ball.velocity:mirrorOn(surface_normal) + + +.. function:: vector:cross(other) + + :param vector other: Vector to compute the cross product with. + :returns: ``number`` Cross product of both vectors. + + +Get cross product of two vectors. Equals the area of the parallelogram spanned +by both vectors. + +**Example**:: + + parallelogram_area = a:cross(b) + + +.. function:: vector:angleTo(other) + + :param vector other: Vector to measure the angle to (optional). + :returns: Angle in radians. + + +Measures the angle between two vectors. If ``other`` is omitted it defaults +to the vector ``(0,0)``, i.e. the function returns the angle to the coordinate +system. + +**Example**:: + + lean = self.upvector:angleTo(vector(0,1)) + if lean > .1 then self:fallOver() end + +.. function:: vector:trimmed(max_length) + + :param number max_length: Maximum allowed length of the vector. + :returns: A trimmed vector. + +Trim the vector to ``max_length``, i.e. return a vector that points in the same +direction as the source vector, but has a magnitude smaller or equal to +``max_length``. + +Does not change the input vector, but creates a new vector. + +**Example**:: + + ship.velocity = ship.force * ship.mass * dt + ship.velocity = ship.velocity:trimmed(299792458) + + +.. function:: vector:trimInplace(max_length) + + :param number max_length: Maximum allowed length of the vector. + :returns: Itself -- the trimmed vector. + +Trim the vector to ``max_length``, i.e. return a vector that points in the same +direction as the source vector, but has a magnitude smaller or equal to +``max_length``. + +.. warning:: + Yhis modifies the vector. If in doubt, use :func:`vector:trimmed()`. + + +**Example**:: + + ship.velocity = (ship.velocity + ship.force * ship.mass * dt):trimInplace(299792458) From fa89556eb6bd6056a8e5804f8cbd107bdd95d546 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Mon, 12 Oct 2015 08:21:56 +0200 Subject: [PATCH 28/50] Documentation with sphinx --- docs/_static/tween-example.svg | 225 --------------------------------- 1 file changed, 225 deletions(-) delete mode 100644 docs/_static/tween-example.svg diff --git a/docs/_static/tween-example.svg b/docs/_static/tween-example.svg deleted file mode 100644 index 39ab626..0000000 --- a/docs/_static/tween-example.svg +++ /dev/null @@ -1,225 +0,0 @@ - - - - From 37f4ed9e435b05827602a614caa7a2c7b62fd63a Mon Sep 17 00:00:00 2001 From: vrld Date: Mon, 12 Oct 2015 08:29:36 +0200 Subject: [PATCH 29/50] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 899ee2f..621cbde 100644 --- a/README.md +++ b/README.md @@ -7,17 +7,17 @@ Contents: ------------ * *gamestate.lua*: Easy gamestate management. -* *timer.lua*: Delayed and time-limited function calls and tweening functionality. +* *timer.lua*: Delayed and time-limited function calls and tweening. * *vector.lua*: 2D vector math. * *vector-light.lua*: Lightweight 2D vector math (for optimisation purposes - leads to potentially ugly code). * *class.lua*: Lightweight object orientation (class or prototype based). * *signal.lua*: Simple Signal/Slot (aka. Observer) implementation. -* *camera.lua*: Move-, zoom- and rotatable camera. +* *camera.lua*: Move-, zoom- and rotatable camera with camera locking and movement smoothing. Documentation ============= -You can find the documentation here: [http://vrld.github.com/hump/](http://vrld.github.com/hump/) +You can find the documentation here: [hump.readthedocs.org](http://hump.readthedocs.org) License From f851254f2666b1f79b942ebe37721c2f3082ce43 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Tue, 13 Oct 2015 08:08:26 +0200 Subject: [PATCH 30/50] Fix #52 - Gamestate require init function. Use __NULL__ when init is not defined in the state. --- gamestate.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gamestate.lua b/gamestate.lua index 61517f9..b727dc1 100644 --- a/gamestate.lua +++ b/gamestate.lua @@ -40,7 +40,7 @@ local function change_state(stack_offset, to, ...) local pre = stack[#stack] -- initialize only on first call - ;(initialized_states[to] or to.init)(to) + ;(initialized_states[to] or to.init or __NULL__)(to) initialized_states[to] = __NULL__ stack[#stack+stack_offset] = to From 2257ab025c447c2028104c1b3908cd78234426ad Mon Sep 17 00:00:00 2001 From: vrld Date: Tue, 13 Oct 2015 15:34:59 +0200 Subject: [PATCH 31/50] Update camera.rst --- docs/camera.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/camera.rst b/docs/camera.rst index 817fc1f..aa3e925 100644 --- a/docs/camera.rst +++ b/docs/camera.rst @@ -92,7 +92,7 @@ This function is shortcut to ``camera.x,camera.y = x, y``. camera:lookAt(player.pos:unpack()):rotation(player.rot) end -.. function:: camera:pos() +.. function:: camera:position() :returns: ``x,y`` -- Camera position. @@ -283,7 +283,7 @@ between these two coordinate systems. love.graphics.line(x, y, love.mouse.getPosition()) -.. function:: camera:mousepos() +.. function:: camera:mousePosition() :returns: Mouse position in world coordinates. @@ -292,7 +292,7 @@ Shortcut to ``camera:worldCoords(love.mouse.getPosition())``. **Example**:: - x,y = camera:mousepos() + x,y = camera:mousePosition() selectedUnit:plotPath(x,y) From 523502ca8027f58bf5b87cdab120dab98758671f Mon Sep 17 00:00:00 2001 From: vrld Date: Tue, 13 Oct 2015 15:35:46 +0200 Subject: [PATCH 32/50] [camera] More consistent naming --- camera.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/camera.lua b/camera.lua index 74e2c98..7070d76 100644 --- a/camera.lua +++ b/camera.lua @@ -78,7 +78,7 @@ function camera:move(dx,dy) return self end -function camera:pos() +function camera:position() return self.x, self.y end @@ -139,7 +139,7 @@ function camera:worldCoords(x,y) return x+self.x, y+self.y end -function camera:mousePos() +function camera:mousePosition() return self:worldCoords(love.mouse.getPosition()) end @@ -162,7 +162,7 @@ function camera:lockY(y, smoother, ...) return self end -function camera:lockPos(x,y, smoother, ...) +function camera:lockPosition(x,y, smoother, ...) return self:move((smoother or self.smoother)(x - self.x, y - self.y, ...)) end From 12761564b90ce665863166124d1f33fd24c825d4 Mon Sep 17 00:00:00 2001 From: vrld Date: Tue, 13 Oct 2015 15:37:23 +0200 Subject: [PATCH 33/50] Document changes --- docs/camera.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/camera.rst b/docs/camera.rst index aa3e925..41f7b12 100644 --- a/docs/camera.rst +++ b/docs/camera.rst @@ -279,7 +279,7 @@ between these two coordinate systems. **Example**:: - x,y = cam:cameraCoords(player.pos) + x,y = cam:cameraCoords(player.pos.x, player.pos.y) love.graphics.line(x, y, love.mouse.getPosition()) @@ -386,7 +386,7 @@ screen center, aim 20 pixels *above* it (see examples). -.. function:: camera:lockPos(x,y, smoother, ...) +.. function:: camera:lockPosition(x,y, smoother, ...) :param numbers x,y: Position (in world coordinates) to lock to. :param function smoother: Movement smoothing override. (optional) From 5e02dcdba28847c8033c6a6038935ac1f111aea8 Mon Sep 17 00:00:00 2001 From: vrld Date: Fri, 16 Oct 2015 11:20:08 +0200 Subject: [PATCH 34/50] Fix #53: Typo in camera.lua --- camera.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/camera.lua b/camera.lua index 7070d76..0ab146c 100644 --- a/camera.lua +++ b/camera.lua @@ -31,7 +31,7 @@ local camera = {} camera.__index = camera -- Movement interpolators (for camera locking/windowing) -smooth.smooth = {} +camera.smooth = {} function camera.smooth.none() return function(dx,dy) return dx,dy end From 7713d054b3dcee31d4214d5a77e37aec1cebeb40 Mon Sep 17 00:00:00 2001 From: tesselode Date: Mon, 19 Oct 2015 09:47:54 -0400 Subject: [PATCH 35/50] Fixed a typo in the gamestate docs Sorry about Atom doing its thing with empty lines... --- docs/gamestate.rst | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/gamestate.rst b/docs/gamestate.rst index c8ad77f..9ab96fc 100644 --- a/docs/gamestate.rst +++ b/docs/gamestate.rst @@ -13,30 +13,30 @@ A typical game could consist of a menu-state, a level-state and a game-over-stat local menu = {} -- previously: Gamestate.new() local game = {} - + function menu:draw() love.graphics.print("Press Enter to continue", 10, 10) end - + function menu:keyreleased(key, code) if key == 'enter' then Gamestate.switch(game) end end - + function game:enter() Entities.clear() -- setup entities here end - + function game:update(dt) Entities.update(dt) end - + function game:draw() Entities.draw() end - + function love.load() Gamestate.registerEvents() Gamestate.switch(menu) @@ -101,6 +101,8 @@ corresponding LÖVE callbacks and receive receive the same arguments (e.g. **Example**:: menu = {} -- previously: Gamestate.new() + + function menu:init() self.background = love.graphics.newImage('bg.jpg') Buttons.initialize() end @@ -295,11 +297,11 @@ to be one of the :ref:`callbacks`. Mostly useful when not using function love.draw() Gamestate.draw() -- is `draw' end - + function love.update(dt) Gamestate.update(dt) -- pass dt to currentState:update(dt) end - + function love.keypressed(key, code) Gamestate.keypressed(key, code) -- pass multiple arguments end @@ -332,7 +334,7 @@ This is by done by overwriting the love callbacks, e.g.:: Gamestate.registerEvents() Gamestate.switch(menu) end - + -- love callback will still be invoked function love.update(dt) Timer.update(dt) @@ -346,4 +348,3 @@ This is by done by overwriting the love callbacks, e.g.:: Gamestate.registerEvents{'draw', 'update', 'quit'} Gamestate.switch(menu) end - From b85922d4703548bc928ef04744053d2ba788b0e9 Mon Sep 17 00:00:00 2001 From: tesselode Date: Fri, 30 Oct 2015 13:07:02 -0400 Subject: [PATCH 36/50] Small fixes to timer docs Timer instances created using Timer.new don't use colon syntax, which the docs seem to indicate. Also I changed "menu_timer" to menuTimer to make it consistent with the rest of the page. --- docs/timer.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/timer.rst b/docs/timer.rst index f936646..0595493 100644 --- a/docs/timer.rst +++ b/docs/timer.rst @@ -21,7 +21,7 @@ easier to produce `juicy games `_. Timer.after(1, function() print("Hello, world!") end) end end - + function love.update(dt) Timer.update(dt) end @@ -79,7 +79,7 @@ periodic behavior (see the example). :: --Using a timer instance: - menuTimer:after(1, finishAnimation) + menuTimer.after(1, finishAnimation) .. function:: Timer.every(delay, func[, count]) @@ -184,9 +184,9 @@ Prevent a timer from being executed in the future. function tick() print('tick... tock...') end - handle = menuTimer:every(1, tick) + handle = menuTimer.every(1, tick) -- later - menuTimer:cancel(handle) + menuTimer.cancel(handle) .. function:: Timer.clear() @@ -200,7 +200,7 @@ executed will discarded. :: - menu_timer:clear() + menuTimer.clear() .. function:: Timer.update(dt) @@ -393,4 +393,3 @@ You can also invert and chain functions:: outsqrt = Timer.tween.out(math.sqrt) inoutsqrt = Timer.tween.chain(math.sqrt, outsqrt) - From 00a3f9becc19820acbb7513951387f800c20ed90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Segu=C3=AD?= Date: Sat, 31 Oct 2015 00:04:42 +0100 Subject: [PATCH 37/50] fixing scale for camera:lockWindow --- camera.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/camera.lua b/camera.lua index 0ab146c..2f77e37 100644 --- a/camera.lua +++ b/camera.lua @@ -183,7 +183,7 @@ function camera:lockWindow(x, y, x_min, x_max, y_min, y_max, smoother, ...) -- transform displacement to movement in world coordinates local c,s = cos(-self.rot), sin(-self.rot) - dx,dy = (c*dx - s*dy) * self.scale, (s*dx + c*dy) * self.scale + dx,dy = (c*dx - s*dy) / self.scale, (s*dx + c*dy) / self.scale -- move self:move((smoother or self.smoother)(dx,dy,...)) From 8e65618e3c322dfeee8807adc510c81322a79585 Mon Sep 17 00:00:00 2001 From: vrld Date: Mon, 2 Nov 2015 12:13:29 +0100 Subject: [PATCH 38/50] Update timer.rst Clearly show colon-syntax for timer-instance calls --- docs/timer.rst | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/timer.rst b/docs/timer.rst index f936646..7226c41 100644 --- a/docs/timer.rst +++ b/docs/timer.rst @@ -38,6 +38,10 @@ Creates a new timer instance that is independent of the global timer: It will manage it's own list of scheduled functions and does not in any way affect the the global timer. Likewise, the global timer does not affect timer instances. +.. note:: + Unlike the global instance, timer instaces need the colon sytax, i.e. + ``instance:after()``) instead of ``Timer.after()``. + .. note:: If you don't need multiple independent schedulers, you can use the global/default timer (see examples). @@ -49,6 +53,8 @@ the global timer. Likewise, the global timer does not affect timer instances. .. function:: Timer.after(delay, func) +.. function:: instance:after(delay, func) + :param number delay: Number of seconds the function will be delayed. :param function func: The function to be delayed. :returns: The timer handle. See also :func:`Timer.cancel`. @@ -84,6 +90,8 @@ periodic behavior (see the example). .. function:: Timer.every(delay, func[, count]) +.. function:: instance:every(delay, func[, count]) + :param number delay: Number of seconds between two consecutive function calls. :param function func: The function to be called periodically. :param number count: Number of times the function is to be called (optional). @@ -116,6 +124,8 @@ or :func:`Timer.cancel` or :func:`Timer.clear` is called on the timer instance. .. function:: Timer.during(delay, func[, after]) +.. function:: instance:during(delay, func[, after]) + :param number delay: Number of seconds the func will be called. :param function func: The function to be called on ``update(dt)``. :param function after: A function to be called after delay seconds (optional). @@ -165,6 +175,8 @@ seconds have passed. .. function:: Timer.cancel(handle) +.. function:: instance:cancel(handle) + :param table handle: The function to be canceled. Prevent a timer from being executed in the future. @@ -191,6 +203,8 @@ Prevent a timer from being executed in the future. .. function:: Timer.clear() +.. function:: instance:clear() + Remove all timed and periodic functions. Functions that have not yet been executed will discarded. @@ -200,7 +214,7 @@ executed will discarded. :: - menu_timer:clear() + menuTimer:clear() .. function:: Timer.update(dt) @@ -227,6 +241,8 @@ Update timers and execute functions if the deadline is reached. Call in .. function:: Timer.tween(duration, subject, target, method, after, ...) +.. function:: instance:tween(duration, subject, target, method, after, ...) + :param number duration: Duration of the tween. :param table subject: Object to be tweened. :param table target: Target values. From f00de3c0a4093a6f1c6ea18fce587ed3a7af4d37 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Mon, 2 Nov 2015 21:09:44 +0100 Subject: [PATCH 39/50] Revert "Update timer.rst" This reverts commit 8e65618e3c322dfeee8807adc510c81322a79585. --- docs/timer.rst | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/docs/timer.rst b/docs/timer.rst index 7226c41..f936646 100644 --- a/docs/timer.rst +++ b/docs/timer.rst @@ -38,10 +38,6 @@ Creates a new timer instance that is independent of the global timer: It will manage it's own list of scheduled functions and does not in any way affect the the global timer. Likewise, the global timer does not affect timer instances. -.. note:: - Unlike the global instance, timer instaces need the colon sytax, i.e. - ``instance:after()``) instead of ``Timer.after()``. - .. note:: If you don't need multiple independent schedulers, you can use the global/default timer (see examples). @@ -53,8 +49,6 @@ the global timer. Likewise, the global timer does not affect timer instances. .. function:: Timer.after(delay, func) -.. function:: instance:after(delay, func) - :param number delay: Number of seconds the function will be delayed. :param function func: The function to be delayed. :returns: The timer handle. See also :func:`Timer.cancel`. @@ -90,8 +84,6 @@ periodic behavior (see the example). .. function:: Timer.every(delay, func[, count]) -.. function:: instance:every(delay, func[, count]) - :param number delay: Number of seconds between two consecutive function calls. :param function func: The function to be called periodically. :param number count: Number of times the function is to be called (optional). @@ -124,8 +116,6 @@ or :func:`Timer.cancel` or :func:`Timer.clear` is called on the timer instance. .. function:: Timer.during(delay, func[, after]) -.. function:: instance:during(delay, func[, after]) - :param number delay: Number of seconds the func will be called. :param function func: The function to be called on ``update(dt)``. :param function after: A function to be called after delay seconds (optional). @@ -175,8 +165,6 @@ seconds have passed. .. function:: Timer.cancel(handle) -.. function:: instance:cancel(handle) - :param table handle: The function to be canceled. Prevent a timer from being executed in the future. @@ -203,8 +191,6 @@ Prevent a timer from being executed in the future. .. function:: Timer.clear() -.. function:: instance:clear() - Remove all timed and periodic functions. Functions that have not yet been executed will discarded. @@ -214,7 +200,7 @@ executed will discarded. :: - menuTimer:clear() + menu_timer:clear() .. function:: Timer.update(dt) @@ -241,8 +227,6 @@ Update timers and execute functions if the deadline is reached. Call in .. function:: Timer.tween(duration, subject, target, method, after, ...) -.. function:: instance:tween(duration, subject, target, method, after, ...) - :param number duration: Duration of the tween. :param table subject: Object to be tweened. :param table target: Target values. From 487b1a1921be71fbc902ee6d186d0d836f52ff6e Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Mon, 2 Nov 2015 21:23:33 +0100 Subject: [PATCH 40/50] Clear warning when making documentation --- docs/3 | 391 ------------------------------------------ docs/vector-light.rst | 10 +- 2 files changed, 6 insertions(+), 395 deletions(-) delete mode 100644 docs/3 diff --git a/docs/3 b/docs/3 deleted file mode 100644 index 0cfffe0..0000000 --- a/docs/3 +++ /dev/null @@ -1,391 +0,0 @@ -hump.vector -=========== - -:: - - vector = require "hump.vector" - -A handy 2D vector class providing most of the things you do with vectors. - -You can access the individual coordinates by ``vec.x`` and ``vec.y``. - -.. note:: - - The vectors are stored as tables. Most operations create new vectors and - thus new tables, which *may* put - -**Example**:: - - function player:update(dt) - local delta = vector(0,0) - if love.keyboard.isDown('left') then - delta.x = -1 - elseif love.keyboard.isDown('right') then - delta.x = 1 - end - if love.keyboard.isDown('up') then - delta.y = -1 - elseif love.keyboard.isDown('down') then - delta.y = 1 - end - delta:normalize_inplace() - - player.velocity = player.velocity + delta * player.acceleration * dt - - if player.velocity:len() > player.max_velocity then - player.velocity = player.velocity:normalized() * player.max_velocity - end - - player.position = player.position + player.velocity * dt - end - - -Vector arithmetic ------------------ - -**hump** provides vector arithmetic by implement the corresponding metamethods -(``__add``, ``__mul``, etc.). Here are the semantics: - -``vector + vector = vector`` - Component wise sum: \((a,b) + (x,y) = (a+x, b+y)\) -``vector - vector = vector`` - Component wise difference: \((a,b) - (x,y) = (a-x, b-y)\) -``vector * vector = number`` - Dot product: \((a,b) * (x,y) = a*x + b*y\) -``number * vector = vector`` - Scalar multiplication/scaling: \((a,b) * s = (s*a, s*b)\) -``vector * number = vector`` - Scalar multiplication/scaling: \(s * (x,y) = (s*x, s*y)\) -``vector / number = vector`` - Scalar multiplication/scaling: \((a,b) / s = (a/s, b/s)\). - -Common relations are also defined: - -``a == b`` - Same as ``a.x == b.x and a.y == b.y``. -``a <= b`` - Same as ``a.x <= b.x and a.y <= b.y``. -``a < b`` - Lexicographical order: ``a.x < b.x or (a.x == b.x and a.y < b.y)``. - -**Example**:: - - -- acceleration, player.velocity and player.position are vectors - acceleration = vector(0,-9) - player.velocity = player.velocity + acceleration * dt - player.position = player.position + player.velocity * dt - - -Function Reference ------------------- - -.. function:: vector.new(x,y) - - :param numbers x,y: Coordinates. - :returns: The vector. - - -Create a new vector. - -**Examples**:: - - a = vector.new(10,10) - -:: - - -- as a shortcut, you can call the module like a function: - vector = require "hump.vector" - a = vector(10,10) - - -.. function:: vector.isvector(v) - - :param mixed v: The variable to test. - :returns: ``true`` if ``v`` is a vector, ``false`` otherwise. - -Test whether a variable is a vector. - -**Example**:: - - if not vector.isvector(v) then - v = vector(v,0) - end - - -.. function:: vector.vector:clone() - - :returns: Copy of the vector. - -Copy a vector. Assigning a vector to a variable will create a *reference*, so -when modifying the vector referenced by the new variable would also change the -old one:: - - a = vector(1,1) -- create vector - b = a -- b references a - c = a:clone() -- c is a copy of a - b.x = 0 -- changes a,b and c - print(a,b,c) -- prints '(1,0), (1,0), (1,1)' - -**Example**:: - - copy = original:clone() - - -.. function:: vector.vector:unpack() - - :returns: The coordinates ``x,y``. - - -Extract coordinates. - -**Examples**:: - - x,y = pos:unpack() - -:: - - love.graphics.draw(self.image, self.pos:unpack()) - - -.. function:: vector.vector:permul(other) - - :param vector other: The second source vector. - :returns: Vector whose components are products of the source vectors. - - -Multiplies vectors coordinate wise, i.e. ``result = vector(a.x * b.x, a.y * -b.y)``. - -This does not change either argument vectors, but creates a new one. - -**Example**:: - - -- scale with different magnitudes - scaled = original:permul(vector(1,1.5)) - - -.. function:: vector.vector:len() - - :returns: ``number`` Length of the vector. - - -Get length of a vector, i.e. ``math.sqrt(vec.x * vec.x + vec.y * vec.y)``. - -**Example**:: - - distance = (a - b):len() - - -.. function:: vector.vector:len2() - - :returns: ``number`` Squared length of the vector. - - -Get squared length of a vector, i.e. ``vec.x * vec.x + vec.y * vec.y``. - -**Example**:: - - -- get closest vertex to a given vector - closest, dsq = vertices[1], (pos - vertices[1]):len2() - for i = 2,#vertices do - local temp = (pos - vertices[i]):len2() - if temp < dsq then - closest, dsq = vertices[i], temp - end - end - - -.. function:: vector.vector:dist(other) - - :param vector other: Other vector to measure the distance to. - :returns: ``number`` The distance of the vectors. - - -Get distance of two vectors. The same as ``(a - b):len()``. - -**Example**:: - - -- get closest vertex to a given vector - -- slightly slower than the example using len2() - closest, dist = vertices[1], pos:dist(vertices[1]) - for i = 2,#vertices do - local temp = pos:dist(vertices[i]) - if temp < dist then - closest, dist = vertices[i], temp - end - end - - -.. function:: vector.vector:dist2(other) - - :param vector other: Other vector to measure the distance to. - :returns: ``number`` The squared distance of the vectors. - - -Get squared distance of two vectors. The same as ``(a - b):len2()``. - -**Example**:: - - -- get closest vertex to a given vector - -- slightly faster than the example using len2() - closest, dsq = vertices[1], pos:dist2(vertices[1]) - for i = 2,#vertices do - local temp = pos:dist2(vertices[i]) - if temp < dsq then - closest, dsq = vertices[i], temp - end - end - - -.. function:: vector.vector:normalized() - - :returns: ``vector`` Vector with same direction as the input vector, but length 1. - - -Get normalized vector, i.e. a vector with the same direction as the input -vector, but with length 1. - -This does not change the input vector, but creates a new vector. - -**Example**:: - - direction = velocity:normalized() - - -.. function:: vector.vector:normalize_inplace() - - :returns: ``vector`` Itself - the normalized vector - - -Normalize a vector, i.e. make the vector unit length. Great to use on -intermediate results. - -**This modifies the vector. If in doubt, use -[``vector:normalized()``](#hump.vectornormalized).** - -**Example**:: - - normal = (b - a):perpendicular():normalize_inplace() - - -.. function:: vector.vector:rotated(angle) - - :param number angle: Rotation angle in radians. - :returns: ``vector`` The rotated vector - - -Get a rotated vector. - -This does not change the input vector, but creates a new vector. - -**Example**:: - - -- approximate a circle - circle = {} - for i = 1,30 do - local phi = 2 * math.pi * i / 30 - circle[#circle+1] = vector(0,1):rotated(phi) - end - -**Sketch**:: - -![Rotated vector sketch](vector-rotated.png) - - -.. function:: vector.vector:rotate_inplace(angle) - - :param number angle: Rotation angle in radians. - :returns: ``vector`` Itself - the rotated vector - - -Rotate a vector in-place. Great to use on intermediate results. - -**This modifies the vector. If in doubt, use -[``vector:rotated()``](#hump.vectorvector:rotated).** - -**Example**:: - - -- ongoing rotation - spawner.direction:rotate_inplace(dt) - - -.. function:: vector.vector:perpendicular() - - :returns: ``vector`` A vector perpendicular to the input vector - - -Quick rotation by 90°. Creates a new vector. The same (but faster) as -``vec:rotate(math.pi/2)``. - -**Example**:: - - normal = (b - a):perpendicular():normalize_inplace() - -**Sketch**:: - -![Perpendiculat vector sketch](vector-perpendicular.png) - - -.. function:: vector.vector:projectOn(v) - - :param vector v: The vector to project on. - :returns: ``vector`` The projected vector. - - -Project vector onto another vector (see sketch). - -**Example**:: - - velocity_component = velocity:projectOn(axis) - -**Sketch**:: - -![Projected vector sketch](vector-projectOn.png) - - -.. function:: vector.vector:mirrorOn(v) - - :param vector v: The vector to mirror on. - :returns: ``vector`` The mirrored vector. - - -Mirrors vector on the axis defined by the other vector. - -**Example**:: - - deflected_velocity = ball.velocity:mirrorOn(surface_normal) - -**Sketch**:: - -![Mirrored vector sketch](vector-mirrorOn.png) - - -.. function:: vector.vector:cross(other) - - :param vector other: Vector to compute the cross product with. - :returns: ``number`` Cross product of both vectors. - - -Get cross product of both vectors. Equals the area of the parallelogram spanned -by both vectors. - -**Example**:: - - parallelogram_area = a:cross(b) - - -.. function:: vector.vector:angleTo(other) - - :param vector other (optional): Vector to measure the angle to. - :returns: ``number`` Angle in radians. - - -Measures the angle between two vectors. If ``other`` is omitted it defaults -to the vector ``(0,0)``, i.e. the function returns the angle to the coordinate -system. - -**Example**:: - - lean = self.upvector:angleTo(vector(0,1)) - if lean > .1 then self:fallOver() end - diff --git a/docs/vector-light.rst b/docs/vector-light.rst index 300dfbd..2d48179 100644 --- a/docs/vector-light.rst +++ b/docs/vector-light.rst @@ -9,10 +9,12 @@ An table-free version of :doc:`hump.vector `. Instead of a vector type, ``hump.vector-light`` provides functions that operate on numbers. .. note:: -Using this module instead of :doc:`hump.vector ` may result in faster -code, but does so at the expense of speed of development and code readability. -Unless you are absolutely sure that your code is significantly slowed down by -:doc:`hump.vector `, I recommend using it instead. + + Using this module instead of :doc:`hump.vector ` may result in + faster code, but does so at the expense of speed of development and code + readability. Unless you are absolutely sure that your code is + significantly slowed down by :doc:`hump.vector `, I recommend using + it instead. **Example**:: From acbd215840bb70ff8cedcfcd60c815ff526d058b Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Mon, 2 Nov 2015 21:23:56 +0100 Subject: [PATCH 41/50] Corrent syntax for signal instances (related to issue #55) --- docs/signal.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/signal.rst b/docs/signal.rst index c42a3c0..8bc71db 100644 --- a/docs/signal.rst +++ b/docs/signal.rst @@ -81,7 +81,7 @@ Registers a function ``f`` to be called when signal ``s`` is emitted. :: - menu:register('key-left', select_previous_item) + menu.register('key-left', select_previous_item) .. function:: Signal.emit(s, ...) @@ -97,7 +97,7 @@ Calls all functions bound to signal ``s`` with the supplied arguments. function love.keypressed(key) -- using a signal instance - if key == 'left' then menu:emit('key-left') end + if key == 'left' then menu.emit('key-left') end end :: @@ -176,5 +176,5 @@ Removes **all** functions from all signals that match a `Lua string pattern :: - player.signals:clearPattern('.*') -- clear all signals + player.signals.clearPattern('.*') -- clear all signals From 2cf3f19ff0d0e8dab5b0952e1449da63def6c3b5 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sun, 8 Nov 2015 23:02:46 +0100 Subject: [PATCH 42/50] Fix documentation errors found by z0rg --- camera.lua | 8 +------- docs/camera.rst | 8 ++++---- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/camera.lua b/camera.lua index 2f77e37..84b0f4c 100644 --- a/camera.lua +++ b/camera.lua @@ -143,13 +143,7 @@ function camera:mousePosition() return self:worldCoords(love.mouse.getPosition()) end --- camera scrolling utilities - adapted from - ---- Lock camera's x coordinate. --- @param x X coordinate (in world coordinates) to lock to. --- @param smoother Overriding smoothing function (optional). --- @param ... Additional parameters to the smoothing function (optional). --- @return The camera. +-- camera scrolling utilities function camera:lockX(x, smoother, ...) local dx, dy = (smoother or self.smoother)(x - self.x, self.y, ...) self.x = self.x + dx diff --git a/docs/camera.rst b/docs/camera.rst index 41f7b12..78b81f9 100644 --- a/docs/camera.rst +++ b/docs/camera.rst @@ -89,7 +89,7 @@ This function is shortcut to ``camera.x,camera.y = x, y``. :: function love.update(dt) - camera:lookAt(player.pos:unpack()):rotation(player.rot) + camera:lookAt(player.pos:unpack()):rotate(player.rot) end .. function:: camera:position() @@ -333,7 +333,7 @@ You can specify a default movement smoother by assigning the variable :param mixed ...: Additional parameters to the smoothing function. (optional) Horizontal camera locking: Keep the camera locked on the defined ``x``-position -(in *world coordinates*). They ``y``-position is not affected. +(in *world coordinates*). The ``y``-position is not affected. You can define an off-center locking position by "aiming" the camera left or right of your actual target. For example, to center the player 20 pixels to the @@ -363,7 +363,7 @@ right of your actual target. For example, to center the player 20 pixels to the :param mixed ...: Additional parameters to the smoothing function. (optional) Vertical camera locking: Keep the camera locked on the defined ``y``-position -(in *world coordinates*). They ``x``-position is not affected. +(in *world coordinates*). The ``x``-position is not affected. You can define an off-center locking position by "aiming" the camera above or below your actual target. For example, to center the player 20 pixels *below* the @@ -430,7 +430,7 @@ camera if the position would be out of the screen-rectangle defined by ``x_min`` The locking window is defined in camera coordinates, whereas the position to lock to is defined in world coordinates! -All of the other locking methods can be implemted by window locking. For +All of the other locking methods can be implemented by window locking. For position locking, set ``x_min = x_max`` and ``y_min = y_max``. Off-center locking can be done by defining the locking window accordingly. From 2de9a3015354320b1c5ed10db6789974f071e1b9 Mon Sep 17 00:00:00 2001 From: vrld Date: Fri, 27 Nov 2015 10:34:38 +0100 Subject: [PATCH 43/50] Fix #57: remove writing to global variable in smooth.linear --- camera.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/camera.lua b/camera.lua index 84b0f4c..afbef90 100644 --- a/camera.lua +++ b/camera.lua @@ -42,7 +42,7 @@ function camera.smooth.linear(speed) return function(dx,dy, s) -- normalize direction local d = math.sqrt(dx*dx+dy*dy) - dts = math.min((s or speed) * love.timer.getDelta(), d) -- prevent overshooting the goal + local dts = math.min((s or speed) * love.timer.getDelta(), d) -- prevent overshooting the goal if d > 0 then dx,dy = dx/d, dy/d end From c7c1b8e269acb83ccfd5d72eda2ae168748cd13f Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sun, 13 Dec 2015 22:48:45 +0100 Subject: [PATCH 44/50] add timer.script(f) --- timer.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/timer.lua b/timer.lua index dc19d49..ef4a750 100644 --- a/timer.lua +++ b/timer.lua @@ -76,6 +76,14 @@ function Timer:clear() self.functions = {} end +function Timer:script(f) + local co = coroutine.wrap(f) + co(function(t) + self:after(t, co) + coroutine.yield() + end) +end + Timer.tween = setmetatable({ -- helper functions out = function(f) -- 'rotates' a function @@ -175,6 +183,7 @@ local function new() during = function(...) return timer:during(...) end, after = function(...) return timer:after(...) end, every = function(...) return timer:every(...) end, + script = function(...) return timer:script(...) end, cancel = function(...) return timer:cancel(...) end, clear = function(...) return timer:clear(...) end, tween = setmetatable({}, { From 448ecf704b1e21b973693644ead74b383b37461b Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Mon, 14 Dec 2015 12:11:17 +0100 Subject: [PATCH 45/50] Document Timer.script --- docs/timer.rst | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/docs/timer.rst b/docs/timer.rst index 0595493..83bdf03 100644 --- a/docs/timer.rst +++ b/docs/timer.rst @@ -82,6 +82,70 @@ periodic behavior (see the example). menuTimer.after(1, finishAnimation) +.. function:: Timer.script(func) + + :param function func: Script to execute. + +Execute a function that can be paused without causing the rest of the program to +be suspended. ``func`` will receive a function - ``wait`` - to do that as only +argument. + +**Examples**:: + + Timer.script(function(wait) + print("Now") + wait(1) + print("After one second") + wait(1) + print("Bye!") + end) + +:: + + -- useful for splash screens + Timer.script(function(wait) + Timer.tween(0.5, splash.pos, {x = 300}, 'in-out-quad') + wait(5) -- show the splash for 5 seconds + Timer.tween(0.5, slpash.pos, {x = 800}, 'in-out-quad') + end) + +:: + + -- repeat something with a varying delay + Timer.script(function(wait) + while true do + spawn_ship() + wait(1 / (1-production_speed)) + end + end) + +:: + + -- jumping with timer.script + timer.script(function(wait) + local w = 1/12 + self.jumping = true + Timer.tween(w*2, self, {z = -8}, "out-cubic", function() + Timer.tween(w*2, self, {z = 0},"in-cubic") + end) + + self.quad = self.quads.jump[1] + wait(w) + + self.quad = self.quads.jump[2] + wait(w) + + self.quad = self.quads.jump[3] + wait(w) + + self.quad = self.quads.jump[4] + wait(w) + + self.jumping = false + self.z = 0 + end) + + .. function:: Timer.every(delay, func[, count]) :param number delay: Number of seconds between two consecutive function calls. From 3a5573b1dfc338926fd3ad04a53d33eb2a33b694 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Tue, 19 Jan 2016 09:19:27 +0100 Subject: [PATCH 46/50] Fix #59 - Error in example --- docs/gamestate.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/gamestate.rst b/docs/gamestate.rst index 9ab96fc..75a0359 100644 --- a/docs/gamestate.rst +++ b/docs/gamestate.rst @@ -19,7 +19,7 @@ A typical game could consist of a menu-state, a level-state and a game-over-stat end function menu:keyreleased(key, code) - if key == 'enter' then + if key == 'return' then Gamestate.switch(game) end end From 8435fc798f6789a3fa87e2c6dff91adcbf8eca8a Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sun, 1 May 2016 14:40:58 +0200 Subject: [PATCH 47/50] Fix #60 - Inconsistent self:calls() in timer and signal --- signal.lua | 30 +++++++++++++++--------------- timer.lua | 39 ++++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/signal.lua b/signal.lua index 975d4c8..6bb435e 100644 --- a/signal.lua +++ b/signal.lua @@ -76,20 +76,20 @@ function Registry:clearPattern(p) end end --- the module -local function new() - local registry = setmetatable({}, Registry) - - return setmetatable({ - new = new, - register = function(...) return registry:register(...) end, - emit = function(...) registry:emit(...) end, - remove = function(...) registry:remove(...) end, - clear = function(...) registry:clear(...) end, - emitPattern = function(...) registry:emitPattern(...) end, - removePattern = function(...) registry:removePattern(...) end, - clearPattern = function(...) registry:clearPattern(...) end, - }, {__call = new}) +-- instancing +function Registry.new() + return setmetatable({}, Registry) end -return new() +-- default instance +local default = Registry.new() + +-- module forwards calls to default instance +local module = {} +for k in pairs(Registry) do + if k ~= "__index" then + module[k] = function(...) return default[k](default, ...) end + end +end + +return setmetatable(module, {__call = Registry.new}) diff --git a/timer.lua b/timer.lua index ef4a750..2693849 100644 --- a/timer.lua +++ b/timer.lua @@ -174,24 +174,25 @@ __index = function(tweens, key) or error('Unknown interpolation method: ' .. key) end}) --- the module -local function new() - local timer = setmetatable({functions = {}, tween = Timer.tween}, Timer) - return setmetatable({ - new = new, - update = function(...) return timer:update(...) end, - during = function(...) return timer:during(...) end, - after = function(...) return timer:after(...) end, - every = function(...) return timer:every(...) end, - script = function(...) return timer:script(...) end, - cancel = function(...) return timer:cancel(...) end, - clear = function(...) return timer:clear(...) end, - tween = setmetatable({}, { - __index = Timer.tween, - __newindex = function(_,k,v) Timer.tween[k] = v end, - __call = function(t,...) return timer:tween(...) end, - }) - }, {__call = new}) +-- Timer instancing +function Timer.new() + return setmetatable({functions = {}, tween = Timer.tween}, Timer) end -return new() +-- default instance +local default = Timer.new() + +-- module forwards calls to default instance +local module = {} +for k in pairs(Timer) do + if k ~= "__index" then + module[k] = function(...) return default[k](default, ...) end + end +end +module.tween = setmetatable({}, { + __index = Timer.tween, + __newindex = function(k,v) Timer.tween[k] = v end, + __call = function(t, ...) return default:tween(...) end, +}) + +return setmetatable(module, {__call = Timer.new}) From dff00cc1dc9eeedad1c1e22192ba0cc1e3085121 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sun, 1 May 2016 14:56:12 +0200 Subject: [PATCH 48/50] Document changes due to issue #60 --- docs/signal.rst | 17 +++++++++++------ docs/timer.rst | 26 ++++++++++++++++---------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/docs/signal.rst b/docs/signal.rst index 8bc71db..5103c5f 100644 --- a/docs/signal.rst +++ b/docs/signal.rst @@ -18,7 +18,7 @@ signals that match a `Lua string pattern **Example**:: -- in AI.lua - signals.register('shoot', function(x,y, dx,dy) + Signal.register('shoot', function(x,y, dx,dy) -- for every critter in the path of the bullet: -- try to avoid being hit for critter in pairs(critters) do @@ -29,7 +29,7 @@ signals that match a `Lua string pattern end) -- in sounds.lua - signals.register('shoot', function() + Signal.register('shoot', function() Sounds.fire_bullet:play() end) @@ -38,7 +38,7 @@ signals that match a `Lua string pattern if key == ' ' then local x,y = player.pos:unpack() local dx,dy = player.direction:unpack() - signals.emit('shoot', x,y, dx,dy) + Signal.emit('shoot', x,y, dx,dy) end end @@ -57,6 +57,11 @@ global registry. Likewise, the global registry does not affect the instance. If you don't need multiple independent registries, you can use the global/default registry (see examples). +.. note:: + Unlike the default one, signal registry instances use the colon-syntax, + i.e., you need to call ``instance:emit('foo', 23)`` instead of + ``Signal.mit('foo', 23)``. + **Example**:: player.signals = Signal.new() @@ -81,7 +86,7 @@ Registers a function ``f`` to be called when signal ``s`` is emitted. :: - menu.register('key-left', select_previous_item) + menu:register('key-left', select_previous_item) .. function:: Signal.emit(s, ...) @@ -97,7 +102,7 @@ Calls all functions bound to signal ``s`` with the supplied arguments. function love.keypressed(key) -- using a signal instance - if key == 'left' then menu.emit('key-left') end + if key == 'left' then menu:emit('key-left') end end :: @@ -176,5 +181,5 @@ Removes **all** functions from all signals that match a `Lua string pattern :: - player.signals.clearPattern('.*') -- clear all signals + player.signals:clearPattern('.*') -- clear all signals diff --git a/docs/timer.rst b/docs/timer.rst index 83bdf03..219d5b7 100644 --- a/docs/timer.rst +++ b/docs/timer.rst @@ -42,6 +42,11 @@ the global timer. Likewise, the global timer does not affect timer instances. If you don't need multiple independent schedulers, you can use the global/default timer (see examples). +.. note:: + Unlike the default timer, timer instances use the colon-syntax, i.e., + you need to call ``instance:after(1, foo)`` instead of ``Timer.after(1, + foo)``. + **Example**:: menuTimer = Timer.new() @@ -79,7 +84,7 @@ periodic behavior (see the example). :: --Using a timer instance: - menuTimer.after(1, finishAnimation) + menuTimer:after(1, finishAnimation) .. function:: Timer.script(func) @@ -87,8 +92,9 @@ periodic behavior (see the example). :param function func: Script to execute. Execute a function that can be paused without causing the rest of the program to -be suspended. ``func`` will receive a function - ``wait`` - to do that as only -argument. +be suspended. ``func`` will receive a function - ``wait`` - to do interrupt the +script (but not the whole program) as only argument. The function prototype of +wait is: ``wait(delay)``. **Examples**:: @@ -122,7 +128,7 @@ argument. :: -- jumping with timer.script - timer.script(function(wait) + self.timers:script(function(wait) local w = 1/12 self.jumping = true Timer.tween(w*2, self, {z = -8}, "out-cubic", function() @@ -167,7 +173,7 @@ or :func:`Timer.cancel` or :func:`Timer.clear` is called on the timer instance. :: -- launch 5 fighters in quick succession (using a timer instance) - mothership_timer.every(0.3, function() self:launchFighter() end, 5) + mothership_timer:every(0.3, function() self:launchFighter() end, 5) :: @@ -217,7 +223,7 @@ seconds have passed. player.isInvincible = true -- flash player for 3 seconds local t = 0 - player.timer.during(3, function(dt) + player.timer:during(3, function(dt) t = t + dt player.visible = (t % .2) < .1 end, function() @@ -248,9 +254,9 @@ Prevent a timer from being executed in the future. function tick() print('tick... tock...') end - handle = menuTimer.every(1, tick) + handle = menuTimer:every(1, tick) -- later - menuTimer.cancel(handle) + menuTimer:cancel(handle) .. function:: Timer.clear() @@ -264,7 +270,7 @@ executed will discarded. :: - menuTimer.clear() + menuTimer:clear() .. function:: Timer.update(dt) @@ -285,7 +291,7 @@ Update timers and execute functions if the deadline is reached. Call in -- using hump.gamestate and a timer instance function menuState:update(dt) - self.timer.update(dt) + self.timers:update(dt) end From edf115f19a4fa8e4014196f43314f5e4914639d5 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sun, 1 May 2016 15:03:01 +0200 Subject: [PATCH 49/50] Fix #58 - inconsistent naming in camera documentation --- docs/camera.rst | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/camera.rst b/docs/camera.rst index 78b81f9..44dffc2 100644 --- a/docs/camera.rst +++ b/docs/camera.rst @@ -13,12 +13,12 @@ worry about that. **Example**:: function love.load() - cam = Camera(player.pos.x, player.pos.y) + camera = Camera(player.pos.x, player.pos.y) end function love.update(dt) local dx,dy = player.x - cam.x, player.y - cam.y - cam:move(dx/2, dy/2) + camera:move(dx/2, dy/2) end @@ -195,7 +195,7 @@ Apply camera transformations, i.e. move, scale and rotate everything until function love.draw() camera:attach() draw_world() - cam:detach() + camera:detach() draw_hud() end @@ -210,7 +210,7 @@ Stop looking through the camera. function love.draw() camera:attach() draw_world() - cam:detach() + camera:detach() draw_hud() end @@ -223,9 +223,9 @@ Stop looking through the camera. Wrap a function between a ``camera:attach()``/``camera:detach()`` pair. Equivalent to:: - cam:attach() + camera:attach() func() - cam:detach() + camera:detach() **Example**:: @@ -279,7 +279,7 @@ between these two coordinate systems. **Example**:: - x,y = cam:cameraCoords(player.pos.x, player.pos.y) + x,y = camera:cameraCoords(player.pos.x, player.pos.y) love.graphics.line(x, y, love.mouse.getPosition()) @@ -307,13 +307,13 @@ by Itay Keren gives a lot of insight into how to design good camera systems. **hump.camera** offers functions that help to implement most of the techniques discussed in the article. The functions :func:`camera:lockX`, -:func:`camera:lockY`, :func:`camera:lockPos`, and :func:`camera:lockWindow` +:func:`camera:lockY`, :func:`camera:lockPosition`, and :func:`camera:lockWindow` move the camera so that the interesting content stays in frame. Note that the functions must be called every frame:: function love.update() -- vertical locking - cam:lockX(player.pos.x) + camera:lockX(player.pos.x) end @@ -342,17 +342,17 @@ right of your actual target. For example, to center the player 20 pixels to the **Examples**:: -- lock on player vertically - cam:lockX(player.x) + camera:lockX(player.x) :: -- ... with linear smoothing at 25 px/s - cam:lockX(player.x, Camera.smooth.linear(25)) + camera:lockX(player.x, Camera.smooth.linear(25)) :: -- lock player 20px left of center - cam:lockX(player.x + 20) + camera:lockX(player.x + 20) @@ -372,17 +372,17 @@ screen center, aim 20 pixels *above* it (see examples). **Examples**:: -- lock on player horizontally - cam:lockY(player.y) + camera:lockY(player.y) :: -- ... with damped smoothing with a stiffness of 10 - cam:lockY(player.y, Camera.smooth.damped(10)) + camera:lockY(player.y, Camera.smooth.damped(10)) :: -- lock player 20px below the screen center - cam:lockY(player.y - 20) + camera:lockY(player.y - 20) @@ -403,12 +403,12 @@ the screen center, aim 10 pixels to the *right* and 20 pixels *below*. **Examples**:: -- lock on player - cam:lock(player.x, player.y) + camera:lockPosition(player.x, player.y) :: -- lock 50 pixels into player's aiming direction - cam:lockY(player.x - player.aiming.x * 50, player.y - player.aiming.y * 50) + camera:lockPosition(player.x - player.aiming.x * 50, player.y - player.aiming.y * 50) @@ -437,7 +437,7 @@ Off-center locking can be done by defining the locking window accordingly. **Examples**:: -- lock on player - cam:lock(player.x, player.y) + camera:lock(player.x, player.y) .. attribute:: camera.smoother @@ -514,7 +514,7 @@ Smoothly moves the camera towards to snapping goal with constant speed. :: -- warning: creates a function every frame! - cam:lockX(player.x, Camera.smooth.linear(25)) + camera:lockX(player.x, Camera.smooth.linear(25)) .. function:: Camera.smooth.damped(stiffness) @@ -534,4 +534,4 @@ moves more quickly. :: -- warning: creates a function every frame! - cam:lockPos(player.x, player.y, Camera.smooth.damped(2)) + camera:lockPosition(player.x, player.y, Camera.smooth.damped(2)) From 40f0820d3c4514443bfdc1399fa3357173a9c878 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Sun, 1 May 2016 16:20:43 +0200 Subject: [PATCH 50/50] Add viewport support to camera (fixes #64) --- camera.lua | 54 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/camera.lua b/camera.lua index afbef90..cb86a79 100644 --- a/camera.lua +++ b/camera.lua @@ -102,45 +102,73 @@ function camera:zoomTo(zoom) return self end -function camera:attach() - local cx,cy = love.graphics.getWidth()/(2*self.scale), love.graphics.getHeight()/(2*self.scale) +function camera:attach(x,y,w,h, noclip) + x,y = x or 0, y or 0 + w,h = w or love.graphics.getWidth(), h or love.graphics.getHeight() + + self._sx,self._sy,self._sw,self._sh = love.graphics.getScissor() + if not noclip then + love.graphics.setScissor(x,y,w,h) + end + + local cx,cy = x+w/2, y+h/2 love.graphics.push() - love.graphics.scale(self.scale) love.graphics.translate(cx, cy) + love.graphics.scale(self.scale) love.graphics.rotate(self.rot) love.graphics.translate(-self.x, -self.y) end function camera:detach() love.graphics.pop() + love.graphics.setScissor(self._sx,self._sy,self._sw,self._sh) end -function camera:draw(func) - self:attach() +function camera:draw(...) + local x,y,w,h,noclip,func + local nargs = select("#", ...) + if nargs == 1 then + func = ... + elseif nargs == 5 then + x,y,w,h,func = ... + elseif nargs == 6 then + x,y,w,h,noclip,func = ... + else + error("Invalid arguments to camera:draw()") + end + + self:attach(x,y,w,h,noclip) func() self:detach() end -function camera:cameraCoords(x,y) +-- world coordinates to camera coordinates +function camera:cameraCoords(x,y, ox,oy,w,h) + ox, oy = ox or 0, oy or 0 + w,h = w or love.graphics.getWidth(), h or love.graphics.getHeight() + -- x,y = ((x,y) - (self.x, self.y)):rotated(self.rot) * self.scale + center - local w,h = love.graphics.getWidth(), love.graphics.getHeight() local c,s = cos(self.rot), sin(self.rot) x,y = x - self.x, y - self.y x,y = c*x - s*y, s*x + c*y - return x*self.scale + w/2, y*self.scale + h/2 + return x*self.scale + w/2 + ox, y*self.scale + h/2 + oy end -function camera:worldCoords(x,y) +-- camera coordinates to world coordinates +function camera:worldCoords(x,y, ox,oy,w,h) + ox, oy = ox or 0, oy or 0 + w,h = w or love.graphics.getWidth(), h or love.graphics.getHeight() + -- x,y = (((x,y) - center) / self.scale):rotated(-self.rot) + (self.x,self.y) - local w,h = love.graphics.getWidth(), love.graphics.getHeight() local c,s = cos(-self.rot), sin(-self.rot) - x,y = (x - w/2) / self.scale, (y - h/2) / self.scale + x,y = (x - w/2 - ox) / self.scale, (y - h/2 - oy) / self.scale x,y = c*x - s*y, s*x + c*y return x+self.x, y+self.y end -function camera:mousePosition() - return self:worldCoords(love.mouse.getPosition()) +function camera:mousePosition(ox,oy,w,h) + local mx,my = love.mouse.getPosition() + return self:worldCoords(mx,my, ox,oy,w,h) end -- camera scrolling utilities